Created attachment 10793 [details] ELF file to trigger the bug Triggered by "./objdump -x -W $POC" Tested on Ubuntu 16.04 (x86) Segmentation fault occurred when processing malformed PE file. The GDB debugging information is as follows: - ELF File Program received signal SIGSEGV, Segmentation fault. bfd_section_from_shdr (abfd=0x8218a08, shindex=6) at elf.c:2022 warning: Source file is more recent than executable. 2022 hdr = elf_elfsections (abfd)[shindex]; (gdb) bt #0 bfd_section_from_shdr (abfd=0x8218a08, shindex=6) at elf.c:2022 #1 0x080ab375 in bfd_elf32_object_p (abfd=0x8218a08) at elfcode.h:805 #2 0x080958b5 in bfd_check_format_matches (abfd=0x8218a08, format=bfd_object, matching=0xbfffef48) at format.c:311 #3 0x0804faa8 in display_object_bfd (abfd=0x8218a08) at ./objdump.c:3663 #4 display_any_bfd (file=file@entry=0x8218a08, level=level@entry=0) at ./objdump.c:3754 #5 0x08051a54 in display_file ( filename=0xbffff274 "/home/min/fuzzing/result/binutils/paper/2/objdump_x_W_pe_1_2/triage-latest/../../objdump_x_W_elf_1_2/triage-latest/objalloc.c:186:17/id:000511,sig:06,src:004162,op:havoc,rep:4", target=<optimized out>, last_file=1) at ./objdump.c:3775 #6 0x0804bf70 in main (argc=4, argv=0xbffff064) at ./objdump.c:4077 - PE File Program received signal SIGSEGV, Segmentation fault. __memcpy_ia32 () at ../sysdeps/i386/i686/multiarch/../memcpy.S:90 90 ../sysdeps/i386/i686/multiarch/../memcpy.S: No such file or directory. (gdb) bt #0 __memcpy_ia32 () at ../sysdeps/i386/i686/multiarch/../memcpy.S:90 #1 0xb7e6830f in __GI__IO_file_xsgetn (fp=0x821aa88, data=0x8218828, n=8388608) at fileops.c:1383 #2 0xb7e6a33e in __GI__IO_sgetn (fp=0x821aa88, data=0x8218828, n=8388608) at genops.c:467 #3 0xb7e5d8f7 in __GI__IO_fread (buf=0x8218828, size=1, count=8388608, fp=0x821aa88) at iofread.c:38 #4 0x080fc573 in fread (__stream=0x821aa88, __n=8388608, __size=1, __ptr=<optimized out>) at /usr/include/i386-linux-gnu/bits/stdio2.h:295 #5 cache_bread_1 (nbytes=<optimized out>, buf=<optimized out>, abfd=0x8218a08) at cache.c:337 #6 cache_bread (abfd=0x8218a08, buf=0x8218828, nbytes=4294967295) at cache.c:371 #7 0x08094618 in bfd_bread (ptr=0x8218828, size=4294967295, abfd=0x8218a08) at bfdio.c:196 #8 0x08097416 in _bfd_generic_get_section_contents (abfd=0x8218a08, section=0x8219c50, location=0x8218828, offset=0, count=4294967295) at libbfd.c:826 #9 0x080d19db in _bfd_elf_parse_attributes (abfd=0x8218a08, hdr=0x8219478) at elf-attrs.c:444 #10 0x080afce9 in bfd_section_from_shdr (abfd=0x8218a08, shindex=3) at elf.c:2465 #11 0x080ab375 in bfd_elf32_object_p (abfd=0x8218a08) at elfcode.h:805 #12 0x080958b5 in bfd_check_format_matches (abfd=0x8218a08, format=bfd_object, matching=0xbfffef78) at format.c:311 #13 0x0804faa8 in display_object_bfd (abfd=0x8218a08) at ./objdump.c:3663 #14 display_any_bfd (file=file@entry=0x8218a08, level=level@entry=0) at ./objdump.c:3754 #15 0x08051a54 in display_file ( filename=0xbffff29d "/home/min/fuzzing/result/binutils/paper/2/objdump_x_W_pe_1_2/triage-latest/./SEGV/id:000361,sig:06,src:002944,op:fieldm,pos:652,val:+4", target=<optimized out>, last_file=1) at ./objdump.c:3775 #16 0x0804bf70 in main (argc=3, argv=0xbffff094) at ./objdump.c:4077 (gdb) ASAN output: ==11631==ERROR: AddressSanitizer: SEGV on unknown address 0x2439a980 (pc 0x0871c7fa bp 0xbfc94668 sp 0xbfc94520 T0) #0 0x871c7f9 in objalloc_free /home/min/fuzzing/src/binutils/binutils-gdb/libiberty/./objalloc.c:186:17 #1 0x8308faf in bfd_hash_table_free /home/min/fuzzing/src/binutils/binutils-gdb/bfd/hash.c:426:3 #2 0x831298d in _bfd_delete_bfd /home/min/fuzzing/src/binutils/binutils-gdb/bfd/opncls.c:125:7 #3 0x831298d in bfd_close_all_done /home/min/fuzzing/src/binutils/binutils-gdb/bfd/opncls.c:773 #4 0x81431fc in display_file /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:3788:5 #5 0x81431fc in main /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:4077 #6 0xb7515636 in __libc_start_main /build/glibc-mUak1Y/glibc-2.23/csu/../csu/libc-start.c:291 #7 0x806c9a7 in _start (/home/min/fuzzing/program/binutils-asan/bin/objdump+0x806c9a7) AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /home/min/fuzzing/src/binutils/binutils-gdb/libiberty/./objalloc.c:186:17 in objalloc_free Credits: Mingi Cho and Taekyoung Kwon of the Information Security Lab, Yonsei University.
Created attachment 10794 [details] PE file to trigger the bug
Hi Mingi, I am sorry, but I am unable to reproduce these failures. I do however get "memory exhausted" error messages, so I wonder if you have your test environment set up to generate a seg-fault when a memory allocation fails ? Please could you try the uploaded patch which I think will stop the invalid memory allocations from happening. Is this sufficient to resolve this problem for you ? Cheers Nick
Created attachment 10814 [details] Proposed patch
Hi Nick, I have tested the bug in x86 Ubuntu system. When hdr->sh_size is 0xffffffff then malloc(hdr->sh_size +1) returns a valid pointer with small size at _bfd_elf_parse_attributes function and the bug is occurred after that. The proposed patch works on my system and fixes the problem. However, I got an error in _bfd_error_handler function during compilation time. Best regards, Mingi
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=95a6d23566165208853a68d9cd3c6eedca840ec6 commit 95a6d23566165208853a68d9cd3c6eedca840ec6 Author: Nick Clifton <nickc@redhat.com> Date: Tue May 8 12:51:06 2018 +0100 Prevent a memory exhaustion failure when running objdump on a fuzzed input file with corrupt string and attribute sections. PR 22809 * elf.c (bfd_elf_get_str_section): Check for an excessively large string section. * elf-attrs.c (_bfd_elf_parse_attributes): Issue an error if the attribute section is larger than the size of the file.
Patch applied (with an update to fix the compilation error).