aboutsummaryrefslogtreecommitdiff
path: root/bfd/mach-o.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-02-03 14:34:54 +0000
committerNick Clifton <nickc@redhat.com>2015-02-03 14:34:54 +0000
commit64d2901806c171c0d949f8fb1b29b4e5ba8cf04d (patch)
tree275309fa108305408faa350ecb1043da1ff2fd96 /bfd/mach-o.c
parent46b87d490296235ab7c76c68816de7c402a79326 (diff)
downloadgdb-64d2901806c171c0d949f8fb1b29b4e5ba8cf04d.zip
gdb-64d2901806c171c0d949f8fb1b29b4e5ba8cf04d.tar.gz
gdb-64d2901806c171c0d949f8fb1b29b4e5ba8cf04d.tar.bz2
More fixes for illegal memory accesses triggered by running objdump on fuzzed binaries.
PR binutils/17512 * objdump.c (display_any_bfd): Fail if archives nest too deeply. * ecoff.c: Use bfd_alloc2 to allocate space for structure arrays. (_bfd_ecoff_slurp_symbol_table): Check for a negative symbol index or an out of range fdr index. * elf-m10300.c (mn10300_info_to_howto): Fix typo in error message. * elf32-arc.c (arc_info_to_howto_rel): Likewise. * elf32-avr.c (avr_info_to_howto_rela): Likewise. * elf32-cr16.c (elf_cr16_info_to_howto): Likewise. * elf32-cr16c.c (elf_cr16c_info_to_howto_rel): Likewise. * elf32-cris.c (cris_info_to_howto_rela): Likewise. * elf32-crx.c (elf_crx_info_to_howto): Likewise. * elf32-d10v.c (d10v_info_to_howto_rel): Likewise. * elf32-d30v.c (d30v_info_to_howto_rel): Likewise. * elf32-epiphany.c (epiphany_info_to_howto_rela): Likewise. * elf32-fr30.c (fr30_info_to_howto_rela): Likewise. * elf32-frv.c (frv_info_to_howto_rela): Likewise. * elf32-i370.c (i370_elf_info_to_howto): Likewise. * elf32-i960.c (elf32_i960_info_to_howto_rel): Likewise. * elf32-ip2k.c (ip2k_info_to_howto_rela): Likewise. * elf32-iq2000.c (iq2000_info_to_howto_rela): Likewise. * elf32-lm32.c (lm32_info_to_howto_rela): Likewise. * elf32-m32c.c (m32c_info_to_howto_rela): Likewise. * elf32-m32r.c (m32r_info_to_howto_rel): Likewise. * elf32-m68hc11.c (m68hc11_info_to_howto_rel): Likewise. * elf32-m68hc12.c (m68hc11_info_to_howto_rel): Likewise. * elf32-mcore.c (mcore_elf_info_to_howto): Likewise. * elf32-mep.c (mep_info_to_howto_rela): Likewise. * elf32-metag.c (metag_info_to_howto_rela): Likewise. * elf32-microblaze.c (microblaze_elf_info_to_howto): Likewise. * elf32-moxie.c (moxie_info_to_howto_rela): Likewise. * elf32-msp430.c (msp430_info_to_howto_rela): Likewise. * elf32-mt.c (mt_info_to_howto_rela): Likewise. * elf32-nds32.c (nds32_info_to_howto_rel): Likewise. * elf32-or1k.c (or1k_info_to_howto_rela): Likewise. * elf32-pj.c (pj_elf_info_to_howto): Likewise. * elf32-ppc.c (ppc_elf_info_to_howto): Likewise. * elf32-rl78.c (rl78_info_to_howto_rela): Likewise. * elf32-rx.c (rx_info_to_howto_rela): Likewise. * elf32-sh.c (sh_elf_info_to_howto): Likewise. * elf32-spu.c (spu_elf_info_to_howto): Likewise. * elf32-v850.c (v850_elf_perform_relocation): Likewise. * elf32-vax.c (rtype_to_howto): Likewise. * elf32-visium.c (visium_info_to_howto_rela): Likewise. * elf32-xgate.c (xgate_info_to_howto_rel): Likewise. * elf32-xtensa.c (elf_xtensa_info_to_howto_rela): Likewise. * elf64-alpha.c (elf64_alpha_info_to_howto): Likewise. * elf64-mmix.c (mmix_info_to_howto_rela): Likewise. * mach-o.c: Use bfd_alloc2 to allocate space for structure arrays. (bfd_mach_o_canonicalize_one_reloc): Fix check on out of range symbol indicies. (bfd_mach_o_canonicalize_relocs): Check for out of range alloc. (bfd_mach_o_canonicalize_dynamic_reloc): Likewise. (bfd_mach_o_build_dysymtab): Likewise. (bfd_mach_o_write_symtab_content): Set the string table size to zero upon error. (bfd_mach_o_read_symtab_symbols): Reset the nsyms value if the read fails. * peXXigen.c (pe_print_edata): Check for numeric overflow in edt fields. * tekhex.c (first_phase): Check for src pointer reaching end of buffer.
Diffstat (limited to 'bfd/mach-o.c')
-rw-r--r--bfd/mach-o.c80
1 files changed, 45 insertions, 35 deletions
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index e136c2d..d44b94c 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -390,7 +390,7 @@ bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname,
if (xlat)
{
len = strlen (xlat->bfd_name);
- res = bfd_alloc (abfd, len+1);
+ res = bfd_alloc (abfd, len + 1);
if (res == NULL)
return;
memcpy (res, xlat->bfd_name, len+1);
@@ -1389,7 +1389,7 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
if (reloc.r_extern)
{
/* PR 17512: file: 8396-1185-0.004. */
- if (bfd_get_symcount (abfd) > 0 && num > bfd_get_symcount (abfd))
+ if (num >= bfd_mach_o_count_symbols (abfd))
sym = bfd_und_section_ptr->symbol_ptr_ptr;
else if (syms == NULL)
sym = bfd_und_section_ptr->symbol_ptr_ptr;
@@ -1457,6 +1457,10 @@ bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
/* Allocate and read relocs. */
native_size = count * BFD_MACH_O_RELENT_SIZE;
+ /* PR 17512: file: 09477b57. */
+ if (native_size < count)
+ return -1;
+
native_relocs =
(struct mach_o_reloc_info_external *) bfd_malloc (native_size);
if (native_relocs == NULL)
@@ -1496,6 +1500,8 @@ bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
if (asect->relocation == NULL)
{
+ if (asect->reloc_count * sizeof (arelent) < asect->reloc_count)
+ return -1;
res = bfd_malloc (asect->reloc_count * sizeof (arelent));
if (res == NULL)
return -1;
@@ -1549,6 +1555,10 @@ bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
if (mdata->dyn_reloc_cache == NULL)
{
+ if ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent)
+ < (dysymtab->nextrel + dysymtab->nlocrel))
+ return -1;
+
res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel)
* sizeof (arelent));
if (res == NULL)
@@ -1863,11 +1873,10 @@ bfd_mach_o_write_symtab_content (bfd *abfd, bfd_mach_o_symtab_command *sym)
mdata->filelen += sym->strsize;
if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0)
- return FALSE;
+ goto err;
if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
goto err;
- _bfd_stringtab_free (strtab);
/* Pad string table. */
padlen = bfd_mach_o_pad4 (abfd, sym->strsize);
@@ -1880,6 +1889,7 @@ bfd_mach_o_write_symtab_content (bfd *abfd, bfd_mach_o_symtab_command *sym)
err:
_bfd_stringtab_free (strtab);
+ sym->strsize = 0;
return FALSE;
}
@@ -1997,6 +2007,8 @@ bfd_mach_o_build_dysymtab (bfd *abfd, bfd_mach_o_dysymtab_command *cmd)
cmd->indirectsymoff = mdata->filelen;
mdata->filelen += cmd->nindirectsyms * 4;
+ if (cmd->nindirectsyms * 4 < cmd->nindirectsyms)
+ return FALSE;
cmd->indirect_syms = bfd_zalloc (abfd, cmd->nindirectsyms * 4);
if (cmd->indirect_syms == NULL)
return FALSE;
@@ -2392,8 +2404,8 @@ bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
}
mdata->nsects = nsect;
- mdata->sections = bfd_alloc (abfd,
- mdata->nsects * sizeof (bfd_mach_o_section *));
+ mdata->sections = bfd_alloc2 (abfd,
+ mdata->nsects, sizeof (bfd_mach_o_section *));
if (mdata->sections == NULL)
return FALSE;
@@ -3731,32 +3743,28 @@ bfd_mach_o_read_symtab_symbols (bfd *abfd)
/* Return now if there are no symbols or if already loaded. */
return TRUE;
- sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
-
+ sym->symbols = bfd_alloc2 (abfd, sym->nsyms, sizeof (bfd_mach_o_asymbol));
if (sym->symbols == NULL)
{
(*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
+ sym->nsyms = 0;
return FALSE;
}
if (!bfd_mach_o_read_symtab_strtab (abfd))
- {
- bfd_release (abfd, sym->symbols);
- sym->symbols = NULL;
- return FALSE;
- }
+ goto fail;
for (i = 0; i < sym->nsyms; i++)
- {
- if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
- {
- bfd_release (abfd, sym->symbols);
- sym->symbols = NULL;
- return FALSE;
- }
- }
+ if (!bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i))
+ goto fail;
return TRUE;
+
+ fail:
+ bfd_release (abfd, sym->symbols);
+ sym->symbols = NULL;
+ sym->nsyms = 0;
+ return FALSE;
}
static const char *
@@ -3989,8 +3997,8 @@ bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
}
/* Allocate threads. */
- cmd->flavours = bfd_alloc
- (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
+ cmd->flavours = bfd_alloc2
+ (abfd, nflavours, sizeof (bfd_mach_o_thread_flavour));
if (cmd->flavours == NULL)
return FALSE;
cmd->nflavours = nflavours;
@@ -4113,7 +4121,7 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
unsigned int module_len = wide ? 56 : 52;
cmd->dylib_module =
- bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
+ bfd_alloc2 (abfd, cmd->nmodtab, sizeof (bfd_mach_o_dylib_module));
if (cmd->dylib_module == NULL)
return FALSE;
@@ -4159,10 +4167,10 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
if (cmd->ntoc != 0)
{
- unsigned int i;
+ unsigned long i;
- cmd->dylib_toc = bfd_alloc
- (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
+ cmd->dylib_toc = bfd_alloc2
+ (abfd, cmd->ntoc, sizeof (bfd_mach_o_dylib_table_of_content));
if (cmd->dylib_toc == NULL)
return FALSE;
@@ -4186,8 +4194,8 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
{
unsigned int i;
- cmd->indirect_syms = bfd_alloc
- (abfd, cmd->nindirectsyms * sizeof (unsigned int));
+ cmd->indirect_syms = bfd_alloc2
+ (abfd, cmd->nindirectsyms, sizeof (unsigned int));
if (cmd->indirect_syms == NULL)
return FALSE;
@@ -4211,8 +4219,8 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
unsigned long v;
unsigned int i;
- cmd->ext_refs = bfd_alloc
- (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
+ cmd->ext_refs = bfd_alloc2
+ (abfd, cmd->nextrefsyms, sizeof (bfd_mach_o_dylib_reference));
if (cmd->ext_refs == NULL)
return FALSE;
@@ -4743,8 +4751,8 @@ bfd_mach_o_flatten_sections (bfd *abfd)
}
/* Allocate sections array. */
- mdata->sections = bfd_alloc (abfd,
- mdata->nsects * sizeof (bfd_mach_o_section *));
+ mdata->sections = bfd_alloc2 (abfd,
+ mdata->nsects, sizeof (bfd_mach_o_section *));
/* Fill the array. */
csect = 0;
@@ -4916,7 +4924,8 @@ bfd_mach_o_scan (bfd *abfd,
mdata->first_command = NULL;
mdata->last_command = NULL;
- cmd = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
+
+ cmd = bfd_alloc2 (abfd, header->ncmds, sizeof (bfd_mach_o_load_command));
if (cmd == NULL)
return FALSE;
@@ -5152,7 +5161,7 @@ bfd_mach_o_archive_p (bfd *abfd)
goto error;
adata->archentries =
- bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
+ bfd_alloc2 (abfd, adata->nfat_arch, sizeof (mach_o_fat_archentry));
if (adata->archentries == NULL)
goto error;
@@ -5169,6 +5178,7 @@ bfd_mach_o_archive_p (bfd *abfd)
}
abfd->tdata.mach_o_fat_data = adata;
+
return abfd->xvec;
error: