diff options
author | Nick Clifton <nickc@redhat.com> | 2015-01-21 17:37:23 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-01-21 17:37:23 +0000 |
commit | 86eafac0aad7edbc1ccea6daf53480a36339250a (patch) | |
tree | 380943f3951e65b5a0c9968691828a424e0857c7 /bfd/versados.c | |
parent | ffbc46469f5fa1368251acd65da418775ab1a2ce (diff) | |
download | gdb-86eafac0aad7edbc1ccea6daf53480a36339250a.zip gdb-86eafac0aad7edbc1ccea6daf53480a36339250a.tar.gz gdb-86eafac0aad7edbc1ccea6daf53480a36339250a.tar.bz2 |
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.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/bfd/versados.c b/bfd/versados.c index 95f5f53..2540314 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; } |