Bug 22894

Summary: integer overflow in parse_die
Product: binutils Reporter: skysider <luanjunchao>
Component: binutilsAssignee: Nick Clifton <nickc>
Status: RESOLVED FIXED    
Severity: normal CC: jeremip11, nickc
Priority: P2    
Version: 2.31   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed: 2018-02-27 00:00:00
Attachments: Proposed patch

Description skysider 2018-02-26 03:38:43 UTC
The command I test is "nm-new -A -a -l -S -s --special-syms --synthetic --with-symbol-versions -D $POC".

In function parse_die, I find a case which can lead to interger overflow of xptr. Below is part of function parse_die.

case FORM_BLOCK4:
	  if (xptr + 4 <= aDiePtrEnd)
	    xptr += bfd_get_32 (abfd, xptr);
	  xptr += 4;
	  break;

The result of bfd_get_32 can be large and when it's added to xptr, xptr overflow.
Backtrace of gdb 
(gdb) bt                                                                                                                                                                                                                    
#0  0x08056486 in bfd_getl16 (p=0x206da1) at /work/binutils-gdb/bfd/libbfd.c:583                                                                                                                     
#1  0x080a0c55 in parse_die (aDieInfo=aDieInfo@entry=0xffffd45c, aDiePtr=<optimized out>, aDiePtrEnd=0x8188026 "\r", abfd=<optimized out>) at /work/binutils-gdb/bfd/dwarf1.c:221                                                         
#2  0x080a123c in _bfd_dwarf1_find_nearest_line (abfd=0x817e058, symbols=0x8184de0, section=0x817faa0, offset=160, filename_ptr=0xffffd568, functionname_ptr=0xffffd56c, linenumber_ptr=0xffffd570) at /work/binutils-gdb/bfd/dwarf1.c:541            
#3  0x0807fda9 in _bfd_elf_find_nearest_line (abfd=0x817e058, symbols=0x8184de0, section=0x817faa0, offset=160, filename_ptr=0xffffd568, functionname_ptr=0xffffd56c, line_ptr=0xffffd570, discriminator_ptr=0x0) at /work/binutils-gdb/bfd/elf.c:8746
#4  0x0804b279 in print_symbol (abfd=abfd@entry=0x817e058, sym=<optimized out>, ssize=0, archive_bfd=0x0) at /work/binutils-gdb/binutils/nm.c:1009                                                                                 
#5  0x0804b55c in print_symbols (archive_bfd=<optimized out>, size=<optimized out>, symcount=<optimized out>, minisyms=<optimized out>, is_dynamic=<optimized out>, abfd=0x817e058) at /work/binutils-gdb/binutils/nm.c:1089
#6  display_rel_file (abfd=abfd@entry=0x817e058, archive_bfd=archive_bfd@entry=0x0) at /work/binutils-gdb/binutils/nm.c:1205                                                                         
#7  0x0804c67b in display_file (filename=<optimized out>) at /work/binutils-gdb/binutils/nm.c:1325                                                                                                                                                                  
#8  0x0804a505 in main (argc=11, argv=0xffffd744) at /work/binutils-gdb/binutils/nm.c:1799 
  
The poc file is https://github.com/skysider/FuzzVuln/blob/master/binutils_nm_integer_overflow_parse_die.elf
Comment 1 Nick Clifton 2018-02-27 14:23:03 UTC
Created attachment 10856 [details]
Proposed patch

Hi Skysider,

  Unfortunately I could not reproduce the failure that you reported,
  but I do agree that integer overflow could occur at that point in
  the code.  So please could you try out this patch and let me know
  if it solves the problem for you.

Cheers
  Nick
Comment 2 skysider 2018-02-27 14:44:59 UTC
 I test it in 32bit machine. I wonder if you compile in 32bit mode and it seems that it only crashes in 32 bit .
Comment 3 skysider 2018-02-28 03:04:00 UTC
The patch works.
Comment 4 Sourceware Commits 2018-02-28 10:15:21 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

commit eef104664efb52965d85a28bc3fc7c77e52e48e2
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Feb 28 10:13:54 2018 +0000

    Fix potential integer overflow when reading corrupt dwarf1 debug information.
    
    	PR 22894
    	* dwarf1.c (parse_die): Check the length of form blocks before
    	advancing the data pointer.
Comment 5 Nick Clifton 2018-02-28 10:16:00 UTC
Patch applied.