diff options
author | Nick Clifton <nickc@redhat.com> | 2014-11-12 22:39:58 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2014-11-12 22:39:58 +0000 |
commit | f41e4712a7b7ac60f181e7dfc984ca35c222f0d7 (patch) | |
tree | 6ac324979fd61983fb6a27dccf9fe306725789fa /bfd | |
parent | 40e91bc71f7993f2064cec4ffd007f2c814a1b29 (diff) | |
download | gdb-f41e4712a7b7ac60f181e7dfc984ca35c222f0d7.zip gdb-f41e4712a7b7ac60f181e7dfc984ca35c222f0d7.tar.gz gdb-f41e4712a7b7ac60f181e7dfc984ca35c222f0d7.tar.bz2 |
Fix more memory faults uncovered by fuzzing various executables.
PR binutils/17512
* dwarf.c (read_and_display_attr_value): Check that we do not read
past end.
(display_debug_pubnames_worker): Add range checks.
(process_debug_info): Check for invalid pointer sizes.
(display_loc_list): Likewise.
(display_loc_list_dwo): Likewise.
(display_debug_ranges): Likewise.
(display_debug_aranges): Check for invalid address size.
(read_cie): Add range checks. Replace call strchr with while loop.
* objdump.c (dump_dwarf): Replace abort with a warning message.
(print_section_stabs): Improve range checks.
* rdcoff.c (coff_get_slot): Use long for indx parameter type.
Add check for an excesively large index.
* rddbg.c (read_section_stabs_debugging_info): Zero terminate the
string table. Avoid walking off the end of the stabs data.
* stabs.c (parse_stab_string): Add check for a NULL name.
PR binutils/17512
* coffcode.h (coff_slurp_line_table): Set the line number of
corrupt entries to -1.
(coff_slurp_symbol_table): Alway initialise the value of the
symbol.
* coffgen.c (coff_print_symbol): Check that the combined pointer
is valid.
(coff_print_symbol): Do not print negative line numbers.
* peXXigen.c (pe_print_idata): Add range checking displaying
member names.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 13 | ||||
-rw-r--r-- | bfd/coffcode.h | 14 | ||||
-rw-r--r-- | bfd/coffgen.c | 15 | ||||
-rw-r--r-- | bfd/peXXigen.c | 25 |
4 files changed, 53 insertions, 14 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a04b924..08dda5a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2014-11-12 Nick Clifton <nickc@redhat.com> + + PR binutils/17512 + * coffcode.h (coff_slurp_line_table): Set the line number of + corrupt entries to -1. + (coff_slurp_symbol_table): Alway initialise the value of the + symbol. + * coffgen.c (coff_print_symbol): Check that the combined pointer + is valid. + (coff_print_symbol): Do not print negative line numbers. + * peXXigen.c (pe_print_idata): Add range checking displaying + member names. + 2014-11-12 Alan Modra <amodra@gmail.com> PR binutils/17512 diff --git a/bfd/coffcode.h b/bfd/coffcode.h index acc7360..1eb2412 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -4510,7 +4510,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) unsigned int counter; alent *cache_ptr; bfd_vma prev_offset = 0; - int ordered = 1; + bfd_boolean ordered = TRUE; unsigned int nbr_func; LINENO *src; bfd_boolean have_func; @@ -4561,6 +4561,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) (*_bfd_error_handler) (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"), abfd, (long) symndx, counter); + cache_ptr->line_number = -1; continue; } @@ -4572,11 +4573,12 @@ coff_slurp_line_table (bfd *abfd, asection *asect) /* PR 17512 file: 078-10659-0.004 */ if (sym < obj_symbols (abfd) - || sym >= obj_symbols (abfd) + obj_raw_syment_count (abfd)) + || sym >= obj_symbols (abfd) + bfd_get_symcount (abfd)) { (*_bfd_error_handler) (_("%B: warning: illegal symbol in line number entry %d"), abfd, counter); + cache_ptr->line_number = -1; continue; } @@ -4590,7 +4592,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect) sym->lineno = cache_ptr; if (sym->symbol.value < prev_offset) - ordered = 0; + ordered = FALSE; prev_offset = sym->symbol.value; } else if (!have_func) @@ -4625,6 +4627,8 @@ coff_slurp_line_table (bfd *abfd, asection *asect) if (lineno_cache[i].line_number == 0) *p++ = &lineno_cache[i]; + BFD_ASSERT ((p - func_table) == nbr_func); + /* Sort by functions. */ qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent); @@ -4650,6 +4654,8 @@ coff_slurp_line_table (bfd *abfd, asection *asect) *n_cache_ptr++ = *old_ptr++; while (old_ptr->line_number != 0); } + BFD_ASSERT ((bfd_size_type) (n_cache_ptr - n_lineno_cache) == (amt / sizeof (alent))); + memcpy (lineno_cache, n_lineno_cache, amt); } bfd_release (abfd, func_table); @@ -4710,6 +4716,8 @@ coff_slurp_symbol_table (bfd * abfd) dst->symbol.section = coff_section_from_bfd_index (abfd, src->u.syment.n_scnum); dst->symbol.flags = 0; + /* PR 17512: file: 079-7098-0.001:0.1. */ + dst->symbol.value = 0; dst->done_lineno = FALSE; switch (src->u.syment.n_sclass) diff --git a/bfd/coffgen.c b/bfd/coffgen.c index aab88e3..9dcb3bd 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -2099,6 +2099,14 @@ coff_print_symbol (bfd *abfd, fprintf (file, "[%3ld]", (long) (combined - root)); + /* PR 17512: file: 079-33786-0.001:0.1. */ + if (combined < obj_raw_syments (abfd) + || combined >= obj_raw_syments (abfd) + obj_raw_syment_count (abfd)) + { + fprintf (file, _("<corrupt info> %s"), symbol->name); + break; + } + if (! combined->fix_value) val = (bfd_vma) combined->u.syment.n_value; else @@ -2192,8 +2200,11 @@ coff_print_symbol (bfd *abfd, l++; while (l->line_number) { - fprintf (file, "\n%4d : ", l->line_number); - bfd_fprintf_vma (abfd, file, l->u.offset + symbol->section->vma); + if (l->line_number > 0) + { + fprintf (file, "\n%4d : ", l->line_number); + bfd_fprintf_vma (abfd, file, l->u.offset + symbol->section->vma); + } l++; } } diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index 725e9f6..13e39e4 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -1481,27 +1481,31 @@ pe_print_idata (bfd * abfd, void * vfile) #ifdef COFF_WITH_pex64 for (j = 0; idx + j + 8 <= datasize; j += 8) { + bfd_size_type amt; unsigned long member = bfd_get_32 (abfd, data + idx + j); unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4); if (!member && !member_high) break; + amt = member - adj; + if (HighBitSet (member_high)) fprintf (file, "\t%lx%08lx\t %4lx%08lx <none>", member_high, member, WithoutHighBit (member_high), member); /* PR binutils/17512: Handle corrupt PE data. */ - else if ((bfd_vma) member - adj + 2 >= datasize) + else if (amt + 2 >= datasize) fprintf (file, _("\t<corrupt: 0x%04lx>"), member); else { int ordinal; char *member_name; - ordinal = bfd_get_16 (abfd, data + member - adj); - member_name = (char *) data + member - adj + 2; - fprintf (file, "\t%04lx\t %4d %s",member, ordinal, member_name); + ordinal = bfd_get_16 (abfd, data + amt); + member_name = (char *) data + amt + 2; + fprintf (file, "\t%04lx\t %4d %.*s",member, ordinal, + (int) (datasize - (amt + 2)), member_name); } /* If the time stamp is not zero, the import address @@ -1517,27 +1521,30 @@ pe_print_idata (bfd * abfd, void * vfile) #else for (j = 0; idx + j + 4 <= datasize; j += 4) { + bfd_size_type amt; unsigned long member = bfd_get_32 (abfd, data + idx + j); /* Print single IMAGE_IMPORT_BY_NAME vector. */ if (member == 0) break; + amt = member - adj; if (HighBitSet (member)) fprintf (file, "\t%04lx\t %4lu <none>", member, WithoutHighBit (member)); /* PR binutils/17512: Handle corrupt PE data. */ - else if ((bfd_vma) member - adj + 2 >= datasize) + else if (amt + 2 >= datasize) fprintf (file, _("\t<corrupt: 0x%04lx>"), member); else { int ordinal; char *member_name; - ordinal = bfd_get_16 (abfd, data + member - adj); - member_name = (char *) data + member - adj + 2; - fprintf (file, "\t%04lx\t %4d %s", - member, ordinal, member_name); + ordinal = bfd_get_16 (abfd, data + amt); + member_name = (char *) data + amt + 2; + fprintf (file, "\t%04lx\t %4d %.*s", + member, ordinal, + (int) (datasize - (amt + 2)), member_name); } /* If the time stamp is not zero, the import address |