summaryrefslogtreecommitdiff
path: root/bfd/pei-x86_64.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2014-11-21 21:44:04 +0000
committerNick Clifton <nickc@redhat.com>2014-11-21 21:44:04 +0000
commit0a9d414aa114b7b7e609cbcbc285f79031bbe608 (patch)
treebca8497bf5147c53a4fd786ecf96c44a83906418 /bfd/pei-x86_64.c
parent5974eba65b82912621ac68f2c0ff844efbd02b25 (diff)
downloadbinutils-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.c37
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;