aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2014-11-12 22:39:58 +0000
committerNick Clifton <nickc@redhat.com>2014-11-12 22:39:58 +0000
commitf41e4712a7b7ac60f181e7dfc984ca35c222f0d7 (patch)
tree6ac324979fd61983fb6a27dccf9fe306725789fa /bfd
parent40e91bc71f7993f2064cec4ffd007f2c814a1b29 (diff)
downloadgdb-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/ChangeLog13
-rw-r--r--bfd/coffcode.h14
-rw-r--r--bfd/coffgen.c15
-rw-r--r--bfd/peXXigen.c25
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