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 /binutils/rddbg.c | |
parent | 40e91bc71f7993f2064cec4ffd007f2c814a1b29 (diff) | |
download | binutils-f41e4712a7b7ac60f181e7dfc984ca35c222f0d7.zip binutils-f41e4712a7b7ac60f181e7dfc984ca35c222f0d7.tar.gz binutils-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 'binutils/rddbg.c')
-rw-r--r-- | binutils/rddbg.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/binutils/rddbg.c b/binutils/rddbg.c index bfa54ab..ea8161b 100644 --- a/binutils/rddbg.c +++ b/binutils/rddbg.c @@ -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 |