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.
This commit is contained in:
parent
40e91bc71f
commit
f41e4712a7
10 changed files with 244 additions and 82 deletions
|
@ -139,7 +139,7 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
|
|||
}
|
||||
|
||||
strsize = bfd_section_size (abfd, strsec);
|
||||
strings = (bfd_byte *) xmalloc (strsize);
|
||||
strings = (bfd_byte *) xmalloc (strsize + 1);
|
||||
if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize))
|
||||
{
|
||||
fprintf (stderr, "%s: %s: %s\n",
|
||||
|
@ -147,7 +147,8 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
|
|||
bfd_errmsg (bfd_get_error ()));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Zero terminate the strings table, just in case. */
|
||||
strings [strsize] = 0;
|
||||
if (shandle == NULL)
|
||||
{
|
||||
shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
|
||||
|
@ -159,7 +160,8 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
|
|||
|
||||
stroff = 0;
|
||||
next_stroff = 0;
|
||||
for (stab = stabs; stab < stabs + stabsize; stab += 12)
|
||||
/* PR 17512: file: 078-60391-0.001:0.1. */
|
||||
for (stab = stabs; stab <= (stabs + stabsize) - 12; stab += 12)
|
||||
{
|
||||
unsigned int strx;
|
||||
int type;
|
||||
|
@ -184,33 +186,43 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
|
|||
}
|
||||
else
|
||||
{
|
||||
size_t len;
|
||||
char *f, *s;
|
||||
|
||||
f = NULL;
|
||||
|
||||
if (stroff + strx > strsize)
|
||||
if (stroff + strx >= strsize)
|
||||
{
|
||||
fprintf (stderr, "%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n",
|
||||
fprintf (stderr, _("%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n"),
|
||||
bfd_get_filename (abfd), names[i].secname,
|
||||
(long) (stab - stabs) / 12, strx, type);
|
||||
continue;
|
||||
}
|
||||
|
||||
s = (char *) strings + stroff + strx;
|
||||
f = NULL;
|
||||
|
||||
while (s[strlen (s) - 1] == '\\'
|
||||
/* PR 17512: file: 002-87578-0.001:0.1.
|
||||
It is possible to craft a file where, without the 'strlen (s) > 0',
|
||||
an attempt to read the byte before 'strings' would occur. */
|
||||
while ((len = strlen (s)) > 0
|
||||
&& s[len - 1] == '\\'
|
||||
&& stab + 12 < stabs + stabsize)
|
||||
{
|
||||
char *p;
|
||||
|
||||
stab += 12;
|
||||
p = s + strlen (s) - 1;
|
||||
p = s + len - 1;
|
||||
*p = '\0';
|
||||
s = concat (s,
|
||||
((char *) strings
|
||||
+ stroff
|
||||
+ bfd_get_32 (abfd, stab)),
|
||||
(const char *) NULL);
|
||||
strx = stroff + bfd_get_32 (abfd, stab);
|
||||
if (strx >= strsize)
|
||||
{
|
||||
fprintf (stderr, _("%s: %s: stab entry %ld is corrupt\n"),
|
||||
bfd_get_filename (abfd), names[i].secname,
|
||||
(long) (stab - stabs) / 12);
|
||||
break;
|
||||
}
|
||||
else
|
||||
s = concat (s, (char *) strings + strx,
|
||||
(const char *) NULL);
|
||||
|
||||
/* We have to restore the backslash, because, if
|
||||
the linker is hashing stabs strings, we may
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue