Bug 20931

Summary: STRIP crashes during copy of private bfd data
Product: binutils Reporter: Marcel Böhme <boehme.marcel>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: nickc, thuanpv
Priority: P2    
Version: 2.28   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Marcel Böhme 2016-12-06 04:47:34 UTC
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
Comment 1 Sourceware Commits 2016-12-06 16:55:01 UTC
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.
Comment 2 Nick Clifton 2016-12-06 16:56:57 UTC
Hi Marcel,

  Thanks for reporting this bug.

  I have checked in a patch which should fix the problem.

Cheers
  Nick
Comment 3 Thuan Pham 2017-04-13 06:21:18 UTC
This is CVE-2017-7304