Created attachment 1915583 [details] Short ET_EXEC with (0 == .e_shnum) Description of problem: When ( 0 == ElfXX_Ehdr.e_shnum ) then "readelf --headers" prints 64 items of garbage ElfXX_Shdr Section headers, as if the 0 meant 64 instead. This is a bug. It is perfectly reasonable for an ELF executable to have no Section headers at all. This worked correctly (that is, no Section header info is printed when (0 == .e_shnum)) in Fedora 34. Version-Release number of selected component (if applicable): binutils-2.37-36.fc36.x86_64 How reproducible: every time Steps to Reproduce: 1. "readelf --headers" when (0 == ElfXX_Ehdr.e_shnum) 2. 3. Actual results: Prints 64 items of garbage ElfXX_Shdr Secton headers. Expected results: No Section header info is printed when (0 == .e_shnum). Additional info: 7KB example ET_EXEC with (0 == .e_shnum) will be attached.
Hi John, Actually readelf is behaving correctly. There is an extension to the ELF standard that allows for a file to contain more than 0xFF00 sections: https://docs.oracle.com/cd/E19120-01/open.solaris/819-0690/chapter6-43405/index.html The definition of e_shnum there says: The number of entries in the section header table. The product of e_shentsize and e_shnum gives the section header table's size in bytes. If a file has no section header table, e_shnum holds the value zero. If the number of sections is greater than or equal to SHN_LORESERVE (0xff00), e_shnum has the value zero. The actual number of section header table entries is contained in the sh_size field of the section header at index 0. Otherwise, the sh_size member of the initial section header entry contains the value zero. See Table 7–6 and Table 7–7. So in theory your test file should have a single section header which contains a sh_size value of 0. Either that or the e_shentsize field in the file header should be set to 0, indicating that there really are no sections in the file. There is one thing that readelf can/should do however. If the e_shoff field in the ELF header is zero, then this is a sure sign that there are no sections. Since the file has to start with an ELF file header, that cannot also be the location of the section header table. I will add this test to the upstream binutils sources and to rawhide. I do not see this as a serious issue however, so I am not planning to backport the patch to other releases. Cheers Nick
Hi Nick, > ... or the e_shentsize field in the file header should be set to 0, ... libbfd and other code that checks for "sanity" of ELF, complains if (.e_shentsize != sizeof(ElfXX_Shdr)), regardless of .e_shnum, .e_shoff, etc.; and bfd_open() fails. [The git log for my project shows that I discovered this 16 years ago in 2006.] This makes gdb totally useless, which is fatal for developers and maintenance and support. So I look forward to the extra check for (0 == .e_shoff) as an overriding confirmation of "no Section headers at all, not even by any extension" when (0 == .e_shnum). [Side rant: (.e_shentsize > sizeof(ElfXX_Shdr)) should be allowed so that ElfXX_Shdr can have private extensions! Of course in plain-C this means that incrementing a pointer (ElfXX_Shdr *ptr;) must be done by explicit addition of .shentsize instead of implicitly by increment operator (++). It has long been time to use C++ instead of C.]
(In reply to John Reiser from comment #2) > libbfd and other code that checks for "sanity" of ELF, complains if > (.e_shentsize != sizeof(ElfXX_Shdr)), regardless of .e_shnum, .e_shoff, etc.; > and bfd_open() fails. Hmm, well that is a bug. I should probably fix it. I don't suppose you would care to file an upstream bug report for it ? > So I look forward to the extra check for (0 == .e_shoff) as an overriding > confirmation of "no Section headers at all, not even by any extension" > when (0 == .e_shnum). Please try out: binutils-2.39-4.fc38. > [Side rant: (.e_shentsize > sizeof(ElfXX_Shdr)) should be allowed > so that ElfXX_Shdr can have private extensions! Weeelll - private extensions to the ELF format could be a dangerous thing to pursue. But yes, technically you are correct. > Of course in plain-C > this means that incrementing a pointer (ElfXX_Shdr *ptr;) must be done > by explicit addition of .shentsize instead of implicitly by increment > operator (++). True - and several other changes as well. > It has long been time to use C++ instead of C.] Well I will politely agree to disagree with you here. But then I am old and crumbly... Cheers Nick
(In reply to Nick Clifton from comment #3) Looking at commit aef1974a66ba9644b239f761c4b8b586f4763e4b (origin/master/HEAD on Oct.3) of git://sourceware.org/git/binutils-gdb.git in directory bfd: ===== git blame $(grep -srl e_shentsize .) elfcode.h:dc810e3900d4 (Alan Modra 2001-09-18 09:57:26 +0000 254) dst->e_shentsize = H_GET_16 (abfd, src->e_shentsize); elfcode.h:dc810e3900d4 (Alan Modra 2001-09-18 09:57:26 +0000 287) H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize); elfcode.h:0c35f01ab36d (Alan Modra 2001-09-22 03:16:01 +0000 581) if (i_ehdrp->e_shentsize != sizeof (x_shdr) && i_ehdrp->e_shnum != 0) elfcode.h:^252b5132c75 (Richard Henderson 1999-05-03 07:29:11 +0000 1682) fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); elfcode.h:5979d6b69b20 (Alan Modra 2014-04-02 12:07:33 +1030 1846) if (i_ehdr.e_shoff != 0 && i_ehdr.e_shnum != 0 && i_ehdr.e_shentsize != 0) elfcode.h:5979d6b69b20 (Alan Modra 2014-04-02 12:07:33 +1030 1848) shdr_end = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize; ===== it looks like line 1846) took care of _some_ of this 8.5 years ago in 2014; my problem dates to 2006, 8 years before that. > Please try out: binutils-2.39-4.fc38. Where is version 2.39-4? I tried sudo dnf install fedora-repos-rawhide dnf download --enablerepo rawhide binutils and got version 2.39-3 which still has the problem. I also got version 2.39-3 from Fedora-Workstation-Live-x86_64-Rawhide-20221004.n.0.iso which is today's rawhide compose. (My fedora 36 system has "GNU readelf version 2.37-36.fc36".)
(In reply to John Reiser from comment #4) > it looks like line 1846) took care of _some_ of this 8.5 years ago in 2014; My own tests seem to confirm this. If you do come across a case when an sh_entsize of 0 is causing a problem, please let me know - or file a bug report. > Where is version 2.39-4? Stuck in gating. But you can find the rpms here: https://koji.fedoraproject.org/koji/buildinfo?buildID=2070126
This message is a reminder that Fedora Linux 36 is nearing its end of life. Fedora will stop maintaining and issuing updates for Fedora Linux 36 on 2023-05-16. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as EOL if it remains open with a 'version' of '36'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, change the 'version' to a later Fedora Linux version. Note that the version field may be hidden. Click the "Show advanced fields" button if you do not see it. Thank you for reporting this issue and we are sorry that we were not able to fix it before Fedora Linux 36 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora Linux, you are encouraged to change the 'version' to a later version prior to this bug being closed.
Fedora Linux 36 entered end-of-life (EOL) status on 2023-05-16. Fedora Linux 36 is no longer maintained, which means that it will not receive any further security or bug fix updates. As a result we are closing this bug. If you can reproduce this bug against a currently maintained version of Fedora Linux please feel free to reopen this bug against that version. Note that the version field may be hidden. Click the "Show advanced fields" button if you do not see the version field. If you are unable to reopen this bug, please file a new report against an active release. Thank you for reporting this bug and we are sorry it could not be fixed.