Bug 20908

Summary: LD crashes when writing linked file
Product: binutils Reporter: Marcel Böhme <boehme.marcel>
Component: ldAssignee: 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-02 07:59:16 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.

The linker crashes with an invalid read of size 8 for the following execution on Ubuntu 16.04 x86_64 in Binutils trunk and for preinstalled version v2.26.1 and on Ubuntu 14.04 x86_64 for Binutils in trunk. It works fine for Binutils v2.24.

$ printf "\x00\x00\xff\xff\x00\x00L\x010000\x18\x00\x00\x0000\x0400000000000000000000\x00000\x00" > test
$ ./ld -qN test
/home/ubuntu/subjects/binutils-gdb/ld/ld-new: i386 architecture of input file `test2' is incompatible with i386:x86-64 output
/home/ubuntu/subjects/binutils-gdb/ld/ld-new: warning: cannot find entry symbol _start; defaulting to 0000000000400078
Segmentation fault

VALGRIND says:
==8561== Invalid read of size 8
==8561==    at 0x6DE6D0: bfd_elf_final_link (elflink.c:11427)
==8561==    by 0x484B7C: ldwrite (ldwrite.c:577)
==8561==    by 0x408334: main (ldmain.c:444)
==8561==  Address 0x3030303030303068 is not stack'd, malloc'd or (recently) free'd

UBSAN complains:
../../bfd/peicode.h:658:42: runtime error: member access within misaligned address 0x61e00000f8c7 for type 'struct coff_section_tdata', which requires 8 byte alignment
0x61e00000f8c7: note: pointer points here
 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00
             ^ 

Best regards,
- Marcel
Comment 1 Sourceware Commits 2016-12-02 17:47:50 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d7f399a8de4c55eb841db6493597a587fac002de

commit d7f399a8de4c55eb841db6493597a587fac002de
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Dec 2 17:46:26 2016 +0000

    Fix seg-fault in linker when passed a corrupt binary input file.
    
    	PR lf/20908
    	* elflink.c (bfd_elf_final_link): Check for ELF flavour binaries
    	when following indirect links.
Comment 2 Nick Clifton 2016-12-02 17:50:30 UTC
Hi Marcel,

  Thanks for reporting this bug.  The problem was that the code to emit relocs was not checking the format of the input file before trying to read the ELF reloc section header...  Patch applied, bug fixed.

Cheers
  Nick
Comment 3 Sourceware Commits 2016-12-15 13:27:11 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a961cdd5f139d3c3e09170db52bd8df7dafae13f

commit a961cdd5f139d3c3e09170db52bd8df7dafae13f
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Dec 15 21:29:44 2016 +1030

    Linking non-ELF file broken by PR20908 fix
    
    	PR ld/20968
    	PR ld/20908
    	* elflink.c (bfd_elf_final_link): Revert 2016-12-02 change.  Move
    	reloc counting code later after ELF flavour test.
Comment 4 Thuan Pham 2017-04-13 06:16:12 UTC
This is CVE-2017-7299