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.