This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 5/5] Use seek+read instead of pread to read from /dev/$$/mem files.


On Mon, Oct 05, 2015 at 05:36:34PM +0200, Jose E. Marchesi wrote:
> pread[64] always returns EINVAL when negative offsets are used.
> read+seek allows us to read in-memory vdso objects mapped high in the
> address space.

Nice find.
 
>  {
>    const int fd = *(const int *) arg;
> -  ssize_t nread = pread64 (fd, data, maxread, (off64_t) address);
> +
> +  /* This code relies on the fact the Linux kernel accepts negative
> +     offsets when seeking /dev/$$/mem files, as a special case. In
> +     particular pread[64] cannot be used here, because it will always
> +     return EINVAL when passed a negative offset.  */
> +
> +  if (lseek (fd, (off64_t) address, SEEK_SET) == -1)
> +    return 0;
> +
> +  ssize_t nread = read (fd, data, maxread);
> +
>    /* Some kernels don't actually let us do this read, ignore those errors.  */
> -  if (nread < 0 && (errno == EINVAL || errno == EPERM))
> +  if (nread < 0)
>      return 0;
>    if (nread > 0 && (size_t) nread < minread)
>      nread = 0;

This subtly changes the code to always ignore errors and turns them into
"short reads" instead. Looking at how this code is used I think it is
actually better to instead change the code to report an error with errno.
So return -1 from lseek and just fall through to returning -1 after the
read. It doesn't matter too much, but seems more consistent and might
provide slightly nicer error messages if something fails (actually currently
the error message is swallowed later in the code, but if we are changing
this anyway, then changing it to report a real errno always seems better).

Thanks,

Mark

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]