Created attachment 974342 [details] a test case of the bug Description of problem: There is a UAF(used after free) in dwarf-20130126 and dwarf-20140805, and we have tested the two version, so we guess the versions which are between them will be affected too. when an odd elf file passed to dwarfdump, it would use an object which have be freed before. Version-Release number of selected component (if applicable): dwarf-20130126 and dwarf-20140805 were tested. How reproducible: run : dwarfdump a.out Actual results: when debugging it with gdb, the error information as follows: -------------------------------- /home/xqx/test/dwarf_test/dwarf-20140805/dwarfdump/dwarfdump ERROR: dwarf_elf_init: DW_DLE_ELF_STRPTR_ERROR 30 a call to elf_strptr() failed trying to get a section name (30) CU Name = CU Producer = DIE OFF = 0x00000000 GOFF = 0x00000000, Low PC = 0x00000000, High PC = 0x00000000 Program received signal SIGSEGV, Segmentation fault. 0x0000000000436305 in dwarf_finish (dbg=0x1, error=0x7fffffffe030) at dwarf_original_elf_init.c:193 193 dwarf_elf_object_access_finish(dbg->de_obj_file); ----------------------------------------------- Expected results: Additional info: ========================================= Details: ========================================== if an elf file is passed to dwarfdump, 'dwarf_elf_init' will be called and the 'Dwarf_Debug' object will be free in 'dwarf_elf_object_access_finish', if the elf file is not in correct format. -------------------------------- res = dwarf_object_init(binary_interface, errhand, errarg, ret_dbg, error); if (res != DW_DLV_OK){ dwarf_elf_object_access_finish(binary_interface); } -------------------------------- And the object will be refered again in 'print_error' : -------------------------- if (obj->object) { dwarf_elf_object_access_internals_t *internals = (dwarf_elf_object_access_internals_t *)obj->object; -------------------------- ==================== Status: ===================== We have sent email to libdwarf-list to report it. ================== references: ================== http://www.prevanders.net/dwarf.html
Can you clarify something - is this an issue in the libdwarf library? or in the dwarfdump tool? If it's in the tool then is it dwarfdump or dwarfdump2 (or both)?
(In reply to Tom Hughes from comment #1) > Can you clarify something - is this an issue in the libdwarf library? or in > the dwarfdump tool? If it's in the tool then is it dwarfdump or dwarfdump2 > (or both)? It is in dwarfdump, but the Segmentation fault caused in dwarf_original_elf_init.c which is a file in libdwarf library. And It is not in dwarfdump2.
Right, the actual crash is in the library, but is it caused by a bug in the library or by dwarfdump misusing the library? That's what I'm trying to figure out... If it is in dwarfdump then Fedora is not affected, as we actually ship dwarfdump2 as dwarfdump currently.
To answer my own question, it seems that this in fact effect dwarfdump2 (which we ship as dwarfdump) as valgrind reports two read after free errors: ==24438== Invalid read of size 8 ==24438== at 0x3D9B20DB55: dwarf_errmsg (dwarf_error.c:437 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x40E917: print_error_and_continue(Dwarf_Debug_s*, std::string const&, int, Dwarf_Error_s*) (dwarfdump.cc:1876 in /usr/bin/dwarfdump) ==24438== by 0x40EB38: print_error(Dwarf_Debug_s*, std::string const&, int, Dwarf_Error_s*) (dwarfdump.cc:1862 in /usr/bin/dwarfdump) ==24438== by 0x412026: process_one_file(Elf*, std::string const&, int, dwconf_s*) [clone .constprop.133] (dwarfdump.cc:938 in /usr/bin/dwarfdump) ==24438== by 0x40753F: main (dwarfdump.cc:388 in /usr/bin/dwarfdump) ==24438== Address 0x62c6ce30 is 16 bytes inside a block of size 24 free'd ==24438== at 0x62A5BE90: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==24438== by 0x3D9B21E957: dwarf_tdestroy_inner.isra.2 (dwarf_tsearchhash.c:632 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B21F346: _dwarf_tdestroy (dwarf_tsearchhash.c:665 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B20A94E: _dwarf_free_all_of_one_debug (dwarf_alloc.c:595 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B2156C3: dwarf_object_init (dwarf_init_finish.c:851 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B21B2F6: dwarf_elf_init_file_ownership (dwarf_original_elf_init.c:173 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B21B4E8: dwarf_elf_init (dwarf_original_elf_init.c:137 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x410054: process_one_file(Elf*, std::string const&, int, dwconf_s*) [clone .constprop.133] (dwarfdump.cc:932 in /usr/bin/dwarfdump) ==24438== by 0x40753F: main (dwarfdump.cc:388 in /usr/bin/dwarfdump) and: ==24438== Invalid read of size 8 ==24438== at 0x3D9B20DB35: dwarf_errno (dwarf_error.c:424 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x40E931: print_error_and_continue(Dwarf_Debug_s*, std::string const&, int, Dwarf_Error_s*) (dwarfdump.cc:1877 in /usr/bin/dwarfdump) ==24438== by 0x40EB38: print_error(Dwarf_Debug_s*, std::string const&, int, Dwarf_Error_s*) (dwarfdump.cc:1862 in /usr/bin/dwarfdump) ==24438== by 0x412026: process_one_file(Elf*, std::string const&, int, dwconf_s*) [clone .constprop.133] (dwarfdump.cc:938 in /usr/bin/dwarfdump) ==24438== by 0x40753F: main (dwarfdump.cc:388 in /usr/bin/dwarfdump) ==24438== Address 0x62c6ce30 is 16 bytes inside a block of size 24 free'd ==24438== at 0x62A5BE90: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==24438== by 0x3D9B21E957: dwarf_tdestroy_inner.isra.2 (dwarf_tsearchhash.c:632 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B21F346: _dwarf_tdestroy (dwarf_tsearchhash.c:665 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B20A94E: _dwarf_free_all_of_one_debug (dwarf_alloc.c:595 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B2156C3: dwarf_object_init (dwarf_init_finish.c:851 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B21B2F6: dwarf_elf_init_file_ownership (dwarf_original_elf_init.c:173 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x3D9B21B4E8: dwarf_elf_init (dwarf_original_elf_init.c:137 in /usr/lib64/libdwarf.so.1.20140805.0) ==24438== by 0x410054: process_one_file(Elf*, std::string const&, int, dwconf_s*) [clone .constprop.133] (dwarfdump.cc:932 in /usr/bin/dwarfdump) ==24438== by 0x40753F: main (dwarfdump.cc:388 in /usr/bin/dwarfdump)
Switching back to dwarfdump (dwarfdump2 will be deprecated in the next release anyway) isn't going to help as it has exactly the same structure. I'm inclined to this this is a library API problem - the dwarf_elf_init is returning DLV_ERROR but attempts to ask the library for details of the error are causing it to access freed memory. So I don't think the dwarfdump tools are doing anything wrong in the way they use the library. Hopefully upstream will come up with something soon...
libdwarf-20150112-1.fc21 has been submitted as an update for Fedora 21. https://admin.fedoraproject.org/updates/libdwarf-20150112-1.fc21
Package libdwarf-20150112-1.fc21: * should fix your issue, * was pushed to the Fedora 21 testing repository, * should be available at your local mirror within two days. Update it with: # su -c 'yum update --enablerepo=updates-testing libdwarf-20150112-1.fc21' as soon as you are able to. Please go to the following url: https://admin.fedoraproject.org/updates/FEDORA-2015-0707/libdwarf-20150112-1.fc21 then log in and leave karma (feedback).
Package libdwarf-20150115-1.fc21: * should fix your issue, * was pushed to the Fedora 21 testing repository, * should be available at your local mirror within two days. Update it with: # su -c 'yum update --enablerepo=updates-testing libdwarf-20150115-1.fc21' as soon as you are able to. Please go to the following url: https://admin.fedoraproject.org/updates/FEDORA-2015-0707/libdwarf-20150115-1.fc21 then log in and leave karma (feedback).
libdwarf-20150115-1.fc21 has been pushed to the Fedora 21 stable repository. If problems still persist, please make note of it in this bug report.