Bug 22905 - integer overflow in display_debug_ranges
Summary: integer overflow in display_debug_ranges
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.31
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-03-01 03:08 UTC by skysider
Modified: 2018-03-31 12:33 UTC (History)
2 users (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description skysider 2018-03-01 03:08:52 UTC
The command I test is "objdump -x -D -S -s -g -e -G --dwarf -t -T -r -R --special-syms --inlines --dwarf-check $POC". The binutils tools are compile in 32 bit mode.

Part of gdb debugging output:
Program received signal SIGSEGV, Segmentation fault.                                                                                                       
byte_get_little_endian (field=0x725e9e0 <error: Cannot access memory at address 0x725e9e0>, size=8) at /work/binutils-gdb/binutils/elfcomm.c:209
209             return  ((elf_vma) (field[0]))                                                                                
(gdb) bt                                                                                                                       
#0  byte_get_little_endian (field=0x725e9e0 <error: Cannot access memory at address 0x725e9e0>, size=8) at /work/binutils-gdb/binutils/elfcomm.c:209         
#1  0x08054311 in display_debug_ranges_list (start=0x725e9e0 <error: Cannot access memory at address 0x725e9e0>, finish=0x825ebf0 "", pointer_size=8, offset=4278190080, base_address=0) at /work/binutils-gdb/binutils/dwarf.c:6541
#2  0x0805fa10 in display_debug_ranges (section=0x824b960 <debug_displays+1024>, file=0x8257058) at /work/binutils-gdb/binutils/dwarf.c:6831
#3  0x08052ce9 in dump_dwarf_section (abfd=0x8257058, section=0x825c820, arg=0x0) at /work/binutils-gdb/binutils/objdump.c:2671

It's clear that there is something wrong with display_debug_ranges. Here is snippt of function display_debug_ranges.

6801: offset = range_entry->ranges_offset;
6802: next = section_begin + offset;
....
6828: start = next;
6829: last_start = next;
6830: 
6831: (is_rnglists ? display_debug_rnglists_list : display_debug_ranges_list)
6832:	(start, finish, pointer_size, offset, base_address);

(gdb) p/x *range_entry                                             
$7 = {ranges_offset = 0xff000000, debug_info_p = 0x825e4b8}   
(gdb) p/x section_begin                                            
$4 = 0x825e9e0 

We can see that range_entry->ranges_offset is 0xff000000, and section_begin is 0x825e9e0, thus when executes line 6802 in dwarf.c, integer overflow occurs.

The poc file is https://github.com/skysider/FuzzVuln/blob/master/binutils_objdump_integer_overflow_display_debug_ranges.elf
Comment 1 Sourceware Commits 2018-03-01 16:15:42 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

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

commit d11ae95ea3403559f052903ab053f43ad7821e37
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Mar 1 16:14:08 2018 +0000

    Prevent illegal memory accesses triggerd by intger overflow when parsing corrupt DWARF information on a 32-bit host.
    
    	PR 22905
    	* dwarf.c (display_debug_ranges): Check that the offset loaded
    	from the range_entry structure is valid.
Comment 2 Nick Clifton 2018-03-01 16:23:00 UTC
Hi Skysider,

  Thanks for reporting this bug.  I have checked in a small patch to add
  a check for an integer overflow at the point you indicated.

Cheers
  Nick