Created attachment 10217 [details] ./objdump -S $POC The first heap overflow debug information is below: $ ./objdump -S POC1 ... Disassembly of section .init: 0000000000401ab0 <.init>: ================================================================= ==14591==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf4c00bf4 at pc 0xf72e3c75 bp 0xffa3a548 sp 0xffa3a11c READ of size 148 at 0xf4c00bf4 thread T0 #0 0xf72e3c74 in __asan_memcpy (/usr/lib32/libasan.so.2+0x8ac74) #1 0xf72e3e2f in memcpy (/usr/lib32/libasan.so.2+0x8ae2f) #2 0x824edca in get_build_id /home/icy/real/binutils-2.28/bfd/opncls.c:1833 #3 0x825e675 in get_build_id /home/icy/real/binutils-2.28/bfd/opncls.c:1782 #4 0x825e675 in get_build_id_name /home/icy/real/binutils-2.28/bfd/opncls.c:1875 #5 0x825e675 in find_separate_debug_file /home/icy/real/binutils-2.28/bfd/opncls.c:1386 #6 0x825e675 in bfd_follow_build_id_debuglink /home/icy/real/binutils-2.28/bfd/opncls.c:1989 #7 0x84c132d in _bfd_dwarf2_slurp_debug_info dwarf2.c:3920 #8 0x84c6a40 in _bfd_dwarf2_find_nearest_line dwarf2.c:4115 #9 0x839a408 in _bfd_elf_find_nearest_line /home/icy/real/binutils-2.28/bfd/elf.c:8565 #10 0x8073c06 in show_line objdump.c:1434 #11 0x8073c06 in disassemble_bytes objdump.c:1728 #12 0x8073c06 in disassemble_section objdump.c:2241 #13 0x82641fc in bfd_map_over_sections /home/icy/real/binutils-2.28/bfd/section.c:1395 #14 0x8068597 in disassemble_data objdump.c:2375 #15 0x8068597 in dump_bfd objdump.c:3469 #16 0x806b0ce in display_object_bfd objdump.c:3526 #17 0x806b0ce in display_any_bfd objdump.c:3615 #18 0x8056562 in display_file objdump.c:3636 #19 0x8056562 in main objdump.c:3919 #20 0xf70b479d in __libc_start_main (/lib32/libc.so.6+0x1879d) #21 0x805944b (/home/icy/real/binutils-2.28/binutils/objdump+0x805944b) 0xf4c00bf4 is located 0 bytes to the right of 36-byte region [0xf4c00bd0,0xf4c00bf4) allocated by thread T0 here: #0 0xf72eff06 in malloc (/usr/lib32/libasan.so.2+0x96f06) #1 0x8247518 in bfd_malloc /home/icy/real/binutils-2.28/bfd/libbfd.c:184 SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 __asan_memcpy Shadow bytes around the buggy address: 0x3e980120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e980130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e980140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e980150: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e980160: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x3e980170: fa fa fa fa fa fa fa fa fa fa 00 00 00 00[04]fa 0x3e980180: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fd 0x3e980190: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 04 fa 0x3e9801a0: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 04 fa 0x3e9801b0: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 04 fa 0x3e9801c0: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 04 fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe ==14591==ABORTING Crash happended at line bfd/opncls.c:1833. The function tries to copy inote.descsz bytes from inote.descdata to build_id->data, but it didn't take the situation that value inote.descsz is larger than inote.descdata into account. 1771 static struct bfd_build_id * 1772 get_build_id (bfd *abfd) 1773 { ... 1825 build_id = bfd_alloc (abfd, sizeof (struct bfd_build_id) + inote.descsz); 1826 if (build_id == NULL) 1827 { 1828 free (contents); 1829 return NULL; 1830 } 1831 1832 build_id->size = inote.descsz; 1833 memcpy (build_id->data, inote.descdata, inote.descsz); 1834 abfd->build_id = build_id; 1835 free (contents); 1836 1837 return build_id; 1838 } ... The second heap overflow debug information is below: $ ./objdump -S POC2 fuzz/objdump/output/crashes/id:000008,sig:06,src:000000,op:flip1,pos:92180: file format elf64-x86-64 Disassembly of section .init: 0000000000401ab0 <.init>: 401ab0: be be be be be mov $0xbebebebe,%esi 401ab5: be be be be be mov $0xbebebebe,%esi 401aba: be be be be be mov $0xbebebebe,%esi 401abf: be be be be be mov $0xbebebebe,%esi 401ac4: be be be be be mov $0xbebebebe,%esi 401ac9: be .byte 0xbe ================================================================= ==96445==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf4300b0a at pc 0x0807eefe bp 0xffad0b58 sp 0xffad0b48 READ of size 1 at 0xf4300b0a thread T0 #0 0x807eefd in disassemble_bytes objdump.c:1692 #1 0x807eefd in disassemble_section objdump.c:2241 #2 0x82641fc in bfd_map_over_sections /home/icy/real/binutils-2.28/bfd/section.c:1395 #3 0x8068597 in disassemble_data objdump.c:2375 #4 0x8068597 in dump_bfd objdump.c:3469 #5 0x806b0ce in display_object_bfd objdump.c:3526 #6 0x806b0ce in display_any_bfd objdump.c:3615 #7 0x8056562 in display_file objdump.c:3636 #8 0x8056562 in main objdump.c:3919 #9 0xf6fbc79d in __libc_start_main (/lib32/libc.so.6+0x1879d) #10 0x805944b (/home/icy/real/binutils-2.28/binutils/objdump+0x805944b) 0xf4300b0a is located 0 bytes to the right of 26-byte region [0xf4300af0,0xf4300b0a) allocated by thread T0 here: #0 0xf71f7f06 in malloc (/usr/lib32/libasan.so.2+0x96f06) #1 0x88832a7 in xmalloc xmalloc.c:148 SUMMARY: AddressSanitizer: heap-buffer-overflow objdump.c:1692 disassemble_bytes Shadow bytes around the buggy address: 0x3e860110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e860120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e860130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e860140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e860150: fa fa fa fa fa fa fa fa fd fd fd fd fa fa 00 00 =>0x3e860160: 00[02]fa fa 00 00 00 04 fa fa 00 00 00 04 fa fa 0x3e860170: fd fd fd fd fa fa 00 00 03 fa fa fa 00 00 05 fa 0x3e860180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e860190: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e8601a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x3e8601b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe ==96445==ABORTING The array data accesses uninitialized memory in line objdump.c:1692. 1615 static void 1616 disassemble_bytes (struct disassemble_info * inf, ... 1687 aux->reloc = NULL; 1688 1689 /* If we see more than SKIP_ZEROES octets of zeroes, we just 1690 print `...'. */ 1691 for (z = addr_offset * opb; z < stop_offset * opb; z++) 1692 if (data[z] != 0) 1693 break; 1694 if (! disassemble_zeroes ... Credits: This vulnerability is detected by team OWL337, with our custom fuzzer collAFL. Please contact ganshuitao@gmail.com and chaoz@tsinghua.edu.cn if you need more info about the team, the tool or the vulnerability.
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cfd14a500e0485374596234de4db10e88ebc7618 commit cfd14a500e0485374596234de4db10e88ebc7618 Author: Nick Clifton <nickc@redhat.com> Date: Mon Jun 26 15:25:08 2017 +0100 Fix address violations when atempting to parse fuzzed binaries. PR binutils/21665 bfd * opncls.c (get_build_id): Check that the section is beig enough to contain the whole note. * compress.c (bfd_get_full_section_contents): Check for and reject a section whoes size is greater than the size of the entire file. * elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not contain a notes section. binutils* objdump.c (disassemble_section): Skip any section that is bigger than the entire file.
Hi Owl, Thanks for reporting these bugs. I have checked in a patch which should address both issues, but if you find that either of the files still causes faults when you test them please feel free to reopen this PR. Cheers Nick
(In reply to cvs-commit@gcc.gnu.org from comment #1) > The master branch has been updated by Nick Clifton <nickc@sourceware.org>: > > https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git; > h=cfd14a500e0485374596234de4db10e88ebc7618 > > commit cfd14a500e0485374596234de4db10e88ebc7618 > Author: Nick Clifton <nickc@redhat.com> > Date: Mon Jun 26 15:25:08 2017 +0100 > > Fix address violations when atempting to parse fuzzed binaries. > > PR binutils/21665 > bfd * opncls.c (get_build_id): Check that the section is beig enough > to contain the whole note. > * compress.c (bfd_get_full_section_contents): Check for and reject > a section whoes size is greater than the size of the entire file. > * elf32-v850.c (v850_elf_copy_notes): Allow for the ouput to not > contain a notes section. > > binutils* objdump.c (disassemble_section): Skip any section that is > bigger > than the entire file. This patch caused: FAIL: Build libfoo.so with compressed debug sections FAIL: Build libbar.so with compressed debug sections FAIL: Build libfoozlib.so with compressed debug sections with zlib-gabi FAIL: Build libbarzlib.so with compressed debug sections with zlib-gabi FAIL: Build libzlibfoo.so with zlib compressed debug sections FAIL: Build libgnufoo.so with zlib-gnu compressed debug sections FAIL: Build libgabifoo.so with zlib-gabi compressed debug sections FAIL: Build gabiend.o with zlib-gabi compressed debug sections FAIL: Run normal with libfoo.so with compressed debug sections FAIL: Run normal with libfoozlib.so with compressed debug sections with zlib-gabi FAIL: Run zlibnormal with libzlibfoo.so with zlib compressed debug sections FAIL: Run zlibnormal with libfoozlib.so with zlib compressed debug sections FAIL: Run gnunormal with libgnufoo.so with zlib-gnu compressed debug sections FAIL: Run gnunormal with libfoozlib.so with zlib-gnu compressed debug sections FAIL: Run gabinormal with libgabifoo.so with zlib-gabi compressed debug sections FAIL: Run gabinormal with libfoozlib.so with zlib-gabi compressed debug sections FAIL: Link with zlib-gabi compressed debug input FAIL: Link -r with zlib-gabi compressed debug output FAIL: Link with zlib compressed debug output FAIL: Link with zlib-gnu compressed debug output FAIL: Link with zlib-gabi compressed debug output with GCC 4.2 on x86-64.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0630b49c470ca2e3c3f74da4c7e4ff63440dd71f commit 0630b49c470ca2e3c3f74da4c7e4ff63440dd71f Author: H.J. Lu <hjl.tools@gmail.com> Date: Mon Jun 26 09:24:49 2017 -0700 Check file size before getting section contents Don't check the section size in bfd_get_full_section_contents since the size of a decompressed section may be larger than the file size. Instead, check file size in _bfd_generic_get_section_contents. PR binutils/21665 * compress.c (bfd_get_full_section_contents): Don't check the file size here. * libbfd.c (_bfd_generic_get_section_contents): Check for and reject a section whoes size + offset is greater than the size of the entire file. (_bfd_generic_get_section_contents_in_window): Likewise.
Fixed for 2.29.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1f473e3d0ad285195934e6a077c7ed32afe66437 commit 1f473e3d0ad285195934e6a077c7ed32afe66437 Author: H.J. Lu <hjl.tools@gmail.com> Date: Mon Jun 26 15:47:16 2017 -0700 Add a missing line to _bfd_generic_get_section_contents_in_window PR binutils/21665 * libbfd.c (_bfd_generic_get_section_contents_in_window): Add a missing line.
The master branch has been updated by Pedro Alves <palves@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ab27f80c5dceaa23c4ba7f62c0d5d22a5d5dd7a1 commit ab27f80c5dceaa23c4ba7f62c0d5d22a5d5dd7a1 Author: Pedro Alves <palves@redhat.com> Date: Tue Jun 27 00:21:25 2017 +0100 Fix GDB regressions caused by previous bfd_get_section_contents changes Ref: https://sourceware.org/ml/binutils/2017-06/msg00343.html bfd/ChangeLog: 2017-06-26 Pedro Alves <palves@redhat.com> PR binutils/21665 * libbfd.c (_bfd_generic_get_section_contents): Add "count", not "sz".
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7211ae501eb0de1044983f2dfb00091a58fbd66c commit 7211ae501eb0de1044983f2dfb00091a58fbd66c Author: Alan Modra <amodra@gmail.com> Date: Tue Jun 27 09:45:04 2017 +0930 More fixes for bfd_get_section_contents change PR binutils/21665 * libbfd.c (_bfd_generic_get_section_contents): Delete abort. Use unsigned file pointer type, and remove cast. * libbfd.c (_bfd_generic_get_section_contents_in_window): Likewise. Add "count", not "sz".
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ea9aafc41a764e4e2dbb88a7b031e886b481b99a commit ea9aafc41a764e4e2dbb88a7b031e886b481b99a Author: Alan Modra <amodra@gmail.com> Date: Tue Jun 27 14:43:49 2017 +0930 Warning fix PR binutils/21665 * libbfd.c (_bfd_generic_get_section_contents): Warning fix. (_bfd_generic_get_section_contents_in_window): Likewise.
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=60a02042bacf8d25814430080adda61ed086bca6 commit 60a02042bacf8d25814430080adda61ed086bca6 Author: Nick Clifton <nickc@redhat.com> Date: Fri Jun 30 11:03:37 2017 +0100 Fix failures in MMIX linker tests introduced by fix for PR 21665. PR binutils/21665 * objdump.c (disassemble_section): Move check for an overlarge section to just before the allocation of memory. Do not check section size against file size, but instead use an arbitrary 2Gb limit. Issue a warning message if the section is too big.
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bae7501e87ab614115d9d3213b4dd18d96e604db commit bae7501e87ab614115d9d3213b4dd18d96e604db Author: Alan Modra <amodra@gmail.com> Date: Sat Jul 1 21:58:10 2017 +0930 Use bfd_malloc_and_get_section It's nicer than xmalloc followed by bfd_get_section_contents, since xmalloc exits on failure and needs a check that its size_t arg doesn't lose high bits when converted from bfd_size_type. PR binutils/21665 * objdump.c (strtab): Make var a bfd_byte*. (disassemble_section): Don't limit malloc size. Instead, use bfd_malloc_and_get_section. (read_section_stabs): Use bfd_malloc_and_get_section. Return bfd_byte*. (find_stabs_section): Remove now unnecessary cast. * objcopy.c (copy_object): Use bfd_malloc_and_get_section. Free contents on error return. * nlmconv.c (copy_sections): Use bfd_malloc_and_get_section.