Subject: Re: bug#36291: od --skip-bytes reads everything from the very beginning

From: Pádraig Brady <[email-masked]>
Date: Wed, 19 Jun 2019 20:42:31 +0100

On 19/06/19 09:20, Szőts Ákos wrote:
> Dear List members,
> 
> I've recently discovered that od "--skip-bytes" feature doesn't
> actually seek into the file but rather it reads everything from the
> very beginning until the given offset is reached.
> 
> This can be problematic in two cases:
>  - when speed matters, and
>  - when parts of the file is read-protected (like in the case of
> /dev/mem when CONFIG_STRICT_DEVMEM=y, which is usually the case). In
> this example od will reach an area in /dev/mem which is read-protected
> (even for root) and will report back EPERM before it could reach the
> requested, and allowed, memory area. The error report will be
> misleading since the resulting EPERM is not because the requested area
> is protected (as suggested by the error message) but because of the
> inner mechanics of the program.
> 
> In contrary, hexdump jumps to the address directly.
> 
> You can test it by running the following two commands:
> - strace hexdump --skip 0xFE000124 --length 1 /dev/sda
> - strace od --skip-bytes 0xFE000124 --read-bytes 1 /dev/sda
> 
> I don't know whether this behaviour is intended but if so, could you
> please expand the documentation a little bit with this additional
> information?
> 
> od version: od (GNU coreutils) 8.30, openSUSE Tumbleweed, x64
> 
> Thank you and all the best,

Similar issues were discussed in https://debbugs.gnu.org/18621
(though od always only skipped in regular files).

It's hard to get something applicable to all cases.
We'd like to seek for the last two here:

$ stat /proc/$$/io /sys/kernel/vmcoreinfo /dev/sda /dev/mem | grep Size
  Size: 0         	Blocks: 0          IO Block: 1024   regular empty file
  Size: 4096      	Blocks: 0          IO Block: 4096   regular file
  Size: 0         	Blocks: 0          IO Block: 4096   block special file
  Size: 0         	Blocks: 0          IO Block: 4096   character special file

Maybe we should relax the cases we do read() for,
and try to seek in block/character special files,
falling back to read() where that fails?

Note one can get the same functionality by combining dd like:
  dd bs=1 skip=$((0xFE000124)) count=1 if=/dev/sda | od
or more efficiently for larger sizes like
  dd iflag=skip_bytes skip=$((0xFE000124)) if=/dev/sda | od --read-bytes=1

cheers,
Pádraig