diff options
author | Nick Clifton <nickc@redhat.com> | 2015-02-03 20:42:36 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-02-03 20:42:36 +0000 |
commit | 570286220e28e606e199b37a06cd199cadb592ba (patch) | |
tree | 4bab2058d947ccc70a61bde391202554159aee79 /binutils/dwarf.c | |
parent | a7606d8083c9e217294f6e47a8d2903716c6337c (diff) | |
download | gdb-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.c | 30 |
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); |