summaryrefslogtreecommitdiff
path: root/bfd/versados.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-01-21 17:37:23 +0000
committerNick Clifton <nickc@redhat.com>2015-01-21 17:37:23 +0000
commit86eafac0aad7edbc1ccea6daf53480a36339250a (patch)
tree380943f3951e65b5a0c9968691828a424e0857c7 /bfd/versados.c
parentffbc46469f5fa1368251acd65da418775ab1a2ce (diff)
Fix memory access violations triggered by running strip on fuzzed binaries.
PR binutils/17512 * coffcode.h (coff_set_arch_mach_hook): Check return value from bfd_malloc. (coff_slurp_line_table): Return FALSE if the line number information was corrupt. (coff_slurp_symbol_table): Return FALSE if the symbol information was corrupt. * mach-o.c (bfd_mach_o_bfd_copy_private_header_data): Always initialise the fields of the dyld_info structure. (bfd_mach_o_build_exec_seg_command): Replace assertion with an error message and a return value. (bfd_mach_o_layout_commands): Change the function to boolean. Return FALSE if the function fails. (bfd_mach_o_build_commands): Fail if bfd_mach_o_layout_commands fails. (bfd_mach_o_read_command): Fail if an unrecognised command is encountered. * peXXigen.c (_bfd_XXi_swap_aouthdr_in): Set bfd_error if the read fails. (slurp_symtab): Check the return from bfd_malloc. (_bfd_XX_bfd_copy_private_bfd_data_common): Fail if the copy encountered an error. (_bfd_XXi_final_link_postscript): Fail if a section could not be copied. * peicode.h (pe_bfd_object_p): Fail if the header could not be swapped in. * tekhex.c (first_phase): Fail if the section is too big. * versados.c (struct esdid): Add content_size field. (process_otr): Use and check the new field. (versados_get_section_contents): Check that the section exists and that the requested data is available. PR binutils/17512 * addr2line.c (main): Call bfd_set_error_program_name. * ar.c (main): Likewise. * coffdump.c (main): Likewise. * cxxfilt.c (main): Likewise. * dlltool.c (main): Likewise. * nlmconv.c (main): Likewise. * nm.c (main): Likewise. * objdump.c (main): Likewise. * size.c (main): Likewise. * srconv.c (main): Likewise. * strings.c (main): Likewise. * sysdump.c (main): Likewise. * windmc.c (main): Likewise. * windres.c (main): Likewise. * objcopy.c (main): Likewise. (copy_relocations_in_section): Check for relocs without associated symbol pointers.
Diffstat (limited to 'bfd/versados.c')
-rw-r--r--bfd/versados.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/bfd/versados.c b/bfd/versados.c
index 95f5f538c8..25403141d8 100644
--- a/bfd/versados.c
+++ b/bfd/versados.c
@@ -57,6 +57,7 @@ struct esdid
{
asection *section; /* Ptr to bfd version. */
unsigned char *contents; /* Used to build image. */
+ bfd_size_type content_size; /* The size of the contents buffer. */
int pc;
int relocs; /* Reloc count, valid end of pass 1. */
int donerel; /* Have relocs been translated. */
@@ -406,7 +407,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
if (pass == 1)
need_contents = TRUE;
- else if (contents && dst_idx < esdid->section->size - sizeinwords * 2)
+ else if (contents && dst_idx < esdid->content_size - sizeinwords * 2)
for (j = 0; j < sizeinwords * 2; j++)
{
contents[dst_idx + (sizeinwords * 2) - j - 1] = val;
@@ -449,7 +450,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
{
need_contents = TRUE;
- if (esdid->section && contents && dst_idx < esdid->section->size)
+ if (esdid->section && contents && dst_idx < esdid->content_size - 1)
if (pass == 2)
{
/* Absolute code, comes in 16 bit lumps. */
@@ -472,6 +473,7 @@ process_otr (bfd *abfd, struct ext_otr *otr, int pass)
size = esdid->section->size;
esdid->contents = bfd_alloc (abfd, size);
+ esdid->content_size = size;
}
else
esdid->contents = NULL;
@@ -686,12 +688,20 @@ versados_get_section_contents (bfd *abfd,
file_ptr offset,
bfd_size_type count)
{
+ struct esdid *esdid;
+
if (!versados_pass_2 (abfd))
return FALSE;
- memcpy (location,
- EDATA (abfd, section->target_index).contents + offset,
- (size_t) count);
+ esdid = &EDATA (abfd, section->target_index);
+
+ if (esdid->contents == NULL
+ || offset < 0
+ || (bfd_size_type) offset > esdid->content_size
+ || offset + count > esdid->content_size)
+ return FALSE;
+
+ memcpy (location, esdid->contents + offset, (size_t) count);
return TRUE;
}