https://sourceware.org/bugzilla/show_bug.cgi?id=34323
Paul Wang <lswang1112 at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |lswang1112 at gmail dot com
--- Comment #1 from Paul Wang <lswang1112 at gmail dot com> ---
Created attachment 16805
--> https://sourceware.org/bugzilla/attachment.cgi?id=16805&action=edit
Minimal 64-byte PoC ELF triggering null-pointer dereference in
process_got_section_contents
Additional analysis for bug #34323: null-pointer dereference in
process_got_section_contents via NULL section_headers
Affected version: GNU Binutils 2.46.50.20260629 (git HEAD 0e73a13c)
Confirmed reproduced on latest upstream HEAD as of 2026-06-30.
I independently found this bug through fuzzing and am providing a root
cause analysis, a minimal 64-byte PoC, ASan traces, and a suggested fix,
hoping this helps move the issue toward resolution.
------------------------------------------------------------------------
ROOT CAUSE
------------------------------------------------------------------------
process_got_section_contents() iterates over filedata->section_headers to
locate .got sections, but does not guard against section_headers being NULL:
/* binutils/readelf.c:21563-21568 */
initialise_dumps_byname (filedata);
for (i = 0, section = filedata->section_headers; /* can be NULL */
i < filedata->file_header.e_shnum;
i++, section++)
if (section->sh_type == SHT_PROGBITS /* line 21568: NULL
deref */
&& section->sh_size != 0)
filedata->section_headers is populated by get_section_headers(). When the
ELF header's e_shoff points beyond the end of the file, get_section_headers()
fails and returns NULL, leaving section_headers as NULL. However,
process_got_section_contents() is still entered when e_shnum > 0, so the
loop executes and crashes on section->sh_type.
------------------------------------------------------------------------
ASAN + UBSAN OUTPUT
------------------------------------------------------------------------
../../src/binutils/readelf.c:21568:16: runtime error:
member access within null pointer of type 'struct Elf_Internal_Shdr'
ERROR: AddressSanitizer: SEGV on unknown address 0x000000000004
#0 process_got_section_contents binutils/readelf.c:21568
#1 process_object binutils/readelf.c:24981
#2 process_file binutils/readelf.c:25404
#3 main binutils/readelf.c:25470
SUMMARY: AddressSanitizer: SEGV in process_got_section_contents
GDB on a plain build:
Program received signal SIGSEGV, Segmentation fault.
#0 process_got_section_contents (filedata=...) at binutils/readelf.c:21568
------------------------------------------------------------------------
HOW TO REPRODUCE
------------------------------------------------------------------------
Build from latest HEAD:
git clone --depth 1 https://sourceware.org/git/binutils-gdb.git
cd binutils-gdb
mkdir build && cd build
../configure --disable-gdb \
CFLAGS="-g -O1 -fsanitize=address,undefined -Wno-error=format-overflow"
make -j$(nproc) all-binutils
The attached poc.elf is 64 bytes (minimal ELF -- header only, no sections).
Run with:
./binutils/readelf --dyn-syms -D -W -a -s poc.elf
The 64-byte PoC in hexadecimal:
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0300 3e00 0100 0000 2011 0000 0000 0000 ..>..... .......
00000020: 4000 0000 0000 0000 08be 0000 0000 0000 @...............
00000030: 0000 0000 4000 3800 0d00 4000 2700 2600 [email protected]...@.'.&.
Key ELF header fields:
e_type 0x10 0x0003 ET_DYN
e_machine 0x12 0x003e x86-64
e_shoff 0x28 0x0000be08 section header offset (far beyond 64-byte EOF)
e_shnum 0x3c 0x0027 claims 39 sections
e_shoff = 0xbe08 points past the file end, so get_section_headers() fails
and section_headers remains NULL. But e_shnum = 39 > 0 allows the loop to
run, causing the dereference at line 21568.
------------------------------------------------------------------------
Build & Platform
------------------------------------------------------------------------
binutils version: GNU Binutils 2.46.50.20260629 (git HEAD 0e73a13c)
component: readelf
OS: Ubuntu 24.04.4 LTS
arch: x86_64
------------------------------------------------------------------------
SUGGESTED FIX
------------------------------------------------------------------------
Add a NULL guard at the top of the section-iteration loop in
process_got_section_contents() (binutils/readelf.c):
+ if (filedata->section_headers == NULL)
+ goto out;
for (i = 0, section = filedata->section_headers;
i < filedata->file_header.e_shnum;
i++, section++)
Alternatively, guard the loop condition directly:
for (i = 0, section = filedata->section_headers;
- i < filedata->file_header.e_shnum;
+ filedata->section_headers != NULL && i <
filedata->file_header.e_shnum;
i++, section++)
------------------------------------------------------------------------
IMPACT
------------------------------------------------------------------------
Null-pointer dereference (CWE-476) in process_got_section_contents,
triggered by a 64-byte ELF with an out-of-range section header offset.
Reproducible with standard readelf flags (-a -s -D). Impact is denial
of service.
--
You are receiving this mail because:
You are on the CC list for the bug.