aboutsummaryrefslogtreecommitdiff
path: root/bfd/mach-o.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/mach-o.c
parentffbc46469f5fa1368251acd65da418775ab1a2ce (diff)
downloadbinutils-86eafac0aad7edbc1ccea6daf53480a36339250a.zip
binutils-86eafac0aad7edbc1ccea6daf53480a36339250a.tar.gz
binutils-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.c54
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;