public inbox for
 help / color / mirror / Atom feed
From: Mark Wielaard <>
To: Josh Stone <>,
Subject: Re: failed reading "Smallest x86 ELF Hello World"
Date: Wed, 04 Oct 2017 18:55:00 -0000	[thread overview]
Message-ID: <> (raw)
In-Reply-To: <>

On Thu, 2017-09-28 at 12:06 -0700, Josh Stone wrote:
> From
> Elfutils completely fails to read the file:
> $ eu-readelf --version
> eu-readelf (elfutils) 0.169
> Copyright [...]
> $ eu-readelf -a hello
> eu-readelf: failed reading 'hello': invalid file descriptor
> It's not clear that we should care, since that page even says it's "a
> completely corrupted x86 ELF Binary that still runs."  But since it's
> good enough for the kernel to run it, I'd hope for *something* from
> tools.
> It also seems weird to get the message "invalid file descriptor",
> from ELF_E_INVALID_FILE, which makes it sound like more like
> EBADF.  The file descriptor itself is fine - it just doesn't like the
> ELF within.

At first I though it was because eu-readelf uses libdwfl to get more
information about the ELF file. To get all the data about the
Dwfl_Modules we might hit some error that might not be relevant for the
initial showing of data. But that isn't really it in this case.

The first issue is indeed that almost anything that goes wrong when
setting up the initial Elf handle ends up being described as
ELF_E_INVALID_FILE. Which is not always the correct error code. So I
introduced ELF_E_INVALID_ELF which indicates it is bad ELF data being
encountered and not just the inability to read the data from the file
descriptor. Also in a couple of cases we didn't explicitly set the
libelf errno to indicate what really went wrong. I made sure we always
do now.

  libelf: Add ELF_E_INVALID_ELF error value.

This at least gives a nicer error message:

  eu-readelf: failed reading './hello': invalid ELF file data

But while auditing this code it is clear we go out of our way to get
the section (count) making sure we don't touch any bad data. If there
is a change we might read anything bad from the (mmapped) file then we
explicitly set the elf->state.elf[64|32].scns.cnt to zero. Which is
respected throughout libelf whenever we try to touch section headers.
Except... during the initial read we double check e_shoff is sane and
error out early. Even though the code right below it explicitly doesn't
use it when scncnt is zero. So we can fix this sanity check.

  libelf: Don't error out when sanity checking e_shoff if scncnt is

This then gives similar output to binutils readelf:

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 48 69 20 57 6f 72 6c 64 0a
  Class:                             ELF32
  Data:                              2's complement, little endian
  Ident Version:                     1 (current)
  OS/ABI:                            <unknown>: 72
  ABI Version:                       105
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           1 (current)
  Entry point address:               0x8048080
  Start of program headers:          52 (bytes into file)
  Start of section headers:          309248 (bytes into file)
  Flags:                             0x80cd0000
  Size of this header:               22763 (bytes)
  Size of program header entries:    32 (bytes)
  Number of program headers entries: 2
  Size of section header entries:    40 (bytes)
  Number of section headers entries: 5
  Section header string table index: 4

Section Headers:
[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align
  LOAD           0x000000 0x08048000 0x08048000 0x0000a2 0x0000a2 R E 0x1000
  LOAD           0x0000a4 0x080490a4 0x080490a4 0x000009 0x000009  W  0x9007b900

 Section to Segment mapping:
  Segment Sections...

Maybe it could be improved a little more by adding a warning that 5
section [headers] were expected, but none could be read. But I leave it
at this for now.



  reply	other threads:[~2017-10-04 18:55 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-28 19:06 Josh Stone
2017-10-04 18:55 ` Mark Wielaard [this message]
2017-10-04 18:57   ` [PATCH 1/2] libelf: Add ELF_E_INVALID_ELF error value Mark Wielaard
2017-10-04 18:57     ` [PATCH 2/2] libelf: Don't error out when sanity checking e_shoff if scncnt is zero Mark Wielaard
2017-10-13 15:09   ` failed reading "Smallest x86 ELF Hello World" Mark Wielaard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \ \ \ \ \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).