Dear all, The following bug was found with AFLFast, a fork of AFL, in a 24 hour fuzzing session on Binutils. Thanks also to Van-Thuan Pham. Objcopy/Strip crashes with an invalid read of size 8 for the following execution on Ubuntu 14.04 x86_64 in Binutils trunk. However, this execution does *not* crash on preinstalled version v2.26.1 on Ubuntu 16.04 x86_64 or preinstalled version v2.24 on Ubuntu 14.04 x86_64. $ printf "\x7fELF\x01\x01\x0100000000000\x03\x00000000000000\x0c\x00\x00\x0000000000\x00\x0000\x00\x00\x03\x00\x00\x00\x00\x00\x08\x00\x00\x000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x000000000000000000\x00\x00\x00\x00\x00\x00\x00\x00000000000000\x00\x00\x00\x000000000000000\x00\x00\x000\x00\x00\x00\x00\x00\x00\x00000000000000\x00\x00\x00\x0000000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x0000000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x0000000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x0000000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x0000000000000000000000\x02\x00\x00\x00000000000000\x00\x00\x00\x0000000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x00000\xff0000000000000000\x00\xff\x00\x00000000000000\x00\x00\x00\x0000000000000000000000\x00\x00\x00\x00000000000000" > test $ strip test VALGRIND says: ==145571== Invalid read of size 8 ==145571== at 0x5702D9: copy_special_section_fields (elf.c:1349) ==145571== by 0x57B7ED: _bfd_elf_copy_private_bfd_data (elf.c:1471) ==145571== by 0x42BA8B: copy_object.part.18 (objcopy.c:2517) ==145571== by 0x42F645: copy_object (objcopy.c:1849) ==145571== by 0x42F645: copy_file (objcopy.c:2879) ==145571== by 0x41670E: strip_main (objcopy.c:3790) ==145571== by 0x41670E: main (objcopy.c:4890) ==145571== Address 0x5482cc0 is 393,552 bytes inside an unallocated block of size 4,052,080 in arena "client" ==145571== /home/ubuntu/subjects/binutils-gdb_fixed/obj-afl/binutils/strip-new: BFD (GNU Binutils) 2.27.51.20161206 assertion fail ../../bfd/elf.c:1274 ==145571== Invalid read of size 8 ==145571== at 0x56E9DA: find_link.isra.7 (elf.c:1277) ==145571== by 0x5702E1: copy_special_section_fields (elf.c:1349) ==145571== by 0x57B7ED: _bfd_elf_copy_private_bfd_data (elf.c:1471) ==145571== by 0x42BA8B: copy_object.part.18 (objcopy.c:2517) ==145571== by 0x42F645: copy_object (objcopy.c:1849) ==145571== by 0x42F645: copy_file (objcopy.c:2879) ==145571== by 0x41670E: strip_main (objcopy.c:3790) ==145571== by 0x41670E: main (objcopy.c:4890) ==145571== Address 0x5497fe0 is 480,240 bytes inside an unallocated block of size 4,051,952 in arena "client" ==145571== ==145571== Invalid read of size 4 ==145571== at 0x56EB3C: section_match (elf.c:1258) ==145571== by 0x56EB3C: find_link.isra.7 (elf.c:1287) ==145571== by 0x5702E1: copy_special_section_fields (elf.c:1349) ==145571== by 0x57B7ED: _bfd_elf_copy_private_bfd_data (elf.c:1471) ==145571== by 0x42BA8B: copy_object.part.18 (objcopy.c:2517) ==145571== by 0x42F645: copy_object (objcopy.c:1849) ==145571== by 0x42F645: copy_file (objcopy.c:2879) ==145571== by 0x41670E: strip_main (objcopy.c:3790) ==145571== by 0x41670E: main (objcopy.c:4890) ==145571== Address 0x4 is not stack'd, malloc'd or (recently) free'd GDB says: 0x00000000005702d9 in copy_special_section_fields (ibfd=ibfd@entry=0xb37c40, obfd=obfd@entry=0xb39fe0, iheader=0xb3a470, oheader=oheader@entry=0xb3e020, secnum=secnum@entry=10) at ../../bfd/elf.c:1349 1349 sh_link = find_link (obfd, iheaders[iheader->sh_link], iheader->sh_link); (gdb) bt #0 0x00000000005702d9 in copy_special_section_fields (ibfd=ibfd@entry=0xb37c40, obfd=obfd@entry=0xb39fe0, iheader=0xb3a470, oheader=oheader@entry=0xb3e020, secnum=secnum@entry=10) at ../../bfd/elf.c:1349 #1 0x000000000057b7ee in _bfd_elf_copy_private_bfd_data (ibfd=0xb37c40, obfd=0xb39fe0) at ../../bfd/elf.c:1471 #2 0x000000000042ba8c in copy_object (ibfd=ibfd@entry=0xb37c40, obfd=obfd@entry=0xb39fe0, input_arch=input_arch@entry=0x0) at ../../binutils/objcopy.c:2517 #3 0x000000000042f646 in copy_object (input_arch=0x0, obfd=0xb39fe0, ibfd=0xb37c40) at ../../binutils/objcopy.c:1849 #4 copy_file (input_filename=0x7fffffffe6a6 "test", output_filename=output_filename@entry=0xb36f00 "stf2lcWK", input_target=input_target@entry=0x0, output_target=<optimized out>, output_target@entry=0x0, input_arch=input_arch@entry=0x0) at ../../binutils/objcopy.c:2879 #5 0x000000000041670f in strip_main (argv=<optimized out>, argc=<optimized out>) at ../../binutils/objcopy.c:3790 #6 main (argc=<optimized out>, argv=<optimized out>) at ../../binutils/objcopy.c:4890 Best regards, - Marcel
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4f3ca05b487e9755018b4c9a053a2e6c35d8a7df commit 4f3ca05b487e9755018b4c9a053a2e6c35d8a7df Author: Nick Clifton <nickc@redhat.com> Date: Tue Dec 6 16:53:57 2016 +0000 Fix seg-fault in strip when copying a corrupt binary. PR binutils/20931 * elf.c (copy_special_section_fields): Check for an invalid sh_link field before attempting to follow it.
Hi Marcel, Thanks for reporting this bug. I have checked in a patch which should fix the problem. Cheers Nick
This is CVE-2017-7304