elfutils: memory allocation failure in allocate_elf (common.h)

Description:
elfutils is a set of libraries/utilities to handle ELF objects (drop in replacement for libelf).

During the fuzz of libdwarf, I noticed a memory allocation failure which involves elfutils.
Actually there is a proposed patch on the elfutils mailing list, but nobody commented.
EDIT: The patch has been committed, see below.

The complete ASan output:

# dwarfdump $FILE
==21982==ERROR: AddressSanitizer failed to allocate 0x3401fb3000 (223371538432) bytes of LargeMmapAllocator (error code: 12)
==21982==Process memory map follows:
        0x000000400000-0x0000006bc000   /usr/bin/dwarfdump-asan
        0x0000008bb000-0x0000008c3000   /usr/bin/dwarfdump-asan
        0x0000008c3000-0x000000900000   /usr/bin/dwarfdump-asan
        0x000000900000-0x0000015a4000
        0x00007fff7000-0x00008fff7000
        0x00008fff7000-0x02008fff7000
        0x02008fff7000-0x10007fff8000
        0x600000000000-0x603000000000
        0x603000000000-0x603000010000
        0x603000010000-0x604000000000
        0x604000000000-0x604000010000
        0x604000010000-0x619000000000
        0x619000000000-0x619000020000
        0x619000020000-0x624000000000
        0x624000000000-0x624000020000
        0x624000020000-0x640000000000
        0x640000000000-0x640000003000
        0x7f9f19d00000-0x7f9f19e00000
        0x7f9f19f00000-0x7f9f1a000000
        0x7f9f1a0a9000-0x7f9f1c3fb000
        0x7f9f1c3fb000-0x7f9f1c58e000   /lib64/libc-2.22.so
        0x7f9f1c58e000-0x7f9f1c78e000   /lib64/libc-2.22.so
        0x7f9f1c78e000-0x7f9f1c792000   /lib64/libc-2.22.so
        0x7f9f1c792000-0x7f9f1c794000   /lib64/libc-2.22.so
        0x7f9f1c794000-0x7f9f1c798000
        0x7f9f1c798000-0x7f9f1c7ae000   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.9.3/libgcc_s.so.1
        0x7f9f1c7ae000-0x7f9f1c9ad000   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.9.3/libgcc_s.so.1
        0x7f9f1c9ad000-0x7f9f1c9ae000   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.9.3/libgcc_s.so.1
        0x7f9f1c9ae000-0x7f9f1c9af000   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.9.3/libgcc_s.so.1
        0x7f9f1c9af000-0x7f9f1c9b1000   /lib64/libdl-2.22.so
        0x7f9f1c9b1000-0x7f9f1cbb1000   /lib64/libdl-2.22.so
        0x7f9f1cbb1000-0x7f9f1cbb2000   /lib64/libdl-2.22.so
        0x7f9f1cbb2000-0x7f9f1cbb3000   /lib64/libdl-2.22.so
        0x7f9f1cbb3000-0x7f9f1ccb0000   /lib64/libm-2.22.so
        0x7f9f1ccb0000-0x7f9f1ceaf000   /lib64/libm-2.22.so
        0x7f9f1ceaf000-0x7f9f1ceb0000   /lib64/libm-2.22.so
        0x7f9f1ceb0000-0x7f9f1ceb1000   /lib64/libm-2.22.so
        0x7f9f1ceb1000-0x7f9f1ceb7000   /lib64/librt-2.22.so
        0x7f9f1ceb7000-0x7f9f1d0b7000   /lib64/librt-2.22.so
        0x7f9f1d0b7000-0x7f9f1d0b8000   /lib64/librt-2.22.so
        0x7f9f1d0b8000-0x7f9f1d0b9000   /lib64/librt-2.22.so
        0x7f9f1d0b9000-0x7f9f1d0d0000   /lib64/libpthread-2.22.so
        0x7f9f1d0d0000-0x7f9f1d2cf000   /lib64/libpthread-2.22.so
        0x7f9f1d2cf000-0x7f9f1d2d0000   /lib64/libpthread-2.22.so
        0x7f9f1d2d0000-0x7f9f1d2d1000   /lib64/libpthread-2.22.so
        0x7f9f1d2d1000-0x7f9f1d2d5000
        0x7f9f1d2d5000-0x7f9f1d2ea000   /lib64/libz.so.1.2.8
        0x7f9f1d2ea000-0x7f9f1d4e9000   /lib64/libz.so.1.2.8
        0x7f9f1d4e9000-0x7f9f1d4ea000   /lib64/libz.so.1.2.8
        0x7f9f1d4ea000-0x7f9f1d4eb000   /lib64/libz.so.1.2.8
        0x7f9f1d4eb000-0x7f9f1d502000   /usr/lib64/libelf-0.166.so
        0x7f9f1d502000-0x7f9f1d702000   /usr/lib64/libelf-0.166.so
        0x7f9f1d702000-0x7f9f1d703000   /usr/lib64/libelf-0.166.so
        0x7f9f1d703000-0x7f9f1d704000   /usr/lib64/libelf-0.166.so
        0x7f9f1d704000-0x7f9f1d726000   /lib64/ld-2.22.so
        0x7f9f1d8b2000-0x7f9f1d91a000
        0x7f9f1d91a000-0x7f9f1d925000
        0x7f9f1d925000-0x7f9f1d926000   /lib64/ld-2.22.so
        0x7f9f1d926000-0x7f9f1d927000   /lib64/ld-2.22.so
        0x7f9f1d927000-0x7f9f1d928000
        0x7ffc7e844000-0x7ffc7e865000   [stack]
        0x7ffc7e905000-0x7ffc7e907000   [vvar]
        0x7ffc7e907000-0x7ffc7e909000   [vdso]
        0xffffffffff600000-0xffffffffff601000   [vsyscall]
==21982==End of process memory map.
==21982==AddressSanitizer CHECK failed: /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_common.cc:183 "((0 && "unable to mmap")) != (0)" (0x0, 0x0)
    #0 0x4ca3ed in __asan::AsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/asan_rtl.cc:67
    #1 0x4d0f23 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_common.cc:159
    #2 0x4d1111 in __sanitizer::ReportMmapFailureAndDie(unsigned long, char const*, char const*, int, bool) /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_common.cc:183
    #3 0x4da14a in __sanitizer::MmapOrDie(unsigned long, char const*, bool) /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc:122
    #4 0x42493a in __sanitizer::LargeMmapAllocator::Allocate(__sanitizer::AllocatorStats*, unsigned long, unsigned long) /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_allocator.h:1033
    #5 0x42493a in __sanitizer::CombinedAllocator<__sanitizer::SizeClassAllocator64<105553116266496ul, 4398046511104ul, 0ul, __sanitizer::SizeClassMap, __asan::AsanMapUnmapCallback>, __sanitizer::SizeClassAllocatorLocalCache<__sanitizer::SizeClassAllocator64<105553116266496ul, 4398046511104ul, 0ul, __sanitizer::SizeClassMap, __asan::AsanMapUnmapCallback> >, __sanitizer::LargeMmapAllocator >::Allocate(__sanitizer::SizeClassAllocatorLocalCache<__sanitizer::SizeClassAllocator64<105553116266496ul, 4398046511104ul, 0ul, __sanitizer::SizeClassMap, __asan::AsanMapUnmapCallback> >*, unsigned long, unsigned long, bool, bool) /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_allocator.h:1302
    #6 0x42493a in __asan::Allocator::Allocate(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/asan_allocator.cc:368
    #7 0x420003 in __asan::Allocator::Calloc(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*) /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/asan_allocator.cc:557
    #8 0x420003 in __asan::asan_calloc(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*) /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/asan_allocator.cc:722
    #9 0x4c0c3a in calloc /var/tmp/portage/sys-devel/llvm-3.8.1-r2/work/llvm-3.8.1.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:67
    #10 0x7f9f1d4ee5e0 in allocate_elf /tmp/portage/dev-libs/elfutils-0.166/work/elfutils-0.166/libelf/common.h:74
    #11 0x7f9f1d4ee5e0 in file_read_elf /tmp/portage/dev-libs/elfutils-0.166/work/elfutils-0.166/libelf/elf_begin.c:282
    #12 0x7f9f1d4ef2b8 in read_unmmaped_file /tmp/portage/dev-libs/elfutils-0.166/work/elfutils-0.166/libelf/elf_begin.c:584
    #13 0x7f9f1d4ef2b8 in read_file /tmp/portage/dev-libs/elfutils-0.166/work/elfutils-0.166/libelf/elf_begin.c:670
    #14 0x4f9676 in main /tmp/dwarf-20161021/dwarfdump/dwarfdump.c:585:11
    #15 0x7f9f1c41b61f in __libc_start_main /var/tmp/portage/sys-libs/glibc-2.22-r4/work/glibc-2.22/csu/libc-start.c:289
    #16 0x419588 in _start (/usr/bin/dwarfdump-asan+0x419588)

Affected version:
0.166

Fixed version:
0.168

Proposed patch:
https://lists.fedorahosted.org/archives/list/elfutils-devel@lists.fedorahosted.org/message/EJWVY7TMRDEMWPAPNVU3V4MZYG5HANF2/

Commit Fix:
https://git.fedorahosted.org/cgit/elfutils.git/commit/?id=191000fdedba3fafe4d5b8cddad3f3318b49c3fb

Credit:
This bug was discovered by Agostino Sarubbo of Gentoo.

CVE:
CVE-2016-10254

Reproducer:
https://github.com/asarubbo/poc/raw/master/00011-elfutils-memalloc-allocate_elf

Timeline:
2016-10-24: bug discovered and reported to upstream
2016-11-04: blog post about the issue
2016-11-10: upstream committed the proposed patch
2016-12-27: upstream released 0.168
2017-03-22: CVE assigned

Note:
This bug was found with American Fuzzy Lop.

Permalink:

elfutils: memory allocation failure in allocate_elf (common.h)

This entry was posted in advisories, security. Bookmark the permalink.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.