Bug 20922

Summary: STRIP crashes during copy of special section fields
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-03 08:55:42 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 4 for the following execution in Binutils trunk on Ubuntu 16.04 x86_64 and 14.04 x86_64. However, it does *not* crash for preinstalled version v2.26.1 on Ubuntu 16.04 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\x00\x00\x00\x000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x000000000000000000\x00\x00\x00\x00\x00\x00\x00\x00000000000000\x00\x00\x00\x00\x00\x00\x00\x000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x00\x00\x00\x00\x000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x000000000000000000\x00\x00\x00\x00\x00\x00\x00\x00000000000000\x00\x00\x00\x00\x00\x00\x00\x000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x00\x00\x00\x00\x000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x00\x00\x00\x00\x000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x00\x00\x00\x00\x000000000000000000\x00\x00\x00\x00000000000000\x00\x00\x00\x00000\xff\xff00000000\x00\x00\x000\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x0000000000\x00\x00\x00\x00\x00\x00\x00\x000000000000000000\x00\x00\x00\x00000000000000" > test
$ strip test
./binutils/strip-new: test: warning: sh_link not set for section `'
./binutils/strip-new: stZoIaxG: warning: sh_link not set for section `'
Segmentation fault

UBSAN says:
../../bfd/elf.c:1253:6: runtime error: member access within null pointer of type 'const struct Elf_Internal_Shdr'

Valgrind says:
==84818== Invalid read of size 4
==84818==    at 0x56E746: section_match (elf.c:1258)
==84818==    by 0x56E746: find_link.isra.4 (elf.c:1274)
==84818==    by 0x570DCB: copy_special_section_fields (elf.c:1364)
==84818==    by 0x57C26D: _bfd_elf_copy_private_bfd_data (elf.c:1465)
==84818==    by 0x42B87B: copy_object.part.18 (objcopy.c:2517)
==84818==    by 0x42F435: copy_object (objcopy.c:1849)
==84818==    by 0x42F435: copy_file (objcopy.c:2879)
==84818==    by 0x41670E: strip_main (objcopy.c:3788)
==84818==    by 0x41670E: main (objcopy.c:4888)
==84818==  Address 0x4 is not stack'd, malloc'd or (recently) free'd

Best regards,
- Marcel
Comment 1 Sourceware Commits 2016-12-05 13:36:58 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

commit a55c9876bb111fd301b4762cf501de0040b8f9db
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Dec 5 13:35:50 2016 +0000

    Fix seg-fault attempting to strip a corrupt binary.
    
    	PR binutils/20922
    	* elf.c (find_link): Check for null headers before attempting to
    	match them.
Comment 2 Nick Clifton 2016-12-05 13:41:35 UTC
Hi Marcel,

  Thank you for reporting this bug.

  I have checked in a patch to add checks for null section pointers
  when following sh_link fields.  This should fix the problem.

Cheers
  Nick
Comment 3 Thuan Pham 2017-04-13 06:20:27 UTC
This is CVE-2017-7303