diff options
author | Nick Clifton <nickc@redhat.com> | 2014-11-21 21:44:04 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2014-11-21 21:44:04 +0000 |
commit | 0a9d414aa114b7b7e609cbcbc285f79031bbe608 (patch) | |
tree | bca8497bf5147c53a4fd786ecf96c44a83906418 /bfd/pei-x86_64.c | |
parent | 5974eba65b82912621ac68f2c0ff844efbd02b25 (diff) | |
download | binutils-gdb-0a9d414aa114b7b7e609cbcbc285f79031bbe608.tar.gz |
Fixes for memory access violations exposed by fuzzinf various binaries.
PR binutils/17512
* dwarf.c (get_encoded_value): Check for an encoded size of 0.
(display_debug_lines_raw): Check for an invalid line range value.
(display_debug_frames): Check for corrupt augmentation data.
* coffgen.c (coff_get_normalized_symtab): Check for an excessive
number of auxillary entries.
* ieee.c (next_byte): Convert to a function. Return FALSE if the
next byte is beyond the end of the buffer.
(parse_int): Test the return value of next_byte.
(parse_expression): Convert to boolean. Return FALSE if the
parsing failed. Test the return value of next_byte.
(ieee_seek): Convert to a function. Return FALSE if the seek goes
beyond the end of the buffer.
(ieee_slurp_external_symbols): Test the return value of ieee_seek
and next_byte.
(ieee_slurp_sections): Convert to boolean. Return FALSE if the
operation failed. Test the return value of ieee_seek and
next_byte.
(ieee_archive_p): Test the return value of ieee_seek and
next_byte.
(do_one): Likewise.
(ieee_slurp_section_data): Likewise.
(ieee_object_p): Likewise. Store the size of the buffer in the
total_amt field in the header.
* libieee.h (common_header_type): Add amt field.
* mach-o.c (bfd_mach_o_canonicalize_one_reloc): Check that the
reloc's value is within range.
(bfd_mach_o_read_symtab_symbols): Nullify the symbols field if the
operation fails.
* pei-x86_64.c (pex64_xdata_print_uwd_codes): Replace abort with
an error message.
(pex64_dump_xdata): Check for buffer overflows.
* versados.c (process_otr): Check that the section exists before
taking its size.
(versados_object_p): Make sure that enough data was read for the
header to be checked.
* vms-alpha.c (vms_get_remaining_object_record): Change
read_so_far parameter to an unsigned int. Check that the amount
read is in range.
Diffstat (limited to 'bfd/pei-x86_64.c')
-rw-r--r-- | bfd/pei-x86_64.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/bfd/pei-x86_64.c b/bfd/pei-x86_64.c index 11ee73a2de5..ccb5774f3af 100644 --- a/bfd/pei-x86_64.c +++ b/bfd/pei-x86_64.c @@ -276,8 +276,9 @@ pex64_xdata_print_uwd_codes (FILE *file, bfd *abfd, fprintf (file, ", unknown(%u))", info); break; default: - /* Already caught by the previous scan. */ - abort (); + /* PR 17512: file: 2245-7442-0.004. */ + fprintf (file, _("Unknown: %x"), PEX64_UNWCODE_CODE (dta[1])); + break; } if (unexpected) fprintf (file, " [Unexpected!]"); @@ -317,20 +318,34 @@ pex64_dump_xdata (FILE *file, bfd *abfd, bfd_vma vaddr; bfd_vma end_addr; bfd_vma addr = rf->rva_UnwindData; + bfd_size_type sec_size = xdata_section->rawsize > 0 ? xdata_section->rawsize : xdata_section->size; struct pex64_unwind_info ui; vaddr = xdata_section->vma - pe_data (abfd)->pe_opthdr.ImageBase; addr -= vaddr; + /* PR 17512: file: 2245-7442-0.004. */ + if (addr >= sec_size) + { + fprintf (file, _("warning: xdata section corrupt\n")); + return; + } + if (endx) - end_addr = endx[0] - vaddr; + { + end_addr = endx[0] - vaddr; + /* PR 17512: file: 2245-7442-0.004. */ + if (end_addr > sec_size) + { + fprintf (file, _("warning: xdata section corrupt")); + end_addr = sec_size; + } + } else - end_addr = (xdata_section->rawsize != 0 ? - xdata_section->rawsize : xdata_section->size); - + end_addr = sec_size; pex64_get_unwind_info (abfd, &ui, &xdata[addr]); - + if (ui.Version != 1 && ui.Version != 2) { unsigned int i; @@ -380,7 +395,11 @@ pex64_dump_xdata (FILE *file, bfd *abfd, ui.FrameRegister == 0 ? "none" : pex_regs[(unsigned int) ui.FrameRegister]); - pex64_xdata_print_uwd_codes (file, abfd, &ui, rf); + /* PR 17512: file: 2245-7442-0.004. */ + if (ui.CountOfCodes * 2 + ui.rawUnwindCodes + addr >= xdata + xdata_section->size) + fprintf (file, _("Too many unwind codes (%ld)\n"), (long) ui.CountOfCodes); + else + pex64_xdata_print_uwd_codes (file, abfd, &ui, rf); switch (ui.Flags) { @@ -573,6 +592,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile) if (i + PDATA_ROW_SIZE > stop) break; + pex64_get_runtime_function (abfd, &rf, &pdata[i]); if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0 @@ -642,6 +662,7 @@ pex64_bfd_print_pdata (bfd *abfd, void *vfile) identical pointers in the array; advance past all of them. */ while (p[0] <= rf.rva_UnwindData) ++p; + if (p[0] == ~((bfd_vma) 0)) p = NULL; |