aboutsummaryrefslogtreecommitdiff
path: root/binutils/dwarf.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-02-03 20:42:36 +0000
committerNick Clifton <nickc@redhat.com>2015-02-03 20:42:36 +0000
commit570286220e28e606e199b37a06cd199cadb592ba (patch)
tree4bab2058d947ccc70a61bde391202554159aee79 /binutils/dwarf.c
parenta7606d8083c9e217294f6e47a8d2903716c6337c (diff)
downloadgdb-570286220e28e606e199b37a06cd199cadb592ba.zip
gdb-570286220e28e606e199b37a06cd199cadb592ba.tar.gz
gdb-570286220e28e606e199b37a06cd199cadb592ba.tar.bz2
Fix memory access violations triggered by running readelf on fuzzed binaries.
PR binutils/17531 * dwarf.c (process_debug_info): Add range check. (display_debug_pubnames_worker): Likewise. (display_gdb_index): Fix range check. (process_cu_tu_index): Add range check. * readelf.c (get_data): Change parameter types from size_t to bfd_size_type. Add checks for loss of accuracy when casting from bfd_size_type to size_t. (get_dynamic_data): Likewise. (process_section_groups): Limit number of error messages.
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r--binutils/dwarf.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index d82c89c..bee8b64 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -2444,11 +2444,19 @@ process_debug_info (struct dwarf_section *section,
" extends beyond end of section (length = %s)\n"),
dwarf_vmatoa ("x", cu_offset),
dwarf_vmatoa ("x", compunit.cu_length));
+ num_units = unit;
break;
}
tags = hdrptr;
start += compunit.cu_length + initial_length_size;
+ if (start > end)
+ {
+ warn (_("Debug info is corrupt. CU at %s extends beyond end of section"),
+ dwarf_vmatoa ("x", cu_offset));
+ start = end;
+ }
+
if (compunit.cu_version != 2
&& compunit.cu_version != 3
&& compunit.cu_version != 4)
@@ -3720,7 +3728,9 @@ display_debug_pubnames_worker (struct dwarf_section *section,
SAFE_BYTE_GET_AND_INC (names.pn_size, data, offset_size, end);
/* PR 17531: file: 7615b6b2. */
- if ((dwarf_signed_vma) names.pn_length < 0)
+ if ((dwarf_signed_vma) names.pn_length < 0
+ /* PR 17531: file: a5dbeaa7. */
+ || start + names.pn_length + initial_length_size < start)
{
warn (_("Negative length for public name: 0x%lx\n"), (long) names.pn_length);
start = end;
@@ -6691,19 +6701,19 @@ display_gdb_index (struct dwarf_section *section,
constant_pool + name_offset);
if (constant_pool + cu_vector_offset < constant_pool
- || constant_pool + cu_vector_offset >= section->start + section->size)
+ || constant_pool + cu_vector_offset >= section->start + section->size - 3)
{
printf (_("<invalid CU vector offset: %x>\n"), cu_vector_offset);
warn (_("Corrupt CU vector offset of 0x%x found for symbol table slot %d\n"),
cu_vector_offset, i);
continue;
}
- else
- num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4);
+
+ num_cus = byte_get_little_endian (constant_pool + cu_vector_offset, 4);
if (num_cus * 4 < num_cus
- || constant_pool + cu_vector_offset + 4 + num_cus * 4 >=
- section->start + section->size)
+ || constant_pool + cu_vector_offset + 4 + num_cus * 4
+ >= section->start + section->size)
{
printf ("<invalid number of CUs: %d>\n", num_cus);
warn (_("Invalid number of CUs (0x%x) for symbol table slot %d\n"),
@@ -6864,6 +6874,14 @@ process_cu_tu_index (struct dwarf_section *section, int do_display)
pindex = phash + nslots * 8;
ppool = pindex + nslots * 4;
+ /* PR 17531: file: 45d69832. */
+ if (pindex < phash || ppool < phdr)
+ {
+ warn (_("Section %s is too small for %d slots\n"),
+ section->name, nslots);
+ return 0;
+ }
+
if (do_display)
{
printf (_("Contents of the %s section:\n\n"), section->name);