Bug 22509 - Null pointer dereference on coff_slurp_reloc_table
Summary: Null pointer dereference on coff_slurp_reloc_table
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.30
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2017-11-28 05:53 UTC by Mingi Cho
Modified: 2022-11-23 12:29 UTC (History)
1 user (show)

See Also:
Last reconfirmed:

poc of the crash (12.58 KB, application/x-ms-dos-executable)
2017-11-28 05:53 UTC, Mingi Cho

Note You need to log in before you can comment on or make changes to this bug.
Description Mingi Cho 2017-11-28 05:53:15 UTC
Created attachment 10645 [details]
poc of the crash

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

Null pointer dereference occurred when processing malformed PE file.

The GDB debugging information is as follows:

Program received signal SIGSEGV, Segmentation fault.
0x08153c96 in coff_slurp_reloc_table (abfd=0x825ca08, asect=0x825db9c, symbols=0x0) at ./coffcode.h:5353
5353		      ptr = *(cache_ptr->sym_ptr_ptr);

(gdb) bt
#0  0x08153c96 in coff_slurp_reloc_table (abfd=0x825ca08, asect=0x825db9c, symbols=0x0) at ./coffcode.h:5353
#1  0x0815026a in coff_canonicalize_reloc (abfd=0x825ca08, section=0x825db9c, relptr=0x8260e28, symbols=0x0)
    at ./coffcode.h:5452
#2  0x080c105b in bfd_canonicalize_reloc (abfd=0x825ca08, asect=0x825db9c, location=0x8260e28, symbols=0x0)
    at bfd.c:1372
#3  0x08049fcd in load_specific_debug_section (debug=eh_frame, sec=0x825db9c, file=0x825ca08) at ./objdump.c:2524
#4  0x0804de0b in dump_dwarf_section (abfd=0x825ca08, section=0x825db9c, arg=0x0) at ./objdump.c:2665
#5  0x080cd36c in bfd_map_over_sections (abfd=0x825ca08, operation=0x804dcb0 <dump_dwarf_section>, 
    user_storage=0x0) at section.c:1395
#6  0x0804ca8d in dump_dwarf (abfd=0x825ca08) at ./objdump.c:2738
#7  0x0804baeb in dump_bfd (abfd=0x825ca08) at ./objdump.c:3582
#8  0x0804b742 in display_object_bfd (abfd=0x825ca08) at ./objdump.c:3649
#9  0x0804b6f7 in display_any_bfd (file=0x825ca08, level=0) at ./objdump.c:3738
#10 0x0804b421 in display_file (filename=0xbffff2af "/home/min/Downloads/null_coff_slurp_reloc_table", 
    target=0x0, last_file=1) at ./objdump.c:3759
#11 0x0804aff0 in main (argc=3, argv=0xbffff094) at ./objdump.c:4061

(gdb) p *cache_ptr->sym_ptr_ptr 
Cannot access memory at address 0x0

ASAN output:

==7926==ERROR: AddressSanitizer: SEGV on unknown address 0x00000000 (pc 0x085014b4 bp 0xb6100650 sp 0xbffd7690 T0)
    #0 0x85014b3 in coff_slurp_reloc_table /home/min/fuzzing/src/binutils-2.29.1/bfd/./coffcode.h:5336:14
    #1 0x85014b3 in coff_canonicalize_reloc /home/min/fuzzing/src/binutils-2.29.1/bfd/./coffcode.h:5435
    #2 0x82e9f82 in bfd_canonicalize_reloc /home/min/fuzzing/src/binutils-2.29.1/bfd/bfd.c:1074:10
    #3 0x81404bd in load_specific_debug_section /home/min/fuzzing/src/binutils-2.29.1/binutils/./objdump.c:2511:18
    #4 0x814a5a2 in dump_dwarf_section /home/min/fuzzing/src/binutils-2.29.1/binutils/./objdump.c:2626:6
    #5 0x830c34b in bfd_map_over_sections /home/min/fuzzing/src/binutils-2.29.1/bfd/section.c:1395:5
    #6 0x8148a07 in dump_dwarf /home/min/fuzzing/src/binutils-2.29.1/binutils/./objdump.c:2695:3
    #7 0x8145058 in dump_bfd /home/min/fuzzing/src/binutils-2.29.1/binutils/./objdump.c:3536:5
    #8 0x8143726 in display_object_bfd /home/min/fuzzing/src/binutils-2.29.1/binutils/./objdump.c:3603:7
    #9 0x8143726 in display_any_bfd /home/min/fuzzing/src/binutils-2.29.1/binutils/./objdump.c:3692
    #10 0x814267d in display_file /home/min/fuzzing/src/binutils-2.29.1/binutils/./objdump.c:3713:3
    #11 0x814267d in main /home/min/fuzzing/src/binutils-2.29.1/binutils/./objdump.c:4015
    #12 0xb74be636 in __libc_start_main /build/glibc-KM3i_a/glibc-2.23/csu/../csu/libc-start.c:291
    #13 0x806c367 in _start (/home/min/fuzzing/program/binutils-2.29.1-fast/bin/objdump+0x806c367)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/min/fuzzing/src/binutils-2.29.1/bfd/./coffcode.h:5336:14 in coff_slurp_reloc_table


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


commit 4581a1c7d304ce14e714b27522ebf3d0188d6543
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Nov 29 17:12:12 2017 +0000

    Check for a NULL symbol pointer when reading relocs from a COFF based file.
    	PR 22509
    	* coffcode.h (coff_slurp_reloc_table): Check for a NULL symbol
    	pointer when processing relocs.
Comment 2 Nick Clifton 2017-11-29 17:15:00 UTC
Hi Mingi,

  Thanks for reporting this bug.  I have applied a small patch to fix the 


  The issue was that the code that loaded the relocs assumed that a symbol
  was always available, whereas in your test file, it was not.

Comment 3 Sourceware Commits 2022-11-23 12:29:45 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:


commit e6b6fad2fe4d180bcd65a1e0aabc6ba763901346
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Nov 23 22:12:30 2022 +1030

    PR22509 - Null pointer dereference on coff_slurp_reloc_table
    This extends the commit 4581a1c7d304 fix to more targets, which
    hardens BFD a little.  I think the real underlying problem was the
    bfd_canonicalize_reloc call in load_specific_debug_section which
    passed a NULL for "symbols".  Fix that too.
            PR 22509
            * aoutx.h (swap_ext_reloc_out): Gracefully handle NULL symbols.
            * i386lynx.c (swap_ext_reloc_out): Likewise.
            * pdp11.c (pdp11_aout_swap_reloc_out): Likewise.
            * coff-tic30.c (reloc_processing): Likewise.
            * coff-tic4x.c (tic4x_reloc_processing): Likewise.
            * coff-tic54x.c (tic54x_reloc_processing): Likewise.
            * coff-z80.c (reloc_processing): Likewise.
            * coff-z8k.c (reloc_processing): Likewise.
            * ecoff.c (ecoff_slurp_reloc_table): Likewise.
            * som.c (som_set_reloc_info): Likewise.
            * objdump.c (load_specific_debug_section): Pass syms to