https://sourceware.org/bugzilla/show_bug.cgi?id=23528
--- Comment #1 from Mark Wielaard <mark at klomp dot org> --- Replicated under valgrind: $ valgrind -q eu-readelf -S Double-free-libelf ==13892== Invalid free() / delete / delete[] / realloc() ==13892== at 0x48369EB: free (vg_replace_malloc.c:530) ==13892== by 0x4899094: elf_end (elf_end.c:171) ==13892== by 0x4868619: free_file (dwfl_module.c:57) ==13892== by 0x4868787: __libdwfl_module_free (dwfl_module.c:113) ==13892== by 0x4868370: dwfl_end (dwfl_end.c:54) ==13892== by 0x114617: process_file (readelf.c:873) ==13892== by 0x111C13: main (readelf.c:350) ==13892== Address 0x51138b0 is 0 bytes inside a block of size 36 free'd ==13892== at 0x48369EB: free (vg_replace_malloc.c:530) ==13892== by 0x48A5C46: __libelf_reset_rawdata (elf_compress.c:325) ==13892== by 0x48A5D80: elf_compress (elf_compress.c:514) ==13892== by 0x4869F00: relocate_section (relocate.c:507) ==13892== by 0x486A567: __libdwfl_relocate (relocate.c:752) ==13892== by 0x486EB5B: dwfl_module_getelf (dwfl_module_getelf.c:52) ==13892== by 0x11E764: process_elf_file (readelf.c:901) ==13892== by 0x11E764: process_dwflmod (readelf.c:760) ==13892== by 0x486C450: dwfl_getmodules (dwfl_getmodules.c:86) ==13892== by 0x1143BF: process_file (readelf.c:868) ==13892== by 0x111C13: main (readelf.c:350) ==13892== Block was alloc'd at ==13892== at 0x48357BF: malloc (vg_replace_malloc.c:299) ==13892== by 0x48A59E7: __libelf_decompress (elf_compress.c:223) ==13892== by 0x48A60D4: elf_compress_gnu (elf_compress_gnu.c:178) ==13892== by 0x4869F68: relocate_section (relocate.c:504) ==13892== by 0x486A567: __libdwfl_relocate (relocate.c:752) ==13892== by 0x486EB5B: dwfl_module_getelf (dwfl_module_getelf.c:52) ==13892== by 0x11E764: process_elf_file (readelf.c:901) ==13892== by 0x11E764: process_dwflmod (readelf.c:760) ==13892== by 0x486C450: dwfl_getmodules (dwfl_getmodules.c:86) ==13892== by 0x1143BF: process_file (readelf.c:868) ==13892== by 0x111C13: main (readelf.c:350) The issue is this section: [10] .zdebug_abbrev PROGBITS 00000000 00011d 00002b 0 NGTC 0 0 1 Note how it claims to be both gnu style compressed (starts with .zdebug) and gabi compressed (has SHF_COMPRESSED flag C). Then the code in relocate.c tries to decompress the section data twice: if (strncmp (tname, ".zdebug", strlen ("zdebug")) == 0) elf_compress_gnu (tscn, 0, 0); if ((tshdr->sh_flags & SHF_COMPRESSED) != 0) if (elf_compress (tscn, 0, 0) < 0) return DWFL_E_LIBELF; So it tries to decompress twice. The second call sees that the data is already decompressed and assumes it was done implicitly by some call to elf_strptr, and so just uses the decompressed data to setup the decompressed section data again, throwing away the buffer that elf_compress_gnu has already setup. elf_end then tries to free this data buffer again. The most direct fix is to just make relocate.c not decompress twice in different ways: diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c index 9afcdebe..81750cd3 100644 --- a/libdwfl/relocate.c +++ b/libdwfl/relocate.c @@ -238,8 +238,7 @@ resolve_symbol (Dwfl_Module *referer, struct reloc_symtab_cache *symtab, /* If the section is already decompressed, that isn't an error. */ if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0) elf_compress_gnu (scn, 0, 0); - - if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + else if ((shdr->sh_flags & SHF_COMPRESSED) != 0) if (elf_compress (scn, 0, 0) < 0) return DWFL_E_LIBELF; @@ -502,8 +501,7 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr, if (strncmp (tname, ".zdebug", strlen ("zdebug")) == 0) elf_compress_gnu (tscn, 0, 0); - - if ((tshdr->sh_flags & SHF_COMPRESSED) != 0) + else if ((tshdr->sh_flags & SHF_COMPRESSED) != 0) if (elf_compress (tscn, 0, 0) < 0) return DWFL_E_LIBELF; @@ -523,8 +521,7 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr, if (strncmp (sname, ".zdebug", strlen ("zdebug")) == 0) elf_compress_gnu (scn, 0, 0); - - if ((shdr->sh_flags & SHF_COMPRESSED) != 0) + else if ((shdr->sh_flags & SHF_COMPRESSED) != 0) if (elf_compress (scn, 0, 0) < 0) return DWFL_E_LIBELF; But we can probably fix it in elf_compress[_gnu] by better checks or just by refusing to elf_compress_gnu if the section already has the SHF_COMPRESSED flag set. -- You are receiving this mail because: You are on the CC list for the bug.