[Bug debugedit/33819] debugedit crashes when an object file contains 65,280 or more sections

mark at klomp dot org sourceware-bugzilla@sourceware.org
Fri Mar 6 17:13:05 GMT 2026


https://sourceware.org/bugzilla/show_bug.cgi?id=33819

Mark Wielaard <mark at klomp dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2026-03-06
                 CC|                            |mark at klomp dot org
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Mark Wielaard <mark at klomp dot org> ---
(In reply to James Abbatiello from comment #0)
> I'm not sure if this more appropriate for debugedit or for elfutils/libelf.
> 
> If you try to modify an object file that contains 65,280 or more sections
> then debugedit will dereference a null pointer and crash.

It is two bugs, one in elfutils/libelf (the crash) and another in debugedit
which simply doesn't handle > 0xFF00 sections (it handles up to that many
sections, then skips the rest).

>  Here's an example:
> 
> ```
> $ cat testing.cpp
> template <int I>
> void foo() {
> }
> 
> #define F0 foo<__COUNTER__>();
> #define F1 F0 F0
> #define F2 F1 F1
> #define F3 F2 F2
> #define F4 F3 F3
> #define F5 F4 F4
> #define F6 F5 F5
> #define F7 F6 F6
> #define F8 F7 F7
> #define F9 F8 F8
> #define F10 F9 F9
> #define F11 F10 F10
> #define F12 F11 F11
> #define F13 F12 F12
> #define F14 F13 F13
> #define F15 F14 F14
> 
> int main() {
> //    F14  // approx 32779 sections
>     F15  // approx 65548 sections
>     return 0;
> }
> 
> $ g++ -g -c testing.cpp
> 
> $ debugedit -b from -d to testing.o
> Segmentation fault
> ```
> 
> If you comment out the `F15` line and uncomment the `F14` line then this
> will run successfully.
> 
> 
> The crash happens in libelf in elf32_updatenull.c in the
> __elf64_updatenull_wrlock function at this code:
> 
> ```
>       if (shnum >= SHN_LORESERVE)
> 	{
> 	  /* We have to  fill in the number of sections in the header
> 	     of the zeroth section.  */
> 	  Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
> 
> 	  update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
> 			     shnum, scn0->shdr_flags);
> 	}
> ```
> 
> Here shnum will be greater than or equal to SHN_LORESERVE (0xFF00). 
> `scn0->shdr.ELFW(e,LIBELFBITS)` will resolve to `scn0->shdr.e64`.  This will
> be null and will then be dereferenced by the `->sh_size`, leading to the
> crash.
> 
> I can work around this by wrapping the update_if_changed call with `if
> (scn0->shdr.ELFW(e,LIBELFBITS))` but I'm not sure if that's the right fix or
> not.

Thanks for the example and fix. It is almost correct. The fix I am testing now
is:

diff --git a/libelf/elf32_updatenull.c b/libelf/elf32_updatenull.c
index 74c27fdaa7b5..a722a788ac9c 100644
--- a/libelf/elf32_updatenull.c
+++ b/libelf/elf32_updatenull.c
@@ -183,7 +183,9 @@ __elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int
*change_bop, size_t shnum)
          /* We have to  fill in the number of sections in the header
             of the zeroth section.  */
          Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
-
+         /* Make sure section zero header is actually loaded.  */
+         if (scn0->shdr.ELFW(e,LIBELFBITS) == NULL)
+           (void) __elfw2(LIBELFBITS,getshdr_wrlock) (scn0);
          update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
                             shnum, scn0->shdr_flags);
        }

I'll file a new bug against elfutils/libelf and keep this one open for making
sure that (after that libelf fix) debugedit will actually handle > 0xff00
sections.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Debugedit mailing list