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)
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
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.