https://sourceware.org/bugzilla/show_bug.cgi?id=32650
Mark Wielaard <mark at klomp dot org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed| |2025-02-08 CC| |mark at klomp dot org Assignee|unassigned at sourceware dot org |mark at klomp dot org Ever confirmed|0 |1 Status|UNCONFIRMED |ASSIGNED --- Comment #1 from Mark Wielaard <mark at klomp dot org> --- Replicated under valgrind with --debug-dump=abbrev ==552106== Invalid read of size 8 ==552106== at 0x48A7F70: __libdw_thread_tail (libdw_alloc.c:112) ==552106== by 0x488BB98: __libdw_getabbrev (dwarf_getabbrev.c:104) ==552106== by 0x48A1BA2: dwarf_offabbrev (dwarf_offabbrev.c:44) ==552106== by 0x412073: print_debug_abbrev_section (readelf.c:5676) ==552106== by 0x426003: print_debug (readelf.c:12151) ==552106== by 0x404614: process_elf_file (readelf.c:1084) ==552106== by 0x403B91: process_dwflmod (readelf.c:840) ==552106== by 0x48BD8FF: dwfl_getmodules (dwfl_getmodules.c:86) ==552106== by 0x403FC5: process_file (readelf.c:948) ==552106== by 0x402AE0: main (readelf.c:417) ==552106== Address 0xfffffffffffffff8 is not stack'd, malloc'd or (recently) free'd The issue triggers in __libdw_getabbrev when an abbrev is found with a number we have already seen (all abbrev numbers should be unique) or some other sanity check fails later on: if (unlikely (abb->offset != offset)) { /* A duplicate abbrev code at a different offset, that should never happen. */ invalid: if (! foundit) libdw_typed_unalloc (dbg, Dwarf_Abbrev); __libdw_seterrno (DWARF_E_INVALID_DWARF); return NULL; } The unalloc fails when called through dwarf_offabbrev. In that case result != NULL. Which means no new abbrev has been allocated. dwarf_offabbrev is the only function calling with result != NULL, all other calls to __libdw_getabbrev pass result as NULL and so won't trigger this bug in case of an invalid abbrev. Bug introduced in commit 287e502815bf ("libdw: Introduce libdw_unalloc to stop Dwarf_Abbrev leaks.") Possible fix: diff --git a/libdw/dwarf_getabbrev.c b/libdw/dwarf_getabbrev.c index 5b02333f3467..f32326649592 100644 --- a/libdw/dwarf_getabbrev.c +++ b/libdw/dwarf_getabbrev.c @@ -100,7 +100,7 @@ __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset, /* A duplicate abbrev code at a different offset, that should never happen. */ invalid: - if (! foundit) + if (! foundit && result == NULL) libdw_typed_unalloc (dbg, Dwarf_Abbrev); __libdw_seterrno (DWARF_E_INVALID_DWARF); return NULL; @@ -155,8 +155,11 @@ __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset, { /* The entry was already in the table, remove the one we just created and get the one already inserted. */ - libdw_typed_unalloc (dbg, Dwarf_Abbrev); + if (result == NULL) + libdw_typed_unalloc (dbg, Dwarf_Abbrev); abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code); + if (result != NULL) + *result = *abb; } out: -- You are receiving this mail because: You are on the CC list for the bug.