Bug 22148 - Integer overflow in elf64-x86-64.c, binutils 2.29.1
Summary: Integer overflow in elf64-x86-64.c, binutils 2.29.1
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.29
: P2 normal
Target Milestone: 2.30
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-18 01:34 UTC by skysider
Modified: 2017-09-18 20:21 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
poc of integer overlow (4.88 KB, application/x-executable)
2017-09-18 01:34 UTC, skysider
Details

Note You need to log in before you can comment on or make changes to this bug.
Description skysider 2017-09-18 01:34:58 UTC
Created attachment 10418 [details]
poc of integer overlow

In elf64-x86-64.c:6718, function elf_x86_64_get_synthetic_symtab

static long
elf_x86_64_get_synthetic_symtab (bfd *abfd,
				 long symcount ATTRIBUTE_UNUSED,
				 asymbol **syms ATTRIBUTE_UNUSED,
				 long dynsymcount,
				 asymbol **dynsyms,
				 asymbol **ret)
{
......

dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, dynrelbuf,
						dynsyms);

/* Sort the relocs by address.  */
qsort (dynrelbuf, dynrelcount, sizeof (arelent *), compare_relocs);
......
}

When I use objdump to deal with a specific elf file, it causes segmentation fault. Here is the backtrace:

(gdb) bt                                                                                                                                                   
#0  0x0000000000456d43 in compare_relocs (ap=0x800000000084ebd8, bp=0x84ebe0) at elf64-x86-64.c:6635                                   
#1  0x00007ffff784030f in _quicksort (pbase=pbase@entry=0x84ebe0, total_elems=total_elems@entry=18446744073709551615,                   
    size=size@entry=8, cmp=cmp@entry=0x456d40 <compare_relocs>, arg=0x0) at qsort.c:122                                                                                
#2  0x00007ffff7842642 in __GI___qsort_r (b=b@entry=0x84ebe0, 
    cmp=cmp@entry=0x456d40 <compare_relocs>, arg=arg@entry=0x0) at msort.c:216                                                                                                                   
#3  0x00007ffff7842768 in __GI_qsort (b=b@entry=0x84ebe0, n=n@entry=18446744073709551615, s=s@entry=8,                 
    cmp=cmp@entry=0x456d40 <compare_relocs>) at msort.c:308                                      
#4  0x000000000045a00d in elf_x86_64_get_synthetic_symtab (abfd=0x8451c0, symcount=<optimized out>, syms=<optimized out>,       
    dynsymcount=<optimized out>, dynsyms=<optimized out>, ret=0x83e668 <synthsyms>) at elf64-x86-64.c:6722                                       
#5  0x0000000000408287 in dump_bfd (abfd=abfd@entry=0x8451c0) at ./objdump.c:3525                             
#6  0x0000000000408b48 in display_object_bfd (abfd=0x8451c0) at ./objdump.c:3603                                                                                
#7  display_any_bfd (file=file@entry=0x8451c0, level=level@entry=0) at ./objdump.c:3692                                                                  
#8  0x000000000040ae14 in display_file (filename=0x7fffffffe8ba "../out/crashes/id:000000,sig:11,src:000000,op:flip1,pos:9273",                                  
    target=<optimized out>, last_file=1) at ./objdump.c:3713                                                                           
#9  0x0000000000404d5e in main (argc=3, argv=0x7fffffffe698) at ./objdump.c:4015                                                                        
(gdb) p/x 18446744073709551615                                                                                                                         
$41 = 0xffffffffffffffff     

We can see that the n parameter is -1, which is negative, but the qsort parameter type is unsigned, so there is an integer overfow.
Comment 1 cvs-commit@gcc.gnu.org 2017-09-18 20:10:50 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

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

commit 94670f6cf11fc29cc6db6814b38c4305d9bcac96
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Sep 18 13:05:25 2017 -0700

    Check error return from bfd_canonicalize_dynamic_reloc
    
    Since bfd_canonicalize_dynamic_reloc returns -1 on error, check it in
    _bfd_x86_elf_get_synthetic_symtab.
    
    	PR ld/22148
    	* elfxx-x86.c (_bfd_x86_elf_get_synthetic_symtab): Check error
    	return from bfd_canonicalize_dynamic_reloc.
Comment 2 cvs-commit@gcc.gnu.org 2017-09-18 20:19:16 UTC
The binutils-2_29-branch branch has been updated by H.J. Lu <hjl@sourceware.org>:

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

commit e6ff33ca50c1180725dde11c84ee93fcdb4235ef
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Sep 18 13:05:25 2017 -0700

    Check error return from bfd_canonicalize_dynamic_reloc
    
    Since bfd_canonicalize_dynamic_reloc returns -1 on error, check it in
    elf_i386_get_synthetic_symtab and elf_x86_64_get_synthetic_symtab.
    
    	PR ld/22148
    	* elf32-i386.c (elf_i386_get_synthetic_symtab): Check error
    	return from bfd_canonicalize_dynamic_reloc.
    	* elf64-x86-64.c (elf_x86_64_get_synthetic_symtab): Likewise.
    
    (cherry picked from commit 94670f6cf11fc29cc6db6814b38c4305d9bcac96)
Comment 3 H.J. Lu 2017-09-18 20:21:58 UTC
Fixed for master and 2.29 branches.