Bug 1177758 - Use after free vulnerability in Dwarfdump.
Summary: Use after free vulnerability in Dwarfdump.
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: libdwarf
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Tom Hughes
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: CVE-2014-9482
TreeView+ depends on / blocked
 
Reported: 2014-12-30 09:58 UTC by xqx
Modified: 2015-01-30 04:38 UTC (History)
4 users (show)

Fixed In Version: libdwarf-20150115-1.fc21
Clone Of:
Environment:
Last Closed: 2015-01-30 04:38:46 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
a test case of the bug (2.53 KB, application/zip)
2014-12-30 09:58 UTC, xqx
no flags Details

Description xqx 2014-12-30 09:58:09 UTC
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

Comment 1 Tom Hughes 2014-12-30 10:02:21 UTC
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)?

Comment 2 xqx 2014-12-30 13:18:01 UTC
(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.

Comment 3 Tom Hughes 2014-12-30 13:46:20 UTC
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.

Comment 4 Tom Hughes 2015-01-05 12:17:56 UTC
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)

Comment 5 Tom Hughes 2015-01-05 12:27:05 UTC
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...

Comment 6 Fedora Update System 2015-01-14 09:27:32 UTC
libdwarf-20150112-1.fc21 has been submitted as an update for Fedora 21.
https://admin.fedoraproject.org/updates/libdwarf-20150112-1.fc21

Comment 7 Fedora Update System 2015-01-14 23:56:31 UTC
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).

Comment 8 Fedora Update System 2015-01-20 20:59:50 UTC
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).

Comment 9 Fedora Update System 2015-01-30 04:38:46 UTC
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.


Note You need to log in before you can comment on or make changes to this bug.