Bug 22506

Summary: Segmentation fault in coff_i386_reloc
Product: binutils Reporter: Mingi Cho <mgcho.minic>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: nickc
Priority: P2    
Version: 2.30   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: poc of the crash

Description Mingi Cho 2017-11-28 02:55:24 UTC
Created attachment 10642 [details]
poc of the crash

Triggered by "./objdump -W $POC"
Tested on Ubuntu 16.04 (x86)

Segmentation fault occurred when processing malformed PE file


The GDB debugging information is as follows:

(gdb) r -W $POC

Starting program: ./objdump -W ~/Downloads/perform_reloc

/home/min/Downloads/perform_reloc:     file format pei-i386

Contents of the  section:

00000000 ZERO terminator


./objdump: /home/min/Downloads/perform_reloc: warning: illegal symbol index 131072 in relocs
./objdump: /home/min/Downloads/perform_reloc: warning: illegal symbol index 0 in relocs


Breakpoint 1, coff_i386_reloc (abfd=0x8256a08, reloc_entry=0x825a07c, symbol=0x8225ad0 <global_syms+48>, 
    data=0x825b210, input_section=0x8257b9c, output_bfd=0x0, error_message=0xbfffea84) at ./coff-i386.c:81
81    if (bfd_is_com_section (symbol->section))

(gdb) p *reloc_entry 
$11 = {sym_ptr_ptr = 0x824faa4 <_bfd_std_section+488>, address = 7864211, addend = 0, 
  howto = 0x822f0dc <howto_table+1040>}

Program received signal SIGSEGV, Segmentation fault.
0x080c6045 in bfd_getl32 (p=0x89db1a3) at libbfd.c:557
557   v = (unsigned long) addr[0];

(gdb) bt
#0  0x080c6045 in bfd_getl32 (p=0x89db1a3) at libbfd.c:557
#1  0x08152787 in coff_i386_reloc (abfd=0x8256a08, reloc_entry=0x825a07c, symbol=0x8225ad0 <global_syms+48>, 
    data=0x825b210, input_section=0x8257b9c, output_bfd=0x0, error_message=0xbfffea84) at ./coff-i386.c:167
#2  0x08177fce in bfd_perform_relocation (abfd=0x8256a08, reloc_entry=0x825a07c, data=0x825b210, 
    input_section=0x8257b9c, output_bfd=0x0, error_message=0xbfffea84) at reloc.c:622
#3  0x0817987d in bfd_generic_get_relocated_section_contents (abfd=0x8256a08, link_info=0xbfffebf0, 
    link_order=0xbfffebd8, data=0x825b210 "S mode.\r\r\n$", relocatable=0, symbols=0x825b3a0) at reloc.c:8200
#4  0x080bef47 in bfd_get_relocated_section_contents (abfd=0x8256a08, link_info=0xbfffebf0, 
    link_order=0xbfffebd8, data=0x825b210 "S mode.\r\r\n$", relocatable=0, symbols=0x825b3a0) at bfd.c:1930
#5  0x080cb551 in bfd_simple_get_relocated_section_contents (abfd=0x8256a08, sec=0x8257b9c, 
    outbuf=0x825b210 "S mode.\r\r\n$", symbol_table=0x825b3a0) at simple.c:264
#6  0x08049e7a in load_specific_debug_section (debug=eh_frame, sec=0x8257b9c, file=0x8256a08) at ./objdump.c:2496
#7  0x0804dc41 in dump_dwarf_section (abfd=0x8256a08, section=0x8257b9c, arg=0x0) at ./objdump.c:2634
#8  0x080cab5c in bfd_map_over_sections (abfd=0x8256a08, operation=0x804daf0 <dump_dwarf_section>, 
    user_storage=0x0) at section.c:1395
#9  0x0804c906 in dump_dwarf (abfd=0x8256a08) at ./objdump.c:2703
#10 0x0804b97b in dump_bfd (abfd=0x8256a08) at ./objdump.c:3544
#11 0x0804b5d2 in display_object_bfd (abfd=0x8256a08) at ./objdump.c:3611
#12 0x0804b587 in display_any_bfd (file=0x8256a08, level=0) at ./objdump.c:3700
#13 0x0804b2b1 in display_file (filename=0xbffff2ef "/home/min/Downloads/perform_reloc", target=0x0, last_file=1)
    at ./objdump.c:3721
#14 0x0804ae80 in main (argc=3, argv=0xbffff0d4) at ./objdump.c:4023


Credits:

Mingi Cho and Taekyoung Kwon of the Information Security Lab, Yonsei University.
Comment 1 Sourceware Commits 2017-11-28 13:21:51 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

commit b23dc97fe237a1d9e850d7cbeee066183a00630b
Author: Nick Clifton <nickc@redhat.com>
Date:   Tue Nov 28 13:20:31 2017 +0000

    Fix a memory access violation when attempting to parse a corrupt COFF binary with a relocation that points beyond the end of the section to be relocated.
    
    	PR 22506
    	* reloc.c (reloc_offset_in_range): Rename to
    	bfd_reloc_offset_in_range and export.
    	(bfd_perform_relocation): Rename function invocation.
    	(bfd_install_relocation): Likewise.
    	(bfd_final_link_relocate): Likewise.
    	* bfd-in2.h: Regenerate.
    	* coff-arm.c (coff_arm_reloc): Use bfd_reloc_offset_in_range.
    	* coff-i386.c (coff_i386_reloc): Likewise.
    	* coff-i860.c (coff_i860_reloc): Likewise.
    	* coff-m68k.c (mk68kcoff_common_addend_special_fn): Likewise.
    	* coff-m88k.c (m88k_special_reloc): Likewise.
    	* coff-mips.c (mips_reflo_reloc): Likewise.
    	* coff-x86_64.c (coff_amd64_reloc): Likewise.
Comment 2 Nick Clifton 2017-11-28 13:25:36 UTC
Hi Mingi,

  Thanks for reporting this bug.  It turns out that we already had a function
  to check for relocations with out of bounds offsets, but it was not being
  used in some of the COFF backends of the linker.  So I have checked in a
  patch to fix this.

Cheers
  Nick