Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dd: writes null bytes to device if stdout is redirect to device #3542

Closed
jhscheer opened this issue May 18, 2022 · 1 comment · Fixed by #3880
Closed

dd: writes null bytes to device if stdout is redirect to device #3542

jhscheer opened this issue May 18, 2022 · 1 comment · Fixed by #3880
Labels

Comments

@jhscheer
Copy link
Contributor

@jfinkels I took the liberty to open a new issue with a summary for all the findings you published in #3447

gnu/tests/dd/skip-seek-past-dev.sh runs

device=$(df --output=source . | tail -n1)
dev_size=$(blockdev --getsize64 $device)
DEV_OFLOW=$(expr $dev_size + 1)
dd bs=1 seek=$DEV_OFLOW count=0 status=noxfer > "$device"

and expects $?=1 and stderr=dd: 'standard output': cannot seek: Invalid argument.

However, uu_tail does not check if stdout is a redirect to a seekable device and then writes null bytes to $device !

let mut dst = io::stdout();
// The --seek and --oseek flags are additive.
let amt = seek.unwrap_or(0) + oseek.unwrap_or(0);
// stdout is not seekable, so we just write null bytes.
if amt > 0 {
io::copy(&mut io::repeat(0u8).take(amt as u64), &mut dst)
.map_err_context(|| String::from("write error"))?;
}

possible fix

Haven't looked into it much but a possible fix could be to get the redirect for /dev/stdout similar to this:

if let Ok(p) = Path::new("/dev/stdin").canonicalize() {
p.into_os_string()
} else {
OsString::from("/dev/stdin")
}

and then apply the seek checks for the new path.

@jhscheer jhscheer changed the title dd: seek does not respect device size if stdout is a redirect to device dd: writes null bytes to device if stdout is redirect to device May 18, 2022
@jfinkels
Copy link
Collaborator

Thank you for creating a new issue 👍

jfinkels added a commit to jfinkels/coreutils that referenced this issue Aug 27, 2022
Fix a bug in `dd` where null bytes would be unintentionally written if
stdout were redirected to a seekable file. For example, before this
commit, if `dd` were invoked from the command-line as

    dd if=infile bs=1 count=10 seek=5 > /dev/sda1

then five zeros would be written to `/dev/sda1` before copying ten
bytes of `infile` to `/dev/sda1`. After this commit, `dd` will
correctly seek five bytes forward in `/dev/sda1` before copying the
ten bytes of `infile`.

Fixes uutils#3542.
jfinkels added a commit to jfinkels/coreutils that referenced this issue Aug 27, 2022
Fix a bug in `dd` where null bytes would be unintentionally written if
stdout were redirected to a seekable file. For example, before this
commit, if `dd` were invoked from the command-line as

    dd if=infile bs=1 count=10 seek=5 > /dev/sda1

then five zeros would be written to `/dev/sda1` before copying ten
bytes of `infile` to `/dev/sda1`. After this commit, `dd` will
correctly seek five bytes forward in `/dev/sda1` before copying the
ten bytes of `infile`.

Fixes uutils#3542.
sylvestre pushed a commit to jfinkels/coreutils that referenced this issue Sep 5, 2022
Fix a bug in `dd` where null bytes would be unintentionally written if
stdout were redirected to a seekable file. For example, before this
commit, if `dd` were invoked from the command-line as

    dd if=infile bs=1 count=10 seek=5 > /dev/sda1

then five zeros would be written to `/dev/sda1` before copying ten
bytes of `infile` to `/dev/sda1`. After this commit, `dd` will
correctly seek five bytes forward in `/dev/sda1` before copying the
ten bytes of `infile`.

Fixes uutils#3542.
sylvestre pushed a commit that referenced this issue Sep 18, 2022
* dd: move argument parsing outside of Input, Output

Move the argument parsing code out of the `Input::new()` and
`Output::new()` functions and into the calling code. This allows the
calling code to make decisions about how to instantiate the `Input`
and `Output` objects if necessary.

* dd: handle stdout redirected to seekable file

Fix a bug in `dd` where null bytes would be unintentionally written if
stdout were redirected to a seekable file. For example, before this
commit, if `dd` were invoked from the command-line as

    dd if=infile bs=1 count=10 seek=5 > /dev/sda1

then five zeros would be written to `/dev/sda1` before copying ten
bytes of `infile` to `/dev/sda1`. After this commit, `dd` will
correctly seek five bytes forward in `/dev/sda1` before copying the
ten bytes of `infile`.

Fixes #3542.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants