From 806470a219e84665a59fc6be632d4ed6a4ad908b Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 19 Feb 2020 13:15:20 +1030 Subject: Miscellaneous memory alloc related fixes Some minor tidies. Allocating memory for internal relocs and symbols after reading external relocs is slightly better with fuzzed files. You can at least do something about silly sizes that way. * aoutx.h (slurp_reloc_table): Allocate reloc_cache after reading external relocs. * ecoff.c (ecoff_slurp_reloc_table): Likewise. * archive.c (_bfd_write_archive_contents): Don't twiddle bfd_error after bfd_bread. * archive64.c (_bfd_archive_64_bit_slurp_armap): Remove unnecessary bfd_release. * elf32-m32c.c (m32c_offset_for_reloc): Make shndx_buf a bfd_byte*. (m32c_elf_relax_section): Likewise. * elf32-rl78.c (rl78_offset_for_reloc): Likewise. (rl78_elf_relax_section): Likewise. * elf32-rx.c (rx_offset_for_reloc): Likewise. (elf32_rx_relax_section): Likewise. * mach-o.c (bfd_mach_o_alloc_and_read): Move earlier with better parameter types and use.. (bfd_mach_o_read_dylinker, bfd_mach_o_read_dylib), (bfd_mach_o_read_fvmlib, bfd_mach_o_read_str): ..in these functions. * peicode.h (pe_bfd_object_p): Don't zero the part of opthdr being read from file, just the extra. * som.c (som_slurp_symbol_table): Allocate internal symbol buffer after reading external syms. Free on failure. --- bfd/mach-o.c | 68 +++++++++++++++++++++++------------------------------------- 1 file changed, 26 insertions(+), 42 deletions(-) (limited to 'bfd/mach-o.c') diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 1cc9d43..fd9f480 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -3997,6 +3997,20 @@ bfd_mach_o_ppc_flavour_string (unsigned int flavour) } } +static unsigned char * +bfd_mach_o_alloc_and_read (bfd *abfd, file_ptr filepos, size_t size) +{ + unsigned char *buf; + + buf = bfd_alloc (abfd, size); + if (buf == NULL) + return NULL; + if (bfd_seek (abfd, filepos, SEEK_SET) != 0 + || bfd_bread (buf, size, abfd) != size) + return NULL; + return buf; +} + static bfd_boolean bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command) { @@ -4017,13 +4031,8 @@ bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command) cmd->name_offset = nameoff; namelen = command->len - nameoff; nameoff += command->offset; - cmd->name_str = bfd_alloc (abfd, namelen); - if (cmd->name_str == NULL) - return FALSE; - if (bfd_seek (abfd, nameoff, SEEK_SET) != 0 - || bfd_bread (cmd->name_str, namelen, abfd) != namelen) - return FALSE; - return TRUE; + cmd->name_str = (char *) bfd_mach_o_alloc_and_read (abfd, nameoff, namelen); + return cmd->name_str != NULL; } static bfd_boolean @@ -4034,6 +4043,7 @@ bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command) struct mach_o_dylib_command_external raw; unsigned int nameoff; unsigned int namelen; + file_ptr pos; if (command->len < sizeof (raw) + 8) return FALSE; @@ -4063,13 +4073,9 @@ bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command) cmd->name_offset = command->offset + nameoff; namelen = command->len - nameoff; - cmd->name_str = bfd_alloc (abfd, namelen); - if (cmd->name_str == NULL) - return FALSE; - if (bfd_seek (abfd, mdata->hdr_offset + cmd->name_offset, SEEK_SET) != 0 - || bfd_bread (cmd->name_str, namelen, abfd) != namelen) - return FALSE; - return TRUE; + pos = mdata->hdr_offset + cmd->name_offset; + cmd->name_str = (char *) bfd_mach_o_alloc_and_read (abfd, pos, namelen); + return cmd->name_str != NULL; } static bfd_boolean @@ -4163,13 +4169,9 @@ bfd_mach_o_read_fvmlib (bfd *abfd, bfd_mach_o_load_command *command) fvm->name_offset = command->offset + nameoff; namelen = command->len - nameoff; - fvm->name_str = bfd_alloc (abfd, namelen); - if (fvm->name_str == NULL) - return FALSE; - if (bfd_seek (abfd, fvm->name_offset, SEEK_SET) != 0 - || bfd_bread (fvm->name_str, namelen, abfd) != namelen) - return FALSE; - return TRUE; + fvm->name_str = (char *) bfd_mach_o_alloc_and_read (abfd, fvm->name_offset, + namelen); + return fvm->name_str != NULL; } static bfd_boolean @@ -4568,27 +4570,9 @@ bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command) cmd->stroff = command->offset + off; cmd->str_len = command->len - off; - cmd->str = bfd_alloc (abfd, cmd->str_len); - if (cmd->str == NULL) - return FALSE; - if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0 - || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len) - return FALSE; - return TRUE; -} - -static unsigned char * -bfd_mach_o_alloc_and_read (bfd *abfd, unsigned int off, unsigned int size) -{ - unsigned char *buf; - - buf = bfd_alloc (abfd, size); - if (buf == NULL) - return NULL; - if (bfd_seek (abfd, off, SEEK_SET) != 0 - || bfd_bread (buf, size, abfd) != size) - return NULL; - return buf; + cmd->str = (char *) bfd_mach_o_alloc_and_read (abfd, cmd->stroff, + cmd->str_len); + return cmd->str != NULL; } static bfd_boolean -- cgit v1.1