https://sourceware.org/bugzilla/show_bug.cgi?id=34392
Bug ID: 34392
Summary: libdw: heap-buffer-overflow read in dwarf_getpubnames
while parsing .debug_pubnames
Product: elfutils
Version: unspecified
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: libdw
Assignee: unassigned at sourceware dot org
Reporter: karankurani3k at gmail dot com
CC: elfutils-devel at sourceware dot org
Target Milestone: ---
Created attachment 16840
--> https://sourceware.org/bugzilla/attachment.cgi?id=16840&action=edit
Standalone reproducer and ASan trace for .debug_pubnames OOB read
On current elfutils HEAD 304f2a62981badd1d1c8f2507dc8d156856e065b,
dwarf_getpubnames() can read 4 bytes past the end of a malloc-backed ELF image
while parsing .debug_pubnames.
git status --porcelain printed no output.
The issue is in libdw/dwarf_getpubnames.c:get_offsets().
The code validates the referenced .debug_info CU offset with only a 3-byte
minimum:
if (__libdw_read_offset (dbg, dbg, IDX_debug_pubnames,
readp + 2, len_bytes,
&mem[cnt].cu_offset, IDX_debug_info, 3))
It then immediately performs a 4-byte read from that offset:
if (read_4ubyte_unaligned_noncvt (infop) == DWARF3_LENGTH_64_BIT)
A malformed ELF can set the .debug_pubnames CU offset to 0 and provide a
.debug_info section that is exactly 3 bytes long and placed as the final
section
ending at EOF. The offset check passes, then the 4-byte read crosses one byte
past the malloc-backed file buffer.
Public API path:
elf_memory()
-> dwarf_begin_elf()
-> dwarf_getpubnames()
-> get_offsets()
-> read_4ubyte_unaligned_noncvt()
PoC ELF layout:
.debug_pubnames offset=320 size=18
.debug_info offset=377 size=3
total ELF size=380
.debug_info is final at EOF
ASan result:
ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 4
#0 read_4ubyte_unaligned_noncvt ../../elfutils/libdw/memory-access.h:283
#1 get_offsets ../../elfutils/libdw/dwarf_getpubnames.c:116
#2 dwarf_getpubnames ../../elfutils/libdw/dwarf_getpubnames.c:163
Impact:
A malicious or malformed ELF/DWARF file can trigger an out-of-bounds read in
libdw consumers that parse untrusted debug data and call dwarf_getpubnames().
The immediate impact is crash/DoS or undefined behavior while processing the
malformed ELF/DWARF file. I am not claiming RCE.
Not a duplicate:
This is a different path from the recently fixed issues in .debug_macro,
.debug_str_offsets, .debug_rnglists, .debug_loclists, .debug_frame CIE
augmentation, and .debug_line.
This issue is specifically in .debug_pubnames / .debug_info validation
through
dwarf_getpubnames().
Additional check:
I also checked .debug_pubtypes on this HEAD. There appears to be no
dwarf_getpubtypes() API, no IDX_debug_pubtypes, and no reachable libdw
.debug_pubtypes parser path, so this report is limited to .debug_pubnames.
Please include the following credit if this is fixed:
Reported-by: Karan Kurani <[email protected]>
Suggested fix:
Require at least 4 bytes at the referenced .debug_info CU offset before
reading the initial unit_length field.
For example, change the size argument in the __libdw_read_offset() call from
3 to 4:
if (__libdw_read_offset (dbg, dbg, IDX_debug_pubnames,
readp + 2, len_bytes,
&mem[cnt].cu_offset, IDX_debug_info, 4))
goto err_return;
Alternatively, add an explicit 4-byte bounds check before:
read_4ubyte_unaligned_noncvt (infop)
--
You are receiving this mail because:
You are on the CC list for the bug.