Bug 22443 - Global buffer overflow in _bfd_elf_get_symbol_version_string
Summary: Global buffer overflow in _bfd_elf_get_symbol_version_string
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.30
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-11-15 16:09 UTC by Mingi Cho
Modified: 2017-11-23 20:10 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2017-11-17 00:00:00


Attachments
poc file (2.29 KB, application/octet-stream)
2017-11-15 16:09 UTC, Mingi Cho
Details
Proposed patch (267 bytes, patch)
2017-11-17 12:28 UTC, Nick Clifton
Details | Diff
Proposed patch (288 bytes, patch)
2017-11-17 12:41 UTC, Nick Clifton
Details | Diff
minimized testcase (2.97 KB, application/x-executable)
2017-11-17 16:32 UTC, Mingi Cho
Details
Proposed patch (301 bytes, patch)
2017-11-17 16:48 UTC, Mingi Cho
Details | Diff
Proposed patch (437 bytes, patch)
2017-11-17 17:12 UTC, Nick Clifton
Details | Diff
Proposed patch (404 bytes, patch)
2017-11-17 17:15 UTC, Nick Clifton
Details | Diff
Proposed patch (414 bytes, patch)
2017-11-17 18:58 UTC, Mingi Cho
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mingi Cho 2017-11-15 16:09:40 UTC
Created attachment 10591 [details]
poc file

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

Global buffer overflow is occured when corrupted processing elf file.


Configuration information:

CC=clang CXX=clang++ CFLAGS="-g -O0 -fno-omit-frame-pointer -fsanitize=address -fno-sanitize-recover=all" CXXFLAGS=-fsanitize="-g -O0 -fno-omit-frame-pointer -fsanitize=address -fno-sanitize-recover=all" ./configure


ASAN output:

==14558==ERROR: AddressSanitizer
: global-buffer-overflow on address 0x08626220 at pc 0x082dd706 bp 0xbfeb88a8 sp 0xbfeb889c
READ of size 2 at 0x08626220 thread T0
    #0 0x82dd705 in _bfd_elf_get_symbol_version_string /home/min/fuzzing/src/binutils/binutils-gdb/bfd/elf.c:1838:59
    #1 0x8149baf in objdump_print_symname /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:892:22
    #2 0x814f52f in disassemble_bytes /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:2050:7
    #3 0x814f52f in disassemble_section /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:2319
    #4 0x8279497 in bfd_map_over_sections /home/min/fuzzing/src/binutils/binutils-gdb/bfd/section.c:1395:5
    #5 0x8144976 in disassemble_data /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:2455:3
    #6 0x8144976 in dump_bfd /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:3554
    #7 0x8142d75 in display_object_bfd /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:3611:7
    #8 0x8142d75 in display_any_bfd /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:3700
    #9 0x8141fe4 in display_file /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:3721:3
    #10 0x8141fe4 in main /home/min/fuzzing/src/binutils/binutils-gdb/binutils/./objdump.c:4023
    #11 0xb7494636 in __libc_start_main /build/glibc-KM3i_a/glibc-2.23/csu/../csu/libc-start.c:291
    #12 0x806c687 in _start (/home/min/fuzzing/program/binutils-master-patch/bin/objdump+0x806c687)

0x08626220 is located 32 bytes to the left of global variable '<string literal>' defined in 'section.c:771:3' (0x8626240) of size 6
  '<string literal>' is ascii string '*UND*'
0x08626220 is located 0 bytes to the right of global variable 'global_syms' defined in 'section.c:758:22' (0x86261c0) of size 96
SUMMARY: AddressSanitizer: global-buffer-overflow /home/min/fuzzing/src/binutils/binutils-gdb/bfd/elf.c:1838:59 in _bfd_elf_get_symbol_version_string


Credits:

Mingi Cho and Taekyoung Kwon of the Information Security Lab, Yonsei University.
Comment 1 Nick Clifton 2017-11-16 15:41:22 UTC
Hi Mingi,

 I cannot reproduce this failure. :-(  Please could you check with the latest binutils sources in case it has already been fixed by someone else ?

  If the problem persists, please could you post an updated address sanitizer output, since the code in bfd/elf.c has been edited recently.

Cheers
  Nick
Comment 2 Alan Modra 2017-11-17 09:29:58 UTC
I can see one problem when looking at objdump -x under gdb.  _bfd_elf_get_symbol_version_string is called with symbol being one of the global_syms (the first one I saw was *ABS*).  Those symbols are not full elf symbols so the cast to elf_symbol_type is wrong.
Comment 3 Nick Clifton 2017-11-17 12:28:02 UTC
Created attachment 10608 [details]
Proposed patch

Hi Guys,

In which case, please can someone try out this patch and let me know if it fixes the problem ?

Cheers
  Nick
Comment 4 Nick Clifton 2017-11-17 12:41:22 UTC
Created attachment 10609 [details]
Proposed patch

*sigh* I forgot about the 'hidden' return parameter.  Please try this version of the patch instead.
Comment 5 Mingi Cho 2017-11-17 16:32:26 UTC
Created attachment 10615 [details]
minimized testcase
Comment 6 Mingi Cho 2017-11-17 16:48:52 UTC
Created attachment 10616 [details]
Proposed patch

Hi Nick,

I tested with the patch which you suggested. But in my case the problem still occurs.
 I think the problem is caused by a bad symbol index.
Comment 7 Nick Clifton 2017-11-17 17:12:43 UTC
Created attachment 10617 [details]
Proposed patch

Hi Mingi,

> I tested with the patch which you suggested. But in my case the problem still 
> occurs. I think the problem is caused by a bad symbol index.

Ah, right - we need to check the symbol type as well as the file type to see if it is a non-ELF symbol.  Please try this latest version of the patch and let me know if it works this time.

Cheers
  Nick
Comment 8 Nick Clifton 2017-11-17 17:15:15 UTC
Created attachment 10618 [details]
Proposed patch

*sigh* - I meant this patch, not the last one...
Comment 9 Mingi Cho 2017-11-17 18:58:48 UTC
Created attachment 10619 [details]
Proposed patch

Hi Nick,

I have tested with your patch and added checking for null pointers because the symbol->the_bfd can be a null pointer. And the ASAN report is disappeared now.
Comment 10 cvs-commit@gcc.gnu.org 2017-11-18 21:17:26 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 160b1a618ad94988410dc81fce9189fcda5b7ff4
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Nov 18 23:18:22 2017 +1030

    PR22443, Global buffer overflow in _bfd_elf_get_symbol_version_string
    
    Symbols like *ABS* defined in bfd/section.c:global_syms are not
    elf_symbol_type.  They can appear on relocs and perhaps other places
    in an ELF bfd, so a number of places in nm.c and objdump.c are wrong
    to cast an asymbol based on the bfd being ELF.  I think we lose
    nothing by excluding all section symbols, not just the global_syms.
    
    	PR 22443
    	* nm.c (sort_symbols_by_size): Don't attempt to access
    	section symbol internal_elf_sym.
    	(print_symbol): Likewise.  Don't call bfd_get_symbol_version_string
    	for section symbols.
    	* objdump.c (compare_symbols): Don't attempt to access
    	section symbol internal_elf_sym.
    	(objdump_print_symname): Don't call bfd_get_symbol_version_string
    	for section symbols.
Comment 11 Alan Modra 2017-11-23 20:10:36 UTC
Fixed