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/mach-o.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/mach-o.c')
-rw-r--r-- | bfd/mach-o.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 44b12b5..e136c2d 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -690,6 +690,20 @@ bfd_mach_o_bfd_copy_private_header_data (bfd *ibfd, bfd *obfd) ody->export_size = idy->export_size; ody->export_content = idy->export_content; } + /* PR 17512L: file: 730e492d. */ + else + { + ody->rebase_size = + ody->bind_size = + ody->weak_bind_size = + ody->lazy_bind_size = + ody->export_size = 0; + ody->rebase_content = + ody->bind_content = + ody->weak_bind_content = + ody->lazy_bind_content = + ody->export_content = NULL; + } } break; @@ -2764,7 +2778,14 @@ bfd_mach_o_build_exec_seg_command (bfd *abfd, bfd_mach_o_segment_command *seg) bfd_mach_o_append_section_to_segment (seg, s); - BFD_ASSERT (s->addr >= vma); + if (s->addr < vma) + { + (*_bfd_error_handler) + (_("section address (%lx) below start of segment (%lx)"), + (unsigned long) s->addr, (unsigned long) vma); + return FALSE; + } + vma = s->addr + s->size; } @@ -2839,7 +2860,7 @@ bfd_mach_o_build_exec_seg_command (bfd *abfd, bfd_mach_o_segment_command *seg) /* Layout the commands: set commands size and offset, set ncmds and sizeofcmds fields in header. */ -static void +static bfd_boolean bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata) { unsigned wide = mach_o_wide_p (&mdata->header); @@ -2847,6 +2868,7 @@ bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata) ufile_ptr offset; bfd_mach_o_load_command *cmd; unsigned int align; + bfd_boolean ret = TRUE; hdrlen = wide ? BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE; align = wide ? 8 - 1 : 4 - 1; @@ -2902,6 +2924,7 @@ bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata) (*_bfd_error_handler) (_("unable to layout unknown load command 0x%lx"), (unsigned long) cmd->type); + ret = FALSE; break; } @@ -2910,6 +2933,8 @@ bfd_mach_o_layout_commands (bfd_mach_o_data_struct *mdata) } mdata->header.sizeofcmds = offset - hdrlen; mdata->filelen = offset; + + return ret; } /* Subroutine of bfd_mach_o_build_commands: set type, name and nsects of a @@ -3044,8 +3069,7 @@ bfd_mach_o_build_commands (bfd *abfd) if (nbr_commands == 0) { /* Layout commands (well none...) and set headers command fields. */ - bfd_mach_o_layout_commands (mdata); - return TRUE; + return bfd_mach_o_layout_commands (mdata); } /* Create commands for segments (and symtabs), prepend them. */ @@ -3128,7 +3152,8 @@ bfd_mach_o_build_commands (bfd *abfd) } /* Layout commands. */ - bfd_mach_o_layout_commands (mdata); + if (! bfd_mach_o_layout_commands (mdata)) + return FALSE; /* So, now we have sized the commands and the filelen set to that. Now we can build the segment command and set the section file offsets. */ @@ -4687,21 +4712,10 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command) return FALSE; break; default: - { - static bfd_boolean unknown_set = FALSE; - static unsigned long unknown_command = 0; - - /* Prevent reams of error messages when parsing corrupt binaries. */ - if (!unknown_set) - unknown_set = TRUE; - else if (command->type == unknown_command) - break; - unknown_command = command->type; - - (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"), - abfd, (unsigned long) command->type); - break; - } + command->len = 0; + (*_bfd_error_handler)(_("%B: unknown load command 0x%lx"), + abfd, (unsigned long) command->type); + return FALSE; } return TRUE; |