Bug 15201 - readelf invalid memory accesses (debug ranges)
Summary: readelf invalid memory accesses (debug ranges)
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:22 UTC by Paul Marinescu
Modified: 2013-03-22 16:19 UTC (History)
1 user (show)

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


Attachments
valgrind readelf -wR bugtest.o (433 bytes, application/x-object)
2013-02-26 17:22 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:22:52 UTC
Created attachment 6899 [details]
valgrind readelf -wR bugtest.o

Valgrind shows various invalid memory accesses made from the display_debug_ranges function. I used version 2.23.52.20130219 for the trace.

As far as I can tell, the problems stems from the fact that display_debug_ranges loops until it finds two null bytes, without ever checking the section size.

I attached the file used to get the output below.


==24717== Memcheck, a memory error detector
==24717== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==24717== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==24717== Command: /home/pm/binutils/binutils/readelf -wR tmpdir/copy.o.test
==24717== 
Contents of the .debug_ranges section:

    Offset   Begin    End
==24717== Invalid read of size 1
==24717==    at 0x42EC10: byte_get_little_endian (elfcomm.c:143)
==24717==    by 0x42EC48: byte_get_signed (elfcomm.c:224)
==24717==    by 0x429FA9: display_debug_ranges (dwarf.c:4616)
==24717==    by 0x41D423: process_section_contents (readelf.c:10985)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717==  Address 0x4c28872 is 1 bytes after a block of size 33 alloc'd
==24717==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==24717==    by 0x402C2C: get_data (readelf.c:325)
==24717==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==24717==    by 0x41D217: process_section_contents (readelf.c:10978)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717== 
==24717== Invalid read of size 1
==24717==    at 0x42EC14: byte_get_little_endian (elfcomm.c:144)
==24717==    by 0x42EC48: byte_get_signed (elfcomm.c:224)
==24717==    by 0x429FA9: display_debug_ranges (dwarf.c:4616)
==24717==    by 0x41D423: process_section_contents (readelf.c:10985)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717==  Address 0x4c28873 is 2 bytes after a block of size 33 alloc'd
==24717==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==24717==    by 0x402C2C: get_data (readelf.c:325)
==24717==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==24717==    by 0x41D217: process_section_contents (readelf.c:10978)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717== 
==24717== Invalid read of size 1
==24717==    at 0x42EC24: byte_get_little_endian (elfcomm.c:142)
==24717==    by 0x42EC48: byte_get_signed (elfcomm.c:224)
==24717==    by 0x429FA9: display_debug_ranges (dwarf.c:4616)
==24717==    by 0x41D423: process_section_contents (readelf.c:10985)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717==  Address 0x4c28871 is 0 bytes after a block of size 33 alloc'd
==24717==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==24717==    by 0x402C2C: get_data (readelf.c:325)
==24717==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==24717==    by 0x41D217: process_section_contents (readelf.c:10978)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717== 
==24717== Invalid read of size 1
==24717==    at 0x42EC2A: byte_get_little_endian (elfcomm.c:145)
==24717==    by 0x42EC48: byte_get_signed (elfcomm.c:224)
==24717==    by 0x429FA9: display_debug_ranges (dwarf.c:4616)
==24717==    by 0x41D423: process_section_contents (readelf.c:10985)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717==  Address 0x4c28874 is 3 bytes after a block of size 33 alloc'd
==24717==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==24717==    by 0x402C2C: get_data (readelf.c:325)
==24717==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==24717==    by 0x41D217: process_section_contents (readelf.c:10978)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717== 
    0000001d <End of list>
==24717== Invalid read of size 1
==24717==    at 0x42EC10: byte_get_little_endian (elfcomm.c:143)
==24717==    by 0x42EC48: byte_get_signed (elfcomm.c:224)
==24717==    by 0x429F99: display_debug_ranges (dwarf.c:4614)
==24717==    by 0x41D423: process_section_contents (readelf.c:10985)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717==  Address 0x4c2887e is 13 bytes after a block of size 33 alloc'd
==24717==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==24717==    by 0x402C2C: get_data (readelf.c:325)
==24717==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==24717==    by 0x41D217: process_section_contents (readelf.c:10978)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717== 
==24717== Invalid read of size 1
==24717==    at 0x42EC14: byte_get_little_endian (elfcomm.c:144)
==24717==    by 0x42EC48: byte_get_signed (elfcomm.c:224)
==24717==    by 0x429F99: display_debug_ranges (dwarf.c:4614)
==24717==    by 0x41D423: process_section_contents (readelf.c:10985)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717==  Address 0x4c2887f is 14 bytes after a block of size 33 alloc'd
==24717==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==24717==    by 0x402C2C: get_data (readelf.c:325)
==24717==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==24717==    by 0x41D217: process_section_contents (readelf.c:10978)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717== 
==24717== Invalid read of size 1
==24717==    at 0x42EC24: byte_get_little_endian (elfcomm.c:142)
==24717==    by 0x42EC48: byte_get_signed (elfcomm.c:224)
==24717==    by 0x429F99: display_debug_ranges (dwarf.c:4614)
==24717==    by 0x41D423: process_section_contents (readelf.c:10985)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717==  Address 0x4c2887d is 12 bytes after a block of size 33 alloc'd
==24717==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==24717==    by 0x402C2C: get_data (readelf.c:325)
==24717==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==24717==    by 0x41D217: process_section_contents (readelf.c:10978)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717== 
==24717== Invalid read of size 1
==24717==    at 0x42EC2A: byte_get_little_endian (elfcomm.c:145)
==24717==    by 0x42EC48: byte_get_signed (elfcomm.c:224)
==24717==    by 0x429F99: display_debug_ranges (dwarf.c:4614)
==24717==    by 0x41D423: process_section_contents (readelf.c:10985)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717==  Address 0x4c28880 is 15 bytes after a block of size 33 alloc'd
==24717==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==24717==    by 0x402C2C: get_data (readelf.c:325)
==24717==    by 0x4133E8: load_specific_debug_section (readelf.c:10869)
==24717==    by 0x41D217: process_section_contents (readelf.c:10978)
==24717==    by 0x41EB11: process_object (readelf.c:13707)
==24717==    by 0x420E9B: main (readelf.c:14078)
==24717== 
    0000002d <End of list>

==24717== 
==24717== HEAP SUMMARY:
==24717==     in use at exit: 8,192 bytes in 1 blocks
==24717==   total heap usage: 99 allocs, 98 frees, 25,218 bytes allocated
==24717== 
==24717== LEAK SUMMARY:
==24717==    definitely lost: 8,192 bytes in 1 blocks
==24717==    indirectly lost: 0 bytes in 0 blocks
==24717==      possibly lost: 0 bytes in 0 blocks
==24717==    still reachable: 0 bytes in 0 blocks
==24717==         suppressed: 0 bytes in 0 blocks
==24717== Rerun with --leak-check=full to see details of leaked memory
==24717== 
==24717== For counts of detected and suppressed errors, rerun with: -v
==24717== ERROR SUMMARY: 12 errors from 8 contexts (suppressed: 2 from 2)
Comment 1 cvs-commit@gcc.gnu.org 2013-03-22 16:18:02 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	nickc@sourceware.org	2013-03-22 16:18:00

Modified files:
	binutils       : ChangeLog 

Log message:
	PR binutils/15201
	* dwarf.c (display_debug_ranges): Add checks for reading beyond
	the end of the section.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/binutils/ChangeLog.diff?cvsroot=src&r1=1.2001&r2=1.2002
Comment 2 Nick Clifton 2013-03-22 16:19:40 UTC
 I have checked in a patch to prevent the out of bounds reads for this particular test case, although I suspect that others could be crafted which will trigger the same problem.  If these are discovered then this PR can be reopened.