Bug 15202 - display_debug_lines invalid memory access
Summary: display_debug_lines invalid memory access
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.23
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-02-26 17:55 UTC by Paul Marinescu
Modified: 2013-03-25 13:18 UTC (History)
1 user (show)

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


Attachments
valgrind readelf -wL decodedline.o (526 bytes, application/x-object)
2013-02-26 17:55 UTC, Paul Marinescu
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Marinescu 2013-02-26 17:55:12 UTC
Created attachment 6900 [details]
valgrind readelf -wL decodedline.o

readelf and objdump may access invalid memory when trying to display the debug_line section. I attached below a sample output and the file used.

The problems seems to be related to inconsistent li_opcode_base fields. I used binutils version 2.23.52.20130219 on an x64 machine.


==29732== Memcheck, a memory error detector
==29732== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==29732== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==29732== Command: /home/pdm/binutils/binutils/readelf -wL decodedline.o
==29732== 
Decoded dump of debug contents of section .debug_line:

CU: ./dw2-decodedline.c:
File name                            Line number    Starting address

directory/file1.c:
file1.c                                        1                   0


./dw2-decodedline.c:[++]
dw2-decodedline.c                              2                 0x1
==29732== Invalid read of size 1
==29732==    at 0x4237F0: read_leb128 (dwarf.c:208)
==29732==    by 0x4264D6: display_debug_lines (dwarf.c:2977)
==29732==    by 0x41D423: process_section_contents (readelf.c:10985)
==29732==    by 0x41EB11: process_object (readelf.c:13707)
==29732==    by 0x420E9B: main (readelf.c:14078)
==29732==  Address 0x4c2894e is 0 bytes after a block of size 94 alloc'd
==29732==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29732==    by 0x402C2C: get_data (readelf.c:325)
==29732==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==29732==    by 0x41D217: process_section_contents (readelf.c:10978)
==29732==    by 0x41EB11: process_object (readelf.c:13707)
==29732==    by 0x420E9B: main (readelf.c:14078)
==29732== 
==29732== Invalid read of size 1
==29732==    at 0x4237F0: read_leb128 (dwarf.c:208)
==29732==    by 0x4264F5: display_debug_lines (dwarf.c:2981)
==29732==    by 0x41D423: process_section_contents (readelf.c:10985)
==29732==    by 0x41EB11: process_object (readelf.c:13707)
==29732==    by 0x420E9B: main (readelf.c:14078)
==29732==  Address 0x4c2894f is 1 bytes after a block of size 94 alloc'd
==29732==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29732==    by 0x402C2C: get_data (readelf.c:325)
==29732==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==29732==    by 0x41D217: process_section_contents (readelf.c:10978)
==29732==    by 0x41EB11: process_object (readelf.c:13707)
==29732==    by 0x420E9B: main (readelf.c:14078)
==29732== 
==29732== Invalid read of size 1
==29732==    at 0x4237F0: read_leb128 (dwarf.c:208)
==29732==    by 0x426511: display_debug_lines (dwarf.c:2985)
==29732==    by 0x41D423: process_section_contents (readelf.c:10985)
==29732==    by 0x41EB11: process_object (readelf.c:13707)
==29732==    by 0x420E9B: main (readelf.c:14078)
==29732==  Address 0x4c28950 is 2 bytes after a block of size 94 alloc'd
==29732==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==29732==    by 0x402C2C: get_data (readelf.c:325)
==29732==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==29732==    by 0x41D217: process_section_contents (readelf.c:10978)
==29732==    by 0x41EB11: process_object (readelf.c:13707)
==29732==    by 0x420E9B: main (readelf.c:14078)
==29732== 

==29732== 
==29732== HEAP SUMMARY:
==29732==     in use at exit: 0 bytes in 0 blocks
==29732==   total heap usage: 83 allocs, 83 frees, 15,230 bytes allocated
==29732== 
==29732== All heap blocks were freed -- no leaks are possible
==29732== 
==29732== For counts of detected and suppressed errors, rerun with: -v
==29732== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 2 from 2)
Comment 1 cvs-commit@gcc.gnu.org 2013-03-25 13:16:42 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	nickc@sourceware.org	2013-03-25 13:16:41

Modified files:
	binutils       : ChangeLog dwarf.c dwarf.h readelf.c 

Log message:
	PR binutils/15202
	* dwarf.c (read_leb128): Add END parameter.  Do not read at or
	beyond end.
	(read_sleb128): Add END parameter.
	(read_uleb128): New function.
	(process_extended_line_op): Pass END to leb128 functions.
	(process_abbrev_section): Likewise.
	(decode_location_expression): Likewise.
	(read_and_display_attr_value): Likewise.
	(read_and_display_attr): Likewise.
	(process_debug_info): Likewise.
	(display_debug_lines_raw): Likewise.
	(display_debug_lines_decoded): Likewise.
	(display_debug_macinfo): Likewise.
	(get_line_filename_and_dirname): Likewise.
	(display_debug_macro): Likewise.
	(display_loc_list_dwo): Likewise.
	(display_debug_ranges): Likewise.
	* dwarf.h (read_leb128): Update prototype.
	* readelf.c (read_uleb128): Add END parameter.
	(decode_arm_unwind_bytecode): Pass END to read_uleb128.
	(decode_tic6x_unwind_bytecode): Likewise.
	(display_tag_value): New function.
	(display_arm_attribute): Add END parameter. Pass END to
	read_uleb128.  Use display_tag_value.
	(display_gnu_attribute): Likewise.
	(display_power_gnu_attribute): Likewise.
	(display_sparc_gnu_attribute): Likewise.
	(display_mips_gnu_attribute): Likewise.
	(display_tic6x_attribute): Likewise.
	(process_attributes): Likewise.
	(display_raw_attribute): New function.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/ChangeLog.diff?cvsroot=src&r1=1.2002&r2=1.2003
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/dwarf.c.diff?cvsroot=src&r1=1.125&r2=1.126
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/dwarf.h.diff?cvsroot=src&r1=1.27&r2=1.28
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/readelf.c.diff?cvsroot=src&r1=1.599&r2=1.600
Comment 2 Nick Clifton 2013-03-25 13:18:26 UTC
Hi Paul,

  I have checked in a patch to fix this problem.

  The underlying issue was that we were reading LEB128 encoded values without performing any buffer overrun checks.  The patches fixes the problem, although it turned out to be little more extensive than I had originally anticipated.

Cheers
  Nick