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.
This commit is contained in:
parent
1f4361a77b
commit
806470a219
@ -1,3 +1,27 @@
|
||||
2020-02-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2020-02-19 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* coffcode.h (buy_and_read, coff_slurp_line_table),
|
||||
|
29
bfd/aoutx.h
29
bfd/aoutx.h
@ -2316,34 +2316,29 @@ NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (reloc_size == 0)
|
||||
each_size = obj_reloc_entry_size (abfd);
|
||||
count = reloc_size / each_size;
|
||||
if (count == 0)
|
||||
return TRUE; /* Nothing to be done. */
|
||||
|
||||
if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
|
||||
return FALSE;
|
||||
|
||||
each_size = obj_reloc_entry_size (abfd);
|
||||
|
||||
count = reloc_size / each_size;
|
||||
if (count == 0)
|
||||
return TRUE; /* Nothing to be done. */
|
||||
|
||||
amt = count * sizeof (arelent);
|
||||
reloc_cache = (arelent *) bfd_zmalloc (amt);
|
||||
if (reloc_cache == NULL)
|
||||
return FALSE;
|
||||
|
||||
relocs = bfd_malloc (reloc_size);
|
||||
if (relocs == NULL)
|
||||
{
|
||||
free (reloc_cache);
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
|
||||
{
|
||||
free (relocs);
|
||||
free (reloc_cache);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
amt = count * sizeof (arelent);
|
||||
reloc_cache = (arelent *) bfd_zmalloc (amt);
|
||||
if (reloc_cache == NULL)
|
||||
{
|
||||
free (relocs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -2193,11 +2193,7 @@ _bfd_write_archive_contents (bfd *arch)
|
||||
amt = remaining;
|
||||
errno = 0;
|
||||
if (bfd_bread (buffer, amt, current) != amt)
|
||||
{
|
||||
if (bfd_get_error () != bfd_error_system_call)
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
goto input_err;
|
||||
}
|
||||
goto input_err;
|
||||
if (bfd_bwrite (buffer, amt, arch) != amt)
|
||||
return FALSE;
|
||||
remaining -= amt;
|
||||
|
@ -117,7 +117,7 @@ _bfd_archive_64_bit_slurp_armap (bfd *abfd)
|
||||
{
|
||||
if (bfd_get_error () != bfd_error_system_call)
|
||||
bfd_set_error (bfd_error_malformed_archive);
|
||||
goto release_raw_armap;
|
||||
goto release_symdefs;
|
||||
}
|
||||
|
||||
stringend = stringbase + stringsize;
|
||||
@ -142,8 +142,6 @@ _bfd_archive_64_bit_slurp_armap (bfd *abfd)
|
||||
|
||||
return TRUE;
|
||||
|
||||
release_raw_armap:
|
||||
bfd_release (abfd, raw_armap);
|
||||
release_symdefs:
|
||||
bfd_release (abfd, ardata->symdefs);
|
||||
return FALSE;
|
||||
|
15
bfd/ecoff.c
15
bfd/ecoff.c
@ -1623,20 +1623,25 @@ ecoff_slurp_reloc_table (bfd *abfd,
|
||||
if (! _bfd_ecoff_slurp_symbol_table (abfd))
|
||||
return FALSE;
|
||||
|
||||
amt = section->reloc_count;
|
||||
amt *= sizeof (arelent);
|
||||
internal_relocs = (arelent *) bfd_alloc (abfd, amt);
|
||||
|
||||
external_reloc_size = backend->external_reloc_size;
|
||||
amt = external_reloc_size * section->reloc_count;
|
||||
external_relocs = (char *) bfd_alloc (abfd, amt);
|
||||
if (internal_relocs == NULL || external_relocs == NULL)
|
||||
if (external_relocs == NULL)
|
||||
return FALSE;
|
||||
if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0)
|
||||
return FALSE;
|
||||
if (bfd_bread (external_relocs, amt, abfd) != amt)
|
||||
return FALSE;
|
||||
|
||||
amt = section->reloc_count;
|
||||
amt *= sizeof (arelent);
|
||||
internal_relocs = (arelent *) bfd_alloc (abfd, amt);
|
||||
if (internal_relocs == NULL)
|
||||
{
|
||||
bfd_release (abfd, external_relocs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++)
|
||||
{
|
||||
struct internal_reloc intern;
|
||||
|
@ -1284,7 +1284,7 @@ static bfd_vma
|
||||
m32c_offset_for_reloc (bfd *abfd,
|
||||
Elf_Internal_Rela *rel,
|
||||
Elf_Internal_Shdr *symtab_hdr,
|
||||
Elf_External_Sym_Shndx *shndx_buf ATTRIBUTE_UNUSED,
|
||||
bfd_byte *shndx_buf ATTRIBUTE_UNUSED,
|
||||
Elf_Internal_Sym *intsyms)
|
||||
{
|
||||
bfd_vma symval;
|
||||
@ -1442,7 +1442,7 @@ m32c_elf_relax_section
|
||||
bfd_byte * free_contents = NULL;
|
||||
Elf_Internal_Sym *intsyms = NULL;
|
||||
Elf_Internal_Sym *free_intsyms = NULL;
|
||||
Elf_External_Sym_Shndx *shndx_buf = NULL;
|
||||
bfd_byte *shndx_buf = NULL;
|
||||
int machine;
|
||||
|
||||
if (abfd == elf_hash_table (link_info)->dynobj
|
||||
@ -1499,13 +1499,13 @@ m32c_elf_relax_section
|
||||
bfd_set_error (bfd_error_file_too_big);
|
||||
goto error_return;
|
||||
}
|
||||
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
|
||||
shndx_buf = bfd_malloc (amt);
|
||||
if (shndx_buf == NULL)
|
||||
goto error_return;
|
||||
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|
||||
|| bfd_bread (shndx_buf, amt, abfd) != amt)
|
||||
goto error_return;
|
||||
shndx_hdr->contents = (bfd_byte *) shndx_buf;
|
||||
shndx_hdr->contents = shndx_buf;
|
||||
}
|
||||
|
||||
/* Get a copy of the native relocations. */
|
||||
|
@ -1822,7 +1822,7 @@ static bfd_vma
|
||||
rl78_offset_for_reloc (bfd * abfd,
|
||||
Elf_Internal_Rela * rel,
|
||||
Elf_Internal_Shdr * symtab_hdr,
|
||||
Elf_External_Sym_Shndx * shndx_buf ATTRIBUTE_UNUSED,
|
||||
bfd_byte * shndx_buf ATTRIBUTE_UNUSED,
|
||||
Elf_Internal_Sym * intsyms,
|
||||
Elf_Internal_Rela ** lrel,
|
||||
bfd * input_bfd,
|
||||
@ -2068,7 +2068,7 @@ rl78_elf_relax_section
|
||||
bfd_byte * free_contents = NULL;
|
||||
Elf_Internal_Sym * intsyms = NULL;
|
||||
Elf_Internal_Sym * free_intsyms = NULL;
|
||||
Elf_External_Sym_Shndx * shndx_buf = NULL;
|
||||
bfd_byte * shndx_buf = NULL;
|
||||
bfd_vma pc;
|
||||
bfd_vma symval ATTRIBUTE_UNUSED = 0;
|
||||
int pcrel ATTRIBUTE_UNUSED = 0;
|
||||
@ -2129,13 +2129,13 @@ rl78_elf_relax_section
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
goto error_return;
|
||||
}
|
||||
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
|
||||
shndx_buf = bfd_malloc (amt);
|
||||
if (shndx_buf == NULL)
|
||||
goto error_return;
|
||||
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|
||||
|| bfd_bread (shndx_buf, amt, abfd) != amt)
|
||||
goto error_return;
|
||||
shndx_hdr->contents = (bfd_byte *) shndx_buf;
|
||||
shndx_hdr->contents = shndx_buf;
|
||||
}
|
||||
|
||||
/* Get a copy of the native relocations. */
|
||||
|
@ -1738,7 +1738,7 @@ static bfd_vma
|
||||
rx_offset_for_reloc (bfd * abfd,
|
||||
Elf_Internal_Rela * rel,
|
||||
Elf_Internal_Shdr * symtab_hdr,
|
||||
Elf_External_Sym_Shndx * shndx_buf ATTRIBUTE_UNUSED,
|
||||
bfd_byte * shndx_buf ATTRIBUTE_UNUSED,
|
||||
Elf_Internal_Sym * intsyms,
|
||||
Elf_Internal_Rela ** lrel,
|
||||
bfd * input_bfd,
|
||||
@ -2005,7 +2005,7 @@ elf32_rx_relax_section (bfd * abfd,
|
||||
bfd_byte * free_contents = NULL;
|
||||
Elf_Internal_Sym * intsyms = NULL;
|
||||
Elf_Internal_Sym * free_intsyms = NULL;
|
||||
Elf_External_Sym_Shndx * shndx_buf = NULL;
|
||||
bfd_byte * shndx_buf = NULL;
|
||||
bfd_vma pc;
|
||||
bfd_vma sec_start;
|
||||
bfd_vma symval = 0;
|
||||
@ -2066,13 +2066,13 @@ elf32_rx_relax_section (bfd * abfd,
|
||||
bfd_set_error (bfd_error_file_too_big);
|
||||
goto error_return;
|
||||
}
|
||||
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
|
||||
shndx_buf = bfd_malloc (amt);
|
||||
if (shndx_buf == NULL)
|
||||
goto error_return;
|
||||
if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|
||||
|| bfd_bread (shndx_buf, amt, abfd) != amt)
|
||||
goto error_return;
|
||||
shndx_hdr->contents = (bfd_byte *) shndx_buf;
|
||||
shndx_hdr->contents = shndx_buf;
|
||||
}
|
||||
|
||||
/* Get a copy of the native relocations. */
|
||||
|
68
bfd/mach-o.c
68
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
|
||||
|
@ -1408,7 +1408,7 @@ pe_bfd_object_p (bfd * abfd)
|
||||
struct external_PEI_IMAGE_hdr image_hdr;
|
||||
struct internal_filehdr internal_f;
|
||||
struct internal_aouthdr internal_a;
|
||||
file_ptr opt_hdr_size;
|
||||
bfd_size_type opt_hdr_size;
|
||||
file_ptr offset;
|
||||
const bfd_target *result;
|
||||
|
||||
@ -1494,12 +1494,14 @@ pe_bfd_object_p (bfd * abfd)
|
||||
if (amt < sizeof (PEAOUTHDR))
|
||||
amt = sizeof (PEAOUTHDR);
|
||||
|
||||
opthdr = bfd_zalloc (abfd, amt);
|
||||
opthdr = bfd_alloc (abfd, amt);
|
||||
if (opthdr == NULL)
|
||||
return NULL;
|
||||
if (bfd_bread (opthdr, opt_hdr_size, abfd)
|
||||
!= (bfd_size_type) opt_hdr_size)
|
||||
return NULL;
|
||||
if (amt > opt_hdr_size)
|
||||
memset (opthdr + opt_hdr_size, 0, amt - opt_hdr_size);
|
||||
|
||||
bfd_set_error (bfd_error_no_error);
|
||||
bfd_coff_swap_aouthdr_in (abfd, opthdr, & internal_a);
|
||||
|
22
bfd/som.c
22
bfd/som.c
@ -4659,7 +4659,7 @@ som_slurp_symbol_table (bfd *abfd)
|
||||
size_t symsize = sizeof (struct som_external_symbol_dictionary_record);
|
||||
char *stringtab;
|
||||
struct som_external_symbol_dictionary_record *buf = NULL, *bufp, *endbufp;
|
||||
som_symbol_type *sym, *symbase;
|
||||
som_symbol_type *sym, *symbase = NULL;
|
||||
size_t amt;
|
||||
|
||||
/* Return saved value if it exists. */
|
||||
@ -4675,15 +4675,6 @@ som_slurp_symbol_table (bfd *abfd)
|
||||
|
||||
stringtab = obj_som_stringtab (abfd);
|
||||
|
||||
if (_bfd_mul_overflow (symbol_count, sizeof (som_symbol_type), &amt))
|
||||
{
|
||||
bfd_set_error (bfd_error_file_too_big);
|
||||
goto error_return;
|
||||
}
|
||||
symbase = bfd_zmalloc (amt);
|
||||
if (symbase == NULL)
|
||||
goto error_return;
|
||||
|
||||
/* Read in the external SOM representation. */
|
||||
if (_bfd_mul_overflow (symbol_count, symsize, &amt))
|
||||
{
|
||||
@ -4698,6 +4689,15 @@ som_slurp_symbol_table (bfd *abfd)
|
||||
if (bfd_bread (buf, amt, abfd) != amt)
|
||||
goto error_return;
|
||||
|
||||
if (_bfd_mul_overflow (symbol_count, sizeof (som_symbol_type), &amt))
|
||||
{
|
||||
bfd_set_error (bfd_error_file_too_big);
|
||||
goto error_return;
|
||||
}
|
||||
symbase = bfd_zmalloc (amt);
|
||||
if (symbase == NULL)
|
||||
goto error_return;
|
||||
|
||||
/* Iterate over all the symbols and internalize them. */
|
||||
endbufp = buf + symbol_count;
|
||||
for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp)
|
||||
@ -4837,6 +4837,8 @@ som_slurp_symbol_table (bfd *abfd)
|
||||
return (TRUE);
|
||||
|
||||
error_return:
|
||||
if (symbase != NULL)
|
||||
free (symbase);
|
||||
if (buf != NULL)
|
||||
free (buf);
|
||||
return FALSE;
|
||||
|
Loading…
Reference in New Issue
Block a user