_bfd_mul_overflow

This patch removes the bfd_alloc2 series of memory allocation functions,
replacing them with __builtin_mul_overflow followed by bfd_alloc.  Why
do that?  Well, a followup patch will implement _bfd_alloc_and_read
and I don't want to implement alloc2 variants as well.

	* coffcode.h (buy_and_read, coff_slurp_line_table),
	(coff_slurp_symbol_table, coff_slurp_reloc_table): Replace
	bfd_[z][m]alloc2 calls with _bfd_mul_overflow followed by the
	corresponding bfd_alloc call.  Adjust variables to suit.
	* coffgen.c (_bfd_coff_get_external_symbols): Likewise.
	* ecoff.c (_bfd_ecoff_slurp_symbolic_info),
	(_bfd_ecoff_slurp_symbol_table, READ): Likewise.
	* elf.c (bfd_elf_get_elf_syms, setup_group, bfd_section_from_shdr),
	(swap_out_syms, _bfd_elf_slurp_version_tables): Likewise.
	* elf32-m32c.c (m32c_elf_relax_section): Likewise.
	* elf32-rl78.c (rl78_elf_relax_section): Likewise.
	* elf32-rx.c (elf32_rx_relax_section): Likewise.
	* elf64-alpha.c (READ): Likewise.
	* elfcode.h (elf_object_p, elf_write_relocs, elf_write_shdrs_and_ehdr),
	(elf_slurp_symbol_table, elf_slurp_reloc_table),
	(bfd_from_remote_memory): Likewise.
	* elfcore.h (core_find_build_id): Likewise.
	* elfxx-mips.c (READ): Likewise.
	* mach-o.c (bfd_mach_o_mangle_sections),
	(bfd_mach_o_read_symtab_symbols, bfd_mach_o_read_thread),
	(bfd_mach_o_read_dysymtab, bfd_mach_o_flatten_sections),
	(bfd_mach_o_scan, bfd_mach_o_fat_archive_p): Likewise.
	* som.c (setup_sections, som_prep_for_fixups)
	(som_build_and_write_symbol_table, som_slurp_symbol_table),
	(som_slurp_reloc_table, som_bfd_count_ar_symbols),
	(som_bfd_fill_in_ar_symbols, som_slurp_armap),
	(som_bfd_ar_write_symbol_stuff): Likewise.
	* vms-alpha.c (vector_grow1): Likewise.
	* vms-lib.c (vms_add_index): Likewise.
	* wasm-module.c (wasm_scan_name_function_section): Likewise.
	* libbfd.c (bfd_malloc2, bfd_realloc2, bfd_zmalloc2): Delete.
	* opncls.c (bfd_alloc2, bfd_zalloc2): Delete.
	* libbfd-in.h (bfd_malloc2, bfd_realloc2, bfd_zmalloc2),
	(bfd_alloc2, bfd_zalloc2): Delete.
	(_bfd_mul_overflow): Define.
	* libbfd.h: Regenerate.
This commit is contained in:
Alan Modra 2020-02-19 13:15:06 +10:30
parent 446f7ed5ab
commit 1f4361a77b
21 changed files with 541 additions and 353 deletions

View file

@ -1,3 +1,42 @@
2020-02-19 Alan Modra <amodra@gmail.com>
* coffcode.h (buy_and_read, coff_slurp_line_table),
(coff_slurp_symbol_table, coff_slurp_reloc_table): Replace
bfd_[z][m]alloc2 calls with _bfd_mul_overflow followed by the
corresponding bfd_alloc call. Adjust variables to suit.
* coffgen.c (_bfd_coff_get_external_symbols): Likewise.
* ecoff.c (_bfd_ecoff_slurp_symbolic_info),
(_bfd_ecoff_slurp_symbol_table, READ): Likewise.
* elf.c (bfd_elf_get_elf_syms, setup_group, bfd_section_from_shdr),
(swap_out_syms, _bfd_elf_slurp_version_tables): Likewise.
* elf32-m32c.c (m32c_elf_relax_section): Likewise.
* elf32-rl78.c (rl78_elf_relax_section): Likewise.
* elf32-rx.c (elf32_rx_relax_section): Likewise.
* elf64-alpha.c (READ): Likewise.
* elfcode.h (elf_object_p, elf_write_relocs, elf_write_shdrs_and_ehdr),
(elf_slurp_symbol_table, elf_slurp_reloc_table),
(bfd_from_remote_memory): Likewise.
* elfcore.h (core_find_build_id): Likewise.
* elfxx-mips.c (READ): Likewise.
* mach-o.c (bfd_mach_o_mangle_sections),
(bfd_mach_o_read_symtab_symbols, bfd_mach_o_read_thread),
(bfd_mach_o_read_dysymtab, bfd_mach_o_flatten_sections),
(bfd_mach_o_scan, bfd_mach_o_fat_archive_p): Likewise.
* som.c (setup_sections, som_prep_for_fixups)
(som_build_and_write_symbol_table, som_slurp_symbol_table),
(som_slurp_reloc_table, som_bfd_count_ar_symbols),
(som_bfd_fill_in_ar_symbols, som_slurp_armap),
(som_bfd_ar_write_symbol_stuff): Likewise.
* vms-alpha.c (vector_grow1): Likewise.
* vms-lib.c (vms_add_index): Likewise.
* wasm-module.c (wasm_scan_name_function_section): Likewise.
* libbfd.c (bfd_malloc2, bfd_realloc2, bfd_zmalloc2): Delete.
* opncls.c (bfd_alloc2, bfd_zalloc2): Delete.
* libbfd-in.h (bfd_malloc2, bfd_realloc2, bfd_zmalloc2),
(bfd_alloc2, bfd_zalloc2): Delete.
(_bfd_mul_overflow): Define.
* libbfd.h: Regenerate.
2020-02-19 Alan Modra <amodra@gmail.com> 2020-02-19 Alan Modra <amodra@gmail.com>
* elf.c (bfd_section_from_shdr): Use bfd_zalloc rather than * elf.c (bfd_section_from_shdr): Use bfd_zalloc rather than

View file

@ -4200,13 +4200,19 @@ static void *
buy_and_read (bfd *abfd, file_ptr where, buy_and_read (bfd *abfd, file_ptr where,
bfd_size_type nmemb, bfd_size_type size) bfd_size_type nmemb, bfd_size_type size)
{ {
void *area = bfd_alloc2 (abfd, nmemb, size); void *area;
size_t amt;
if (_bfd_mul_overflow (nmemb, size, &amt))
{
bfd_set_error (bfd_error_file_too_big);
return NULL;
}
area = bfd_alloc (abfd, amt);
if (!area) if (!area)
return NULL; return NULL;
size *= nmemb;
if (bfd_seek (abfd, where, SEEK_SET) != 0 if (bfd_seek (abfd, where, SEEK_SET) != 0
|| bfd_bread (area, size, abfd) != size) || bfd_bread (area, amt, abfd) != amt)
return NULL; return NULL;
return area; return area;
} }
@ -4265,6 +4271,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
LINENO *src; LINENO *src;
bfd_boolean have_func; bfd_boolean have_func;
bfd_boolean ret = TRUE; bfd_boolean ret = TRUE;
size_t amt;
if (asect->lineno_count == 0) if (asect->lineno_count == 0)
return TRUE; return TRUE;
@ -4279,9 +4286,12 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
return FALSE; return FALSE;
} }
lineno_cache = (alent *) bfd_alloc2 (abfd, if (_bfd_mul_overflow (asect->lineno_count + 1, sizeof (alent), &amt))
(bfd_size_type) asect->lineno_count + 1, {
sizeof (alent)); bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
lineno_cache = (alent *) bfd_alloc (abfd, amt);
if (lineno_cache == NULL) if (lineno_cache == NULL)
return FALSE; return FALSE;
@ -4395,8 +4405,12 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
alent *n_lineno_cache; alent *n_lineno_cache;
/* Create a table of functions. */ /* Create a table of functions. */
func_table = (alent **) bfd_alloc2 (abfd, nbr_func, sizeof (alent *)); if (_bfd_mul_overflow (nbr_func, sizeof (alent *), &amt))
if (func_table != NULL) {
bfd_set_error (bfd_error_file_too_big);
ret = FALSE;
}
else if ((func_table = (alent **) bfd_alloc (abfd, amt)) != NULL)
{ {
alent **p = func_table; alent **p = func_table;
unsigned int i; unsigned int i;
@ -4411,9 +4425,12 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent); qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent);
/* Create the new sorted table. */ /* Create the new sorted table. */
n_lineno_cache = (alent *) bfd_alloc2 (abfd, asect->lineno_count, if (_bfd_mul_overflow (asect->lineno_count, sizeof (alent), &amt))
sizeof (alent)); {
if (n_lineno_cache != NULL) bfd_set_error (bfd_error_file_too_big);
ret = FALSE;
}
else if ((n_lineno_cache = (alent *) bfd_alloc (abfd, amt)) != NULL)
{ {
alent *n_cache_ptr = n_lineno_cache; alent *n_cache_ptr = n_lineno_cache;
@ -4459,6 +4476,7 @@ coff_slurp_symbol_table (bfd * abfd)
unsigned int *table_ptr; unsigned int *table_ptr;
unsigned int number_of_symbols = 0; unsigned int number_of_symbols = 0;
bfd_boolean ret = TRUE; bfd_boolean ret = TRUE;
size_t amt;
if (obj_symbols (abfd)) if (obj_symbols (abfd))
return TRUE; return TRUE;
@ -4468,15 +4486,23 @@ coff_slurp_symbol_table (bfd * abfd)
return FALSE; return FALSE;
/* Allocate enough room for all the symbols in cached form. */ /* Allocate enough room for all the symbols in cached form. */
cached_area = (coff_symbol_type *) bfd_alloc2 (abfd, if (_bfd_mul_overflow (obj_raw_syment_count (abfd),
obj_raw_syment_count (abfd), sizeof (*cached_area), &amt))
sizeof (coff_symbol_type)); {
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
cached_area = (coff_symbol_type *) bfd_alloc (abfd, amt);
if (cached_area == NULL) if (cached_area == NULL)
return FALSE; return FALSE;
table_ptr = (unsigned int *) bfd_zalloc2 (abfd, obj_raw_syment_count (abfd), if (_bfd_mul_overflow (obj_raw_syment_count (abfd),
sizeof (unsigned int)); sizeof (*table_ptr), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
table_ptr = (unsigned int *) bfd_zalloc (abfd, amt);
if (table_ptr == NULL) if (table_ptr == NULL)
return FALSE; return FALSE;
else else
@ -4963,6 +4989,7 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
arelent *reloc_cache; arelent *reloc_cache;
arelent *cache_ptr; arelent *cache_ptr;
unsigned int idx; unsigned int idx;
size_t amt;
if (asect->relocation) if (asect->relocation)
return TRUE; return TRUE;
@ -4976,9 +5003,12 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
native_relocs = (RELOC *) buy_and_read (abfd, asect->rel_filepos, native_relocs = (RELOC *) buy_and_read (abfd, asect->rel_filepos,
asect->reloc_count, asect->reloc_count,
bfd_coff_relsz (abfd)); bfd_coff_relsz (abfd));
reloc_cache = (arelent *) bfd_alloc2 (abfd, asect->reloc_count, if (_bfd_mul_overflow (asect->reloc_count, sizeof (arelent), &amt))
sizeof (arelent)); {
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
reloc_cache = (arelent *) bfd_alloc (abfd, amt);
if (reloc_cache == NULL || native_relocs == NULL) if (reloc_cache == NULL || native_relocs == NULL)
return FALSE; return FALSE;

View file

@ -1639,30 +1639,29 @@ copy_name (bfd *abfd, char *name, size_t maxlen)
bfd_boolean bfd_boolean
_bfd_coff_get_external_symbols (bfd *abfd) _bfd_coff_get_external_symbols (bfd *abfd)
{ {
bfd_size_type symesz; size_t symesz;
bfd_size_type size; size_t size;
void * syms; void * syms;
ufile_ptr filesize; ufile_ptr filesize;
if (obj_coff_external_syms (abfd) != NULL) if (obj_coff_external_syms (abfd) != NULL)
return TRUE; return TRUE;
symesz = bfd_coff_symesz (abfd);
size = obj_raw_syment_count (abfd) * symesz;
if (size == 0)
return TRUE;
/* Check for integer overflow and for unreasonable symbol counts. */ /* Check for integer overflow and for unreasonable symbol counts. */
filesize = bfd_get_file_size (abfd); filesize = bfd_get_file_size (abfd);
if (size < obj_raw_syment_count (abfd) symesz = bfd_coff_symesz (abfd);
if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size)
|| (filesize != 0 && size > filesize)) || (filesize != 0 && size > filesize))
{ {
bfd_set_error (bfd_error_file_truncated);
_bfd_error_handler (_("%pB: corrupt symbol count: %#" PRIx64 ""), _bfd_error_handler (_("%pB: corrupt symbol count: %#" PRIx64 ""),
abfd, (uint64_t) obj_raw_syment_count (abfd)); abfd, (uint64_t) obj_raw_syment_count (abfd));
return FALSE; return FALSE;
} }
if (size == 0)
return TRUE;
syms = bfd_malloc (size); syms = bfd_malloc (size);
if (syms == NULL) if (syms == NULL)
{ {

View file

@ -514,6 +514,7 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
bfd_size_type raw_end; bfd_size_type raw_end;
bfd_size_type cb_end; bfd_size_type cb_end;
file_ptr pos; file_ptr pos;
size_t amt;
BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info); BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info);
@ -615,8 +616,13 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
We need to look at the fdr to deal with a lot of information in We need to look at the fdr to deal with a lot of information in
the symbols, so we swap them here. */ the symbols, so we swap them here. */
debug->fdr = (FDR *) bfd_alloc2 (abfd, internal_symhdr->ifdMax, if (_bfd_mul_overflow ((unsigned long) internal_symhdr->ifdMax,
sizeof (struct fdr)); sizeof (struct fdr), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
debug->fdr = (FDR *) bfd_alloc (abfd, amt);
if (debug->fdr == NULL) if (debug->fdr == NULL)
return FALSE; return FALSE;
external_fdr_size = backend->debug_swap.external_fdr_size; external_fdr_size = backend->debug_swap.external_fdr_size;
@ -872,6 +878,7 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
char *eraw_end; char *eraw_end;
FDR *fdr_ptr; FDR *fdr_ptr;
FDR *fdr_end; FDR *fdr_end;
size_t amt;
/* If we've already read in the symbol table, do nothing. */ /* If we've already read in the symbol table, do nothing. */
if (ecoff_data (abfd)->canonical_symbols != NULL) if (ecoff_data (abfd)->canonical_symbols != NULL)
@ -884,8 +891,13 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
if (bfd_get_symcount (abfd) == 0) if (bfd_get_symcount (abfd) == 0)
return TRUE; return TRUE;
internal = (ecoff_symbol_type *) bfd_alloc2 (abfd, bfd_get_symcount (abfd), if (_bfd_mul_overflow (bfd_get_symcount (abfd),
sizeof (ecoff_symbol_type)); sizeof (ecoff_symbol_type), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
internal = (ecoff_symbol_type *) bfd_alloc (abfd, amt);
if (internal == NULL) if (internal == NULL)
return FALSE; return FALSE;
@ -3745,25 +3757,32 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd,
HDRR *symhdr = &debug->symbolic_header; HDRR *symhdr = &debug->symbolic_header;
bfd_boolean ret; bfd_boolean ret;
#define READ(ptr, offset, count, size, type) \ #define READ(ptr, offset, count, size, type) \
if (symhdr->count == 0) \ do \
debug->ptr = NULL; \ { \
else \ size_t amt; \
{ \ debug->ptr = NULL; \
bfd_size_type amt = (bfd_size_type) size * symhdr->count; \ if (symhdr->count == 0) \
debug->ptr = (type) bfd_malloc (amt); \ break; \
if (debug->ptr == NULL) \ if (_bfd_mul_overflow (size, symhdr->count, &amt)) \
{ \ { \
ret = FALSE; \ bfd_set_error (bfd_error_file_too_big); \
goto return_something; \ ret = FALSE; \
} \ goto return_something; \
if (bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ } \
|| bfd_bread (debug->ptr, amt, input_bfd) != amt) \ debug->ptr = (type) bfd_malloc (amt); \
{ \ if (debug->ptr == NULL) \
ret = FALSE; \ { \
goto return_something; \ ret = FALSE; \
} \ goto return_something; \
} } \
if (bfd_seek (input_bfd, symhdr->offset, SEEK_SET) != 0 \
|| bfd_bread (debug->ptr, amt, input_bfd) != amt) \
{ \
ret = FALSE; \
goto return_something; \
} \
} while (0)
/* If raw_syments is not NULL, then the data was already by read by /* If raw_syments is not NULL, then the data was already by read by
_bfd_ecoff_slurp_symbolic_info. */ _bfd_ecoff_slurp_symbolic_info. */

144
bfd/elf.c
View file

@ -402,7 +402,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
Elf_Internal_Sym *isymend; Elf_Internal_Sym *isymend;
const struct elf_backend_data *bed; const struct elf_backend_data *bed;
size_t extsym_size; size_t extsym_size;
bfd_size_type amt; size_t amt;
file_ptr pos; file_ptr pos;
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
@ -448,11 +448,16 @@ bfd_elf_get_elf_syms (bfd *ibfd,
alloc_intsym = NULL; alloc_intsym = NULL;
bed = get_elf_backend_data (ibfd); bed = get_elf_backend_data (ibfd);
extsym_size = bed->s->sizeof_sym; extsym_size = bed->s->sizeof_sym;
amt = (bfd_size_type) symcount * extsym_size; if (_bfd_mul_overflow (symcount, extsym_size, &amt))
{
bfd_set_error (bfd_error_file_too_big);
intsym_buf = NULL;
goto out;
}
pos = symtab_hdr->sh_offset + symoffset * extsym_size; pos = symtab_hdr->sh_offset + symoffset * extsym_size;
if (extsym_buf == NULL) if (extsym_buf == NULL)
{ {
alloc_ext = bfd_malloc2 (symcount, extsym_size); alloc_ext = bfd_malloc (amt);
extsym_buf = alloc_ext; extsym_buf = alloc_ext;
} }
if (extsym_buf == NULL if (extsym_buf == NULL
@ -467,12 +472,16 @@ bfd_elf_get_elf_syms (bfd *ibfd,
extshndx_buf = NULL; extshndx_buf = NULL;
else else
{ {
amt = (bfd_size_type) symcount * sizeof (Elf_External_Sym_Shndx); if (_bfd_mul_overflow (symcount, sizeof (Elf_External_Sym_Shndx), &amt))
{
bfd_set_error (bfd_error_file_too_big);
intsym_buf = NULL;
goto out;
}
pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx); pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
if (extshndx_buf == NULL) if (extshndx_buf == NULL)
{ {
alloc_extshndx = (Elf_External_Sym_Shndx *) alloc_extshndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
bfd_malloc2 (symcount, sizeof (Elf_External_Sym_Shndx));
extshndx_buf = alloc_extshndx; extshndx_buf = alloc_extshndx;
} }
if (extshndx_buf == NULL if (extshndx_buf == NULL
@ -486,8 +495,12 @@ bfd_elf_get_elf_syms (bfd *ibfd,
if (intsym_buf == NULL) if (intsym_buf == NULL)
{ {
alloc_intsym = (Elf_Internal_Sym *) if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt))
bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym)); {
bfd_set_error (bfd_error_file_too_big);
goto out;
}
alloc_intsym = (Elf_Internal_Sym *) bfd_malloc (amt);
intsym_buf = alloc_intsym; intsym_buf = alloc_intsym;
if (intsym_buf == NULL) if (intsym_buf == NULL)
goto out; goto out;
@ -629,15 +642,14 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
{ {
/* We keep a list of elf section headers for group sections, /* We keep a list of elf section headers for group sections,
so we can find them quickly. */ so we can find them quickly. */
bfd_size_type amt; size_t amt;
elf_tdata (abfd)->num_group = num_group; elf_tdata (abfd)->num_group = num_group;
elf_tdata (abfd)->group_sect_ptr = (Elf_Internal_Shdr **) amt = num_group * sizeof (Elf_Internal_Shdr *);
bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *)); elf_tdata (abfd)->group_sect_ptr
= (Elf_Internal_Shdr **) bfd_zalloc (abfd, amt);
if (elf_tdata (abfd)->group_sect_ptr == NULL) if (elf_tdata (abfd)->group_sect_ptr == NULL)
return FALSE; return FALSE;
memset (elf_tdata (abfd)->group_sect_ptr, 0,
num_group * sizeof (Elf_Internal_Shdr *));
num_group = 0; num_group = 0;
for (i = 0; i < shnum; i++) for (i = 0; i < shnum; i++)
@ -659,24 +671,12 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
num_group += 1; num_group += 1;
/* Read the raw contents. */ /* Read the raw contents. */
BFD_ASSERT (sizeof (*dest) >= 4); BFD_ASSERT (sizeof (*dest) >= 4 && sizeof (*dest) % 4 == 0);
amt = shdr->sh_size * sizeof (*dest) / 4; shdr->contents = NULL;
shdr->contents = (unsigned char *) if (_bfd_mul_overflow (shdr->sh_size,
bfd_alloc2 (abfd, shdr->sh_size, sizeof (*dest) / 4); sizeof (*dest) / 4, &amt)
/* PR binutils/4110: Handle corrupt group headers. */ || (shdr->contents = bfd_alloc (abfd, amt)) == NULL
if (shdr->contents == NULL) || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
{
_bfd_error_handler
/* xgettext:c-format */
(_("%pB: corrupt size field in group section"
" header: %#" PRIx64),
abfd, (uint64_t) shdr->sh_size);
bfd_set_error (bfd_error_bad_value);
-- num_group;
continue;
}
if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
|| (bfd_bread (shdr->contents, shdr->sh_size, abfd) || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
!= shdr->sh_size)) != shdr->sh_size))
{ {
@ -690,8 +690,11 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
/* PR 17510: If the group contents are even /* PR 17510: If the group contents are even
partially corrupt, do not allow any of the partially corrupt, do not allow any of the
contents to be used. */ contents to be used. */
bfd_release (abfd, shdr->contents); if (shdr->contents != NULL)
shdr->contents = NULL; {
bfd_release (abfd, shdr->contents);
shdr->contents = NULL;
}
continue; continue;
} }
@ -8015,7 +8018,7 @@ swap_out_syms (bfd *abfd,
int relocatable_p) int relocatable_p)
{ {
const struct elf_backend_data *bed; const struct elf_backend_data *bed;
int symcount; unsigned int symcount;
asymbol **syms; asymbol **syms;
struct elf_strtab_hash *stt; struct elf_strtab_hash *stt;
Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Shdr *symtab_hdr;
@ -8026,9 +8029,9 @@ swap_out_syms (bfd *abfd,
bfd_byte *outbound_shndx; bfd_byte *outbound_shndx;
unsigned long outbound_syms_index; unsigned long outbound_syms_index;
unsigned long outbound_shndx_index; unsigned long outbound_shndx_index;
int idx; unsigned int idx;
unsigned int num_locals; unsigned int num_locals;
bfd_size_type amt; size_t amt;
bfd_boolean name_local_sections; bfd_boolean name_local_sections;
if (!elf_map_symbols (abfd, &num_locals)) if (!elf_map_symbols (abfd, &num_locals))
@ -8052,21 +8055,22 @@ swap_out_syms (bfd *abfd,
symstrtab_hdr->sh_type = SHT_STRTAB; symstrtab_hdr->sh_type = SHT_STRTAB;
/* Allocate buffer to swap out the .strtab section. */ /* Allocate buffer to swap out the .strtab section. */
symstrtab = (struct elf_sym_strtab *) bfd_malloc2 (symcount + 1, if (_bfd_mul_overflow (symcount + 1, sizeof (*symstrtab), &amt)
sizeof (*symstrtab)); || (symstrtab = (struct elf_sym_strtab *) bfd_malloc (amt)) == NULL)
if (symstrtab == NULL)
{ {
bfd_set_error (bfd_error_no_memory);
_bfd_elf_strtab_free (stt); _bfd_elf_strtab_free (stt);
return FALSE; return FALSE;
} }
outbound_syms = (bfd_byte *) bfd_alloc2 (abfd, 1 + symcount, if (_bfd_mul_overflow (symcount + 1, bed->s->sizeof_sym, &amt)
bed->s->sizeof_sym); || (outbound_syms = (bfd_byte *) bfd_alloc (abfd, amt)) == NULL)
if (outbound_syms == NULL)
{ {
error_return: error_no_mem:
_bfd_elf_strtab_free (stt); bfd_set_error (bfd_error_no_memory);
error_return:
free (symstrtab); free (symstrtab);
_bfd_elf_strtab_free (stt);
return FALSE; return FALSE;
} }
symtab_hdr->contents = outbound_syms; symtab_hdr->contents = outbound_syms;
@ -8080,9 +8084,10 @@ error_return:
symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr; symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
if (symtab_shndx_hdr->sh_name != 0) if (symtab_shndx_hdr->sh_name != 0)
{ {
amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx); if (_bfd_mul_overflow (symcount + 1,
outbound_shndx = (bfd_byte *) sizeof (Elf_External_Sym_Shndx), &amt))
bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx)); goto error_no_mem;
outbound_shndx = (bfd_byte *) bfd_zalloc (abfd, amt);
if (outbound_shndx == NULL) if (outbound_shndx == NULL)
goto error_return; goto error_return;
@ -8570,6 +8575,7 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
{ {
bfd_byte *contents = NULL; bfd_byte *contents = NULL;
unsigned int freeidx = 0; unsigned int freeidx = 0;
size_t amt;
if (elf_dynverref (abfd) != 0) if (elf_dynverref (abfd) != 0)
{ {
@ -8614,9 +8620,12 @@ error_return_verref:
|| bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
goto error_return_verref; goto error_return_verref;
elf_tdata (abfd)->verref = (Elf_Internal_Verneed *) if (_bfd_mul_overflow (hdr->sh_info, sizeof (Elf_Internal_Verneed), &amt))
bfd_alloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed)); {
bfd_set_error (bfd_error_file_too_big);
goto error_return_verref;
}
elf_tdata (abfd)->verref = (Elf_Internal_Verneed *) bfd_alloc (abfd, amt);
if (elf_tdata (abfd)->verref == NULL) if (elf_tdata (abfd)->verref == NULL)
goto error_return_verref; goto error_return_verref;
@ -8645,9 +8654,14 @@ error_return_verref:
iverneed->vn_auxptr = NULL; iverneed->vn_auxptr = NULL;
else else
{ {
if (_bfd_mul_overflow (iverneed->vn_cnt,
sizeof (Elf_Internal_Vernaux), &amt))
{
bfd_set_error (bfd_error_file_too_big);
goto error_return_verref;
}
iverneed->vn_auxptr = (struct elf_internal_vernaux *) iverneed->vn_auxptr = (struct elf_internal_vernaux *)
bfd_alloc2 (abfd, iverneed->vn_cnt, bfd_alloc (abfd, amt);
sizeof (Elf_Internal_Vernaux));
if (iverneed->vn_auxptr == NULL) if (iverneed->vn_auxptr == NULL)
goto error_return_verref; goto error_return_verref;
} }
@ -8779,9 +8793,12 @@ error_return_verref:
else else
freeidx = ++maxidx; freeidx = ++maxidx;
} }
if (_bfd_mul_overflow (maxidx, sizeof (Elf_Internal_Verdef), &amt))
elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) {
bfd_zalloc2 (abfd, maxidx, sizeof (Elf_Internal_Verdef)); bfd_set_error (bfd_error_file_too_big);
goto error_return_verdef;
}
elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
if (elf_tdata (abfd)->verdef == NULL) if (elf_tdata (abfd)->verdef == NULL)
goto error_return_verdef; goto error_return_verdef;
@ -8809,9 +8826,14 @@ error_return_verref:
iverdef->vd_auxptr = NULL; iverdef->vd_auxptr = NULL;
else else
{ {
if (_bfd_mul_overflow (iverdef->vd_cnt,
sizeof (Elf_Internal_Verdaux), &amt))
{
bfd_set_error (bfd_error_file_too_big);
goto error_return_verdef;
}
iverdef->vd_auxptr = (struct elf_internal_verdaux *) iverdef->vd_auxptr = (struct elf_internal_verdaux *)
bfd_alloc2 (abfd, iverdef->vd_cnt, bfd_alloc (abfd, amt);
sizeof (Elf_Internal_Verdaux));
if (iverdef->vd_auxptr == NULL) if (iverdef->vd_auxptr == NULL)
goto error_return_verdef; goto error_return_verdef;
} }
@ -8874,8 +8896,12 @@ error_return_verref:
else else
freeidx++; freeidx++;
elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) if (_bfd_mul_overflow (freeidx, sizeof (Elf_Internal_Verdef), &amt))
bfd_zalloc2 (abfd, freeidx, sizeof (Elf_Internal_Verdef)); {
bfd_set_error (bfd_error_file_too_big);
goto error_return;
}
elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
if (elf_tdata (abfd)->verdef == NULL) if (elf_tdata (abfd)->verdef == NULL)
goto error_return; goto error_return;

View file

@ -1491,10 +1491,14 @@ m32c_elf_relax_section
if (shndx_hdr && shndx_hdr->sh_size != 0) if (shndx_hdr && shndx_hdr->sh_size != 0)
{ {
bfd_size_type amt; size_t amt;
amt = symtab_hdr->sh_info; if (_bfd_mul_overflow (symtab_hdr->sh_info,
amt *= sizeof (Elf_External_Sym_Shndx); sizeof (Elf_External_Sym_Shndx), &amt))
{
bfd_set_error (bfd_error_file_too_big);
goto error_return;
}
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt); shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL) if (shndx_buf == NULL)
goto error_return; goto error_return;

View file

@ -2121,10 +2121,14 @@ rl78_elf_relax_section
if (shndx_hdr && shndx_hdr->sh_size != 0) if (shndx_hdr && shndx_hdr->sh_size != 0)
{ {
bfd_size_type amt; size_t amt;
amt = symtab_hdr->sh_info; if (_bfd_mul_overflow (symtab_hdr->sh_info,
amt *= sizeof (Elf_External_Sym_Shndx); sizeof (Elf_External_Sym_Shndx), &amt))
{
bfd_set_error (bfd_error_no_memory);
goto error_return;
}
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt); shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL) if (shndx_buf == NULL)
goto error_return; goto error_return;

View file

@ -2058,10 +2058,14 @@ elf32_rx_relax_section (bfd * abfd,
if (shndx_hdr && shndx_hdr->sh_size != 0) if (shndx_hdr && shndx_hdr->sh_size != 0)
{ {
bfd_size_type amt; size_t amt;
amt = symtab_hdr->sh_info; if (_bfd_mul_overflow (symtab_hdr->sh_info,
amt *= sizeof (Elf_External_Sym_Shndx); sizeof (Elf_External_Sym_Shndx), &amt))
{
bfd_set_error (bfd_error_file_too_big);
goto error_return;
}
shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt); shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
if (shndx_buf == NULL) if (shndx_buf == NULL)
goto error_return; goto error_return;

View file

@ -1387,18 +1387,24 @@ elf64_alpha_read_ecoff_info (bfd *abfd, asection *section,
/* The symbolic header contains absolute file offsets and sizes to /* The symbolic header contains absolute file offsets and sizes to
read. */ read. */
#define READ(ptr, offset, count, size, type) \ #define READ(ptr, offset, count, size, type) \
if (symhdr->count == 0) \ do \
debug->ptr = NULL; \
else \
{ \ { \
bfd_size_type amt = (bfd_size_type) size * symhdr->count; \ size_t amt; \
debug->ptr = NULL; \
if (symhdr->count == 0) \
break; \
if (_bfd_mul_overflow (size, symhdr->count, &amt)) \
{ \
bfd_set_error (bfd_error_file_too_big); \
goto error_return; \
} \
debug->ptr = (type) bfd_malloc (amt); \ debug->ptr = (type) bfd_malloc (amt); \
if (debug->ptr == NULL) \ if (debug->ptr == NULL) \
goto error_return; \ goto error_return; \
if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
|| bfd_bread (debug->ptr, amt, abfd) != amt) \ || bfd_bread (debug->ptr, amt, abfd) != amt) \
goto error_return; \ goto error_return; \
} } while (0)
READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *); READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);

View file

@ -687,19 +687,18 @@ elf_object_p (bfd *abfd)
{ {
Elf_Internal_Shdr *shdrp; Elf_Internal_Shdr *shdrp;
unsigned int num_sec; unsigned int num_sec;
size_t amt;
#ifndef BFD64 if (_bfd_mul_overflow (i_ehdrp->e_shnum, sizeof (*i_shdrp), &amt))
if (i_ehdrp->e_shnum > ((bfd_size_type) -1) / sizeof (*i_shdrp))
goto got_wrong_format_error; goto got_wrong_format_error;
#endif i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
i_shdrp = (Elf_Internal_Shdr *) bfd_alloc2 (abfd, i_ehdrp->e_shnum,
sizeof (*i_shdrp));
if (!i_shdrp) if (!i_shdrp)
goto got_no_match; goto got_no_match;
num_sec = i_ehdrp->e_shnum; num_sec = i_ehdrp->e_shnum;
elf_numsections (abfd) = num_sec; elf_numsections (abfd) = num_sec;
elf_elfsections (abfd) if (_bfd_mul_overflow (num_sec, sizeof (i_shdrp), &amt))
= (Elf_Internal_Shdr **) bfd_alloc2 (abfd, num_sec, sizeof (i_shdrp)); goto got_wrong_format_error;
elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt);
if (!elf_elfsections (abfd)) if (!elf_elfsections (abfd))
goto got_no_match; goto got_no_match;
@ -781,20 +780,18 @@ elf_object_p (bfd *abfd)
Elf_Internal_Phdr *i_phdr; Elf_Internal_Phdr *i_phdr;
unsigned int i; unsigned int i;
ufile_ptr filesize; ufile_ptr filesize;
size_t amt;
#ifndef BFD64
if (i_ehdrp->e_phnum > ((bfd_size_type) -1) / sizeof (*i_phdr))
goto got_wrong_format_error;
#endif
/* Check for a corrupt input file with an impossibly large number /* Check for a corrupt input file with an impossibly large number
of program headers. */ of program headers. */
filesize = bfd_get_file_size (abfd); filesize = bfd_get_file_size (abfd);
if (filesize != 0 if (filesize != 0
&& i_ehdrp->e_phnum > filesize / sizeof (Elf_External_Phdr)) && i_ehdrp->e_phnum > filesize / sizeof (Elf_External_Phdr))
goto got_wrong_format_error; goto got_wrong_format_error;
if (_bfd_mul_overflow (i_ehdrp->e_phnum, sizeof (*i_phdr), &amt))
goto got_wrong_format_error;
elf_tdata (abfd)->phdr elf_tdata (abfd)->phdr
= (Elf_Internal_Phdr *) bfd_alloc2 (abfd, i_ehdrp->e_phnum, = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
sizeof (*i_phdr));
if (elf_tdata (abfd)->phdr == NULL) if (elf_tdata (abfd)->phdr == NULL)
goto got_no_match; goto got_no_match;
if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0) if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
@ -881,6 +878,7 @@ elf_write_relocs (bfd *abfd, asection *sec, void *data)
unsigned int idx; unsigned int idx;
asymbol *last_sym; asymbol *last_sym;
int last_sym_idx; int last_sym_idx;
size_t amt;
/* If we have already failed, don't do anything. */ /* If we have already failed, don't do anything. */
if (*failedp) if (*failedp)
@ -907,10 +905,10 @@ elf_write_relocs (bfd *abfd, asection *sec, void *data)
rela_hdr = elf_section_data (sec)->rel.hdr; rela_hdr = elf_section_data (sec)->rel.hdr;
rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count; rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
rela_hdr->contents = (unsigned char *) bfd_alloc2 (abfd, sec->reloc_count, if (_bfd_mul_overflow (sec->reloc_count, rela_hdr->sh_entsize, &amt)
rela_hdr->sh_entsize); || (rela_hdr->contents = bfd_alloc (abfd, amt)) == NULL)
if (rela_hdr->contents == NULL)
{ {
bfd_set_error (bfd_error_no_memory);
*failedp = TRUE; *failedp = TRUE;
return; return;
} }
@ -1019,7 +1017,7 @@ elf_write_shdrs_and_ehdr (bfd *abfd)
Elf_External_Shdr *x_shdrp; /* Section header table, external form */ Elf_External_Shdr *x_shdrp; /* Section header table, external form */
Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */
unsigned int count; unsigned int count;
bfd_size_type amt; size_t amt;
i_ehdrp = elf_elfheader (abfd); i_ehdrp = elf_elfheader (abfd);
i_shdrp = elf_elfsections (abfd); i_shdrp = elf_elfsections (abfd);
@ -1045,8 +1043,12 @@ elf_write_shdrs_and_ehdr (bfd *abfd)
i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx; i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx;
/* at this point we've concocted all the ELF sections... */ /* at this point we've concocted all the ELF sections... */
x_shdrp = (Elf_External_Shdr *) bfd_alloc2 (abfd, i_ehdrp->e_shnum, if (_bfd_mul_overflow (i_ehdrp->e_shnum, sizeof (*x_shdrp), &amt))
sizeof (*x_shdrp)); {
bfd_set_error (bfd_error_no_memory);
return FALSE;
}
x_shdrp = (Elf_External_Shdr *) bfd_alloc (abfd, amt);
if (!x_shdrp) if (!x_shdrp)
return FALSE; return FALSE;
@ -1157,6 +1159,7 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
Elf_External_Versym *xver; Elf_External_Versym *xver;
Elf_External_Versym *xverbuf = NULL; Elf_External_Versym *xverbuf = NULL;
const struct elf_backend_data *ebd; const struct elf_backend_data *ebd;
size_t amt;
/* Read each raw ELF symbol, converting from external ELF form to /* Read each raw ELF symbol, converting from external ELF form to
internal ELF form, and then using the information to create a internal ELF form, and then using the information to create a
@ -1201,8 +1204,12 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
if (isymbuf == NULL) if (isymbuf == NULL)
return -1; return -1;
symbase = (elf_symbol_type *) bfd_zalloc2 (abfd, symcount, if (_bfd_mul_overflow (symcount, sizeof (elf_symbol_type), &amt))
sizeof (elf_symbol_type)); {
bfd_set_error (bfd_error_file_too_big);
goto error_return;
}
symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt);
if (symbase == (elf_symbol_type *) NULL) if (symbase == (elf_symbol_type *) NULL)
goto error_return; goto error_return;
@ -1522,6 +1529,7 @@ elf_slurp_reloc_table (bfd *abfd,
bfd_size_type reloc_count; bfd_size_type reloc_count;
bfd_size_type reloc_count2; bfd_size_type reloc_count2;
arelent *relents; arelent *relents;
size_t amt;
if (asect->relocation != NULL) if (asect->relocation != NULL)
return TRUE; return TRUE;
@ -1559,8 +1567,12 @@ elf_slurp_reloc_table (bfd *abfd,
reloc_count2 = 0; reloc_count2 = 0;
} }
relents = (arelent *) bfd_alloc2 (abfd, reloc_count + reloc_count2, if (_bfd_mul_overflow (reloc_count + reloc_count2, sizeof (arelent), &amt))
sizeof (arelent)); {
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
relents = (arelent *) bfd_alloc (abfd, amt);
if (relents == NULL) if (relents == NULL)
return FALSE; return FALSE;
@ -1660,6 +1672,7 @@ NAME(_bfd_elf,bfd_from_remote_memory)
bfd_vma shdr_end; bfd_vma shdr_end;
bfd_vma loadbase; bfd_vma loadbase;
char *filename; char *filename;
size_t amt;
/* Read in the ELF header in external format. */ /* Read in the ELF header in external format. */
err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr); err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
@ -1716,9 +1729,13 @@ NAME(_bfd_elf,bfd_from_remote_memory)
return NULL; return NULL;
} }
x_phdrs if (_bfd_mul_overflow (i_ehdr.e_phnum,
= (Elf_External_Phdr *) bfd_malloc2 (i_ehdr.e_phnum, sizeof (*x_phdrs) + sizeof (*i_phdrs), &amt))
sizeof (*x_phdrs) + sizeof (*i_phdrs)); {
bfd_set_error (bfd_error_file_too_big);
return NULL;
}
x_phdrs = (Elf_External_Phdr *) bfd_malloc (amt);
if (x_phdrs == NULL) if (x_phdrs == NULL)
return NULL; return NULL;
err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs, err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs,

View file

@ -335,6 +335,7 @@ NAME(_bfd_elf, core_find_build_id)
Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form. */ Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form. */
Elf_Internal_Phdr *i_phdr; Elf_Internal_Phdr *i_phdr;
unsigned int i; unsigned int i;
size_t amt;
/* Seek to the position of the segment at OFFSET. */ /* Seek to the position of the segment at OFFSET. */
if (bfd_seek (abfd, offset, SEEK_SET) != 0) if (bfd_seek (abfd, offset, SEEK_SET) != 0)
@ -384,8 +385,12 @@ NAME(_bfd_elf, core_find_build_id)
goto fail; goto fail;
/* Read in program headers. */ /* Read in program headers. */
i_phdr = (Elf_Internal_Phdr *) bfd_alloc2 (abfd, i_ehdr.e_phnum, if (_bfd_mul_overflow (i_ehdr.e_phnum, sizeof (*i_phdr), &amt))
sizeof (*i_phdr)); {
bfd_set_error (bfd_error_file_too_big);
goto fail;
}
i_phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
if (i_phdr == NULL) if (i_phdr == NULL)
goto fail; goto fail;

View file

@ -1413,18 +1413,24 @@ _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section,
/* The symbolic header contains absolute file offsets and sizes to /* The symbolic header contains absolute file offsets and sizes to
read. */ read. */
#define READ(ptr, offset, count, size, type) \ #define READ(ptr, offset, count, size, type) \
if (symhdr->count == 0) \ do \
debug->ptr = NULL; \
else \
{ \ { \
bfd_size_type amt = (bfd_size_type) size * symhdr->count; \ size_t amt; \
debug->ptr = NULL; \
if (symhdr->count == 0) \
break; \
if (_bfd_mul_overflow (size, symhdr->count, &amt)) \
{ \
bfd_set_error (bfd_error_file_too_big); \
goto error_return; \
} \
debug->ptr = bfd_malloc (amt); \ debug->ptr = bfd_malloc (amt); \
if (debug->ptr == NULL) \ if (debug->ptr == NULL) \
goto error_return; \ goto error_return; \
if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0 \ if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0 \
|| bfd_bread (debug->ptr, amt, abfd) != amt) \ || bfd_bread (debug->ptr, amt, abfd) != amt) \
goto error_return; \ goto error_return; \
} } while (0)
READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *); READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);

View file

@ -116,12 +116,6 @@ extern void *bfd_realloc_or_free
(void *, bfd_size_type) ATTRIBUTE_HIDDEN; (void *, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_zmalloc extern void *bfd_zmalloc
(bfd_size_type) ATTRIBUTE_HIDDEN; (bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_malloc2
(bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_realloc2
(void *, bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_zmalloc2
(bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
static inline char * static inline char *
bfd_strdup (const char *str) bfd_strdup (const char *str)
@ -134,10 +128,6 @@ bfd_strdup (const char *str)
} }
/* These routines allocate and free things on the BFD's objalloc. */ /* These routines allocate and free things on the BFD's objalloc. */
extern void *bfd_alloc2
(bfd *, bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_zalloc2
(bfd *, bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void bfd_release extern void bfd_release
(bfd *, void *) ATTRIBUTE_HIDDEN; (bfd *, void *) ATTRIBUTE_HIDDEN;
@ -905,3 +895,11 @@ extern bfd_signed_vma _bfd_read_signed_leb128
extern bfd_vma _bfd_safe_read_leb128 extern bfd_vma _bfd_safe_read_leb128
(bfd *, bfd_byte *, unsigned int *, bfd_boolean, const bfd_byte * const) (bfd *, bfd_byte *, unsigned int *, bfd_boolean, const bfd_byte * const)
ATTRIBUTE_HIDDEN; ATTRIBUTE_HIDDEN;
#if GCC_VERSION >= 7000
#define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
#else
/* Assumes unsigned values. Careful! Args evaluated multiple times. */
#define _bfd_mul_overflow(a, b, res) \
((*res) = (a), (*res) *= (b), (b) != 0 && (*res) / (b) != (a))
#endif

View file

@ -279,24 +279,6 @@ bfd_malloc (bfd_size_type size)
return ptr; return ptr;
} }
/* Allocate memory using malloc, nmemb * size with overflow checking. */
void *
bfd_malloc2 (bfd_size_type nmemb, bfd_size_type size)
{
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
return bfd_malloc (size * nmemb);
}
/* Reallocate memory using realloc. */
void * void *
bfd_realloc (void *ptr, bfd_size_type size) bfd_realloc (void *ptr, bfd_size_type size)
{ {
@ -322,22 +304,6 @@ bfd_realloc (void *ptr, bfd_size_type size)
return ret; return ret;
} }
/* Reallocate memory using realloc, nmemb * size with overflow checking. */
void *
bfd_realloc2 (void *ptr, bfd_size_type nmemb, bfd_size_type size)
{
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
return bfd_realloc (ptr, size * nmemb);
}
/* Reallocate memory using realloc. /* Reallocate memory using realloc.
If this fails the pointer is freed before returning. */ If this fails the pointer is freed before returning. */
@ -365,25 +331,6 @@ bfd_zmalloc (bfd_size_type size)
return ptr; return ptr;
} }
/* Allocate memory using malloc (nmemb * size) with overflow checking
and clear it. */
void *
bfd_zmalloc2 (bfd_size_type nmemb, bfd_size_type size)
{
void *ptr = bfd_malloc2 (nmemb, size);
if (ptr != NULL)
{
size_t sz = nmemb * size;
if (sz > 0)
memset (ptr, 0, sz);
}
return ptr;
}
/* /*
INTERNAL_FUNCTION INTERNAL_FUNCTION
bfd_write_bigendian_4byte_int bfd_write_bigendian_4byte_int

View file

@ -121,12 +121,6 @@ extern void *bfd_realloc_or_free
(void *, bfd_size_type) ATTRIBUTE_HIDDEN; (void *, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_zmalloc extern void *bfd_zmalloc
(bfd_size_type) ATTRIBUTE_HIDDEN; (bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_malloc2
(bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_realloc2
(void *, bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_zmalloc2
(bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
static inline char * static inline char *
bfd_strdup (const char *str) bfd_strdup (const char *str)
@ -139,10 +133,6 @@ bfd_strdup (const char *str)
} }
/* These routines allocate and free things on the BFD's objalloc. */ /* These routines allocate and free things on the BFD's objalloc. */
extern void *bfd_alloc2
(bfd *, bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void *bfd_zalloc2
(bfd *, bfd_size_type, bfd_size_type) ATTRIBUTE_HIDDEN;
extern void bfd_release extern void bfd_release
(bfd *, void *) ATTRIBUTE_HIDDEN; (bfd *, void *) ATTRIBUTE_HIDDEN;
@ -910,6 +900,14 @@ extern bfd_signed_vma _bfd_read_signed_leb128
extern bfd_vma _bfd_safe_read_leb128 extern bfd_vma _bfd_safe_read_leb128
(bfd *, bfd_byte *, unsigned int *, bfd_boolean, const bfd_byte * const) (bfd *, bfd_byte *, unsigned int *, bfd_boolean, const bfd_byte * const)
ATTRIBUTE_HIDDEN; ATTRIBUTE_HIDDEN;
#if GCC_VERSION >= 7000
#define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
#else
/* Assumes unsigned values. Careful! Args evaluated multiple times. */
#define _bfd_mul_overflow(a, b, res) \
((*res) = (a), (*res) *= (b), (b) != 0 && (*res) / (b) != (a))
#endif
/* Extracted from libbfd.c. */ /* Extracted from libbfd.c. */
bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int); bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);

View file

@ -2554,6 +2554,7 @@ bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
asection *sec; asection *sec;
unsigned target_index; unsigned target_index;
unsigned nsect; unsigned nsect;
size_t amt;
nsect = bfd_count_sections (abfd); nsect = bfd_count_sections (abfd);
@ -2572,8 +2573,12 @@ bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
} }
mdata->nsects = nsect; mdata->nsects = nsect;
mdata->sections = bfd_alloc2 (abfd, if (_bfd_mul_overflow (mdata->nsects, sizeof (bfd_mach_o_section *), &amt))
mdata->nsects, sizeof (bfd_mach_o_section *)); {
bfd_set_error (bfd_error_no_memory);
return FALSE;
}
mdata->sections = bfd_alloc (abfd, amt);
if (mdata->sections == NULL) if (mdata->sections == NULL)
return FALSE; return FALSE;
@ -3923,14 +3928,16 @@ bfd_mach_o_read_symtab_symbols (bfd *abfd)
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
bfd_mach_o_symtab_command *sym = mdata->symtab; bfd_mach_o_symtab_command *sym = mdata->symtab;
unsigned long i; unsigned long i;
size_t amt;
if (sym == NULL || sym->symbols) if (sym == NULL || sym->symbols)
/* Return now if there are no symbols or if already loaded. */ /* Return now if there are no symbols or if already loaded. */
return TRUE; return TRUE;
sym->symbols = bfd_alloc2 (abfd, sym->nsyms, sizeof (bfd_mach_o_asymbol)); if (_bfd_mul_overflow (sym->nsyms, sizeof (bfd_mach_o_asymbol), &amt)
if (sym->symbols == NULL) || (sym->symbols = bfd_alloc (abfd, amt)) == NULL)
{ {
bfd_set_error (bfd_error_no_memory);
_bfd_error_handler (_("bfd_mach_o_read_symtab_symbols: " _bfd_error_handler (_("bfd_mach_o_read_symtab_symbols: "
"unable to allocate memory for symbols")); "unable to allocate memory for symbols"));
sym->nsyms = 0; sym->nsyms = 0;
@ -4174,6 +4181,7 @@ bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
unsigned int nflavours; unsigned int nflavours;
unsigned int i; unsigned int i;
struct mach_o_thread_command_external raw; struct mach_o_thread_command_external raw;
size_t amt;
BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD) BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
|| (command->type == BFD_MACH_O_LC_UNIXTHREAD)); || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
@ -4200,8 +4208,12 @@ bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
return FALSE; return FALSE;
/* Allocate threads. */ /* Allocate threads. */
cmd->flavours = bfd_alloc2 (abfd, nflavours, if (_bfd_mul_overflow (nflavours, sizeof (bfd_mach_o_thread_flavour), &amt))
sizeof (bfd_mach_o_thread_flavour)); {
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
cmd->flavours = bfd_alloc (abfd, amt);
if (cmd->flavours == NULL) if (cmd->flavours == NULL)
return FALSE; return FALSE;
cmd->nflavours = nflavours; cmd->nflavours = nflavours;
@ -4315,9 +4327,15 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
unsigned int i; unsigned int i;
int wide = bfd_mach_o_wide_p (abfd); int wide = bfd_mach_o_wide_p (abfd);
unsigned int module_len = wide ? 56 : 52; unsigned int module_len = wide ? 56 : 52;
size_t amt;
cmd->dylib_module = if (_bfd_mul_overflow (cmd->nmodtab,
bfd_alloc2 (abfd, cmd->nmodtab, sizeof (bfd_mach_o_dylib_module)); sizeof (bfd_mach_o_dylib_module), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
cmd->dylib_module = bfd_alloc (abfd, amt);
if (cmd->dylib_module == NULL) if (cmd->dylib_module == NULL)
return FALSE; return FALSE;
@ -4364,9 +4382,15 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
if (cmd->ntoc != 0) if (cmd->ntoc != 0)
{ {
unsigned long i; unsigned long i;
size_t amt;
cmd->dylib_toc = bfd_alloc2 if (_bfd_mul_overflow (cmd->ntoc,
(abfd, cmd->ntoc, sizeof (bfd_mach_o_dylib_table_of_content)); sizeof (bfd_mach_o_dylib_table_of_content), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
cmd->dylib_toc = bfd_alloc (abfd, amt);
if (cmd->dylib_toc == NULL) if (cmd->dylib_toc == NULL)
return FALSE; return FALSE;
@ -4389,9 +4413,14 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
if (cmd->nindirectsyms != 0) if (cmd->nindirectsyms != 0)
{ {
unsigned int i; unsigned int i;
size_t amt;
cmd->indirect_syms = bfd_alloc2 if (_bfd_mul_overflow (cmd->nindirectsyms, sizeof (unsigned int), &amt))
(abfd, cmd->nindirectsyms, sizeof (unsigned int)); {
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
cmd->indirect_syms = bfd_alloc (abfd, amt);
if (cmd->indirect_syms == NULL) if (cmd->indirect_syms == NULL)
return FALSE; return FALSE;
@ -4414,9 +4443,15 @@ bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
{ {
unsigned long v; unsigned long v;
unsigned int i; unsigned int i;
size_t amt;
cmd->ext_refs = bfd_alloc2 if (_bfd_mul_overflow (cmd->nextrefsyms,
(abfd, cmd->nextrefsyms, sizeof (bfd_mach_o_dylib_reference)); sizeof (bfd_mach_o_dylib_reference), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
cmd->ext_refs = bfd_alloc (abfd, amt);
if (cmd->ext_refs == NULL) if (cmd->ext_refs == NULL)
return FALSE; return FALSE;
@ -5005,6 +5040,7 @@ bfd_mach_o_flatten_sections (bfd *abfd)
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
bfd_mach_o_load_command *cmd; bfd_mach_o_load_command *cmd;
long csect = 0; long csect = 0;
size_t amt;
/* Count total number of sections. */ /* Count total number of sections. */
mdata->nsects = 0; mdata->nsects = 0;
@ -5021,8 +5057,12 @@ bfd_mach_o_flatten_sections (bfd *abfd)
} }
/* Allocate sections array. */ /* Allocate sections array. */
mdata->sections = bfd_alloc2 (abfd, if (_bfd_mul_overflow (mdata->nsects, sizeof (bfd_mach_o_section *), &amt))
mdata->nsects, sizeof (bfd_mach_o_section *)); {
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
mdata->sections = bfd_alloc (abfd, amt);
if (mdata->sections == NULL && mdata->nsects != 0) if (mdata->sections == NULL && mdata->nsects != 0)
return FALSE; return FALSE;
@ -5195,11 +5235,18 @@ bfd_mach_o_scan (bfd *abfd,
if (header->ncmds != 0) if (header->ncmds != 0)
{ {
bfd_mach_o_load_command *cmd; bfd_mach_o_load_command *cmd;
size_t amt;
mdata->first_command = NULL; mdata->first_command = NULL;
mdata->last_command = NULL; mdata->last_command = NULL;
cmd = bfd_alloc2 (abfd, header->ncmds, sizeof (bfd_mach_o_load_command)); if (_bfd_mul_overflow (header->ncmds,
sizeof (bfd_mach_o_load_command), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
cmd = bfd_alloc (abfd, amt);
if (cmd == NULL) if (cmd == NULL)
return FALSE; return FALSE;
@ -5418,6 +5465,7 @@ bfd_mach_o_fat_archive_p (bfd *abfd)
mach_o_fat_data_struct *adata = NULL; mach_o_fat_data_struct *adata = NULL;
struct mach_o_fat_header_external hdr; struct mach_o_fat_header_external hdr;
unsigned long i; unsigned long i;
size_t amt;
if (bfd_seek (abfd, 0, SEEK_SET) != 0 if (bfd_seek (abfd, 0, SEEK_SET) != 0
|| bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr)) || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
@ -5437,8 +5485,13 @@ bfd_mach_o_fat_archive_p (bfd *abfd)
if (adata->nfat_arch > 30) if (adata->nfat_arch > 30)
goto error; goto error;
adata->archentries = if (_bfd_mul_overflow (adata->nfat_arch,
bfd_alloc2 (abfd, adata->nfat_arch, sizeof (mach_o_fat_archentry)); sizeof (mach_o_fat_archentry), &amt))
{
bfd_set_error (bfd_error_file_too_big);
goto error;
}
adata->archentries = bfd_alloc (abfd, amt);
if (adata->archentries == NULL) if (adata->archentries == NULL)
goto error; goto error;

View file

@ -981,32 +981,6 @@ bfd_alloc (bfd *abfd, bfd_size_type size)
return ret; return ret;
} }
/*
INTERNAL_FUNCTION
bfd_alloc2
SYNOPSIS
void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
DESCRIPTION
Allocate a block of @var{nmemb} elements of @var{size} bytes each
of memory attached to <<abfd>> and return a pointer to it.
*/
void *
bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
{
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
return bfd_alloc (abfd, size * nmemb);
}
/* /*
FUNCTION FUNCTION
bfd_zalloc bfd_zalloc
@ -1030,39 +1004,6 @@ bfd_zalloc (bfd *abfd, bfd_size_type size)
return res; return res;
} }
/*
INTERNAL_FUNCTION
bfd_zalloc2
SYNOPSIS
void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size);
DESCRIPTION
Allocate a block of @var{nmemb} elements of @var{size} bytes each
of zeroed memory attached to <<abfd>> and return a pointer to it.
*/
void *
bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size)
{
void *res;
if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
&& size != 0
&& nmemb > ~(bfd_size_type) 0 / size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
size *= nmemb;
res = bfd_alloc (abfd, size);
if (res)
memset (res, 0, (size_t) size);
return res;
}
/* Free a block allocated for a BFD. /* Free a block allocated for a BFD.
Note: Also frees all more recently allocated blocks! */ Note: Also frees all more recently allocated blocks! */

147
bfd/som.c
View file

@ -2079,17 +2079,17 @@ setup_sections (bfd *abfd,
unsigned int total_subspaces = 0; unsigned int total_subspaces = 0;
asection **subspace_sections = NULL; asection **subspace_sections = NULL;
asection *section; asection *section;
bfd_size_type amt; size_t amt;
/* First, read in space names. */ /* First, read in space names. */
amt = file_hdr->space_strings_size; amt = file_hdr->space_strings_size;
if (amt == (bfd_size_type) -1) if (amt == (size_t) -1)
{ {
bfd_set_error (bfd_error_no_memory); bfd_set_error (bfd_error_no_memory);
goto error_return; goto error_return;
} }
space_strings = bfd_malloc (amt + 1); space_strings = bfd_malloc (amt + 1);
if (space_strings == NULL && amt != 0) if (space_strings == NULL)
goto error_return; goto error_return;
if (bfd_seek (abfd, current_offset + file_hdr->space_strings_location, if (bfd_seek (abfd, current_offset + file_hdr->space_strings_location,
@ -2344,7 +2344,12 @@ setup_sections (bfd *abfd,
} }
/* Now that we've read in all the subspace records, we need to assign /* Now that we've read in all the subspace records, we need to assign
a target index to each subspace. */ a target index to each subspace. */
subspace_sections = bfd_malloc2 (total_subspaces, sizeof (asection *)); if (_bfd_mul_overflow (total_subspaces, sizeof (asection *), &amt))
{
bfd_set_error (bfd_error_file_too_big);
goto error_return;
}
subspace_sections = bfd_malloc (amt);
if (subspace_sections == NULL) if (subspace_sections == NULL)
goto error_return; goto error_return;
@ -2804,6 +2809,7 @@ som_prep_for_fixups (bfd *abfd, asymbol **syms, unsigned long num_syms)
unsigned long i; unsigned long i;
asection *section; asection *section;
asymbol **sorted_syms; asymbol **sorted_syms;
size_t amt;
/* Most SOM relocations involving a symbol have a length which is /* Most SOM relocations involving a symbol have a length which is
dependent on the index of the symbol. So symbols which are dependent on the index of the symbol. So symbols which are
@ -2875,7 +2881,12 @@ som_prep_for_fixups (bfd *abfd, asymbol **syms, unsigned long num_syms)
/* Sort a copy of the symbol table, rather than the canonical /* Sort a copy of the symbol table, rather than the canonical
output symbol table. */ output symbol table. */
sorted_syms = bfd_zalloc2 (abfd, num_syms, sizeof (asymbol *)); if (_bfd_mul_overflow (num_syms, sizeof (asymbol *), &amt))
{
bfd_set_error (bfd_error_no_memory);
return FALSE;
}
sorted_syms = bfd_zalloc (abfd, amt);
if (sorted_syms == NULL) if (sorted_syms == NULL)
return FALSE; return FALSE;
memcpy (sorted_syms, syms, num_syms * sizeof (asymbol *)); memcpy (sorted_syms, syms, num_syms * sizeof (asymbol *));
@ -4460,12 +4471,18 @@ som_build_and_write_symbol_table (bfd *abfd)
struct som_external_symbol_dictionary_record *som_symtab = NULL; struct som_external_symbol_dictionary_record *som_symtab = NULL;
unsigned int i; unsigned int i;
bfd_size_type symtab_size; bfd_size_type symtab_size;
size_t amt;
/* Compute total symbol table size and allocate a chunk of memory /* Compute total symbol table size and allocate a chunk of memory
to hold the symbol table as we build it. */ to hold the symbol table as we build it. */
som_symtab if (_bfd_mul_overflow (num_syms,
= bfd_zmalloc2 (num_syms, sizeof (struct som_external_symbol_dictionary_record),
sizeof (struct som_external_symbol_dictionary_record)); &amt))
{
bfd_set_error (bfd_error_no_memory);
return FALSE;
}
som_symtab = bfd_zmalloc (amt);
if (som_symtab == NULL && num_syms != 0) if (som_symtab == NULL && num_syms != 0)
goto error_return; goto error_return;
@ -4638,12 +4655,12 @@ bfd_section_from_som_symbol
static unsigned int static unsigned int
som_slurp_symbol_table (bfd *abfd) som_slurp_symbol_table (bfd *abfd)
{ {
int symbol_count = bfd_get_symcount (abfd); unsigned int symbol_count = bfd_get_symcount (abfd);
int symsize = sizeof (struct som_external_symbol_dictionary_record); size_t symsize = sizeof (struct som_external_symbol_dictionary_record);
char *stringtab; char *stringtab;
struct som_external_symbol_dictionary_record *buf = NULL, *bufp, *endbufp; struct som_external_symbol_dictionary_record *buf = NULL, *bufp, *endbufp;
som_symbol_type *sym, *symbase; som_symbol_type *sym, *symbase;
bfd_size_type amt; size_t amt;
/* Return saved value if it exists. */ /* Return saved value if it exists. */
if (obj_som_symtab (abfd) != NULL) if (obj_som_symtab (abfd) != NULL)
@ -4658,18 +4675,26 @@ som_slurp_symbol_table (bfd *abfd)
stringtab = obj_som_stringtab (abfd); stringtab = obj_som_stringtab (abfd);
symbase = bfd_zmalloc2 (symbol_count, sizeof (som_symbol_type)); 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) if (symbase == NULL)
goto error_return; goto error_return;
/* Read in the external SOM representation. */ /* Read in the external SOM representation. */
buf = bfd_malloc2 (symbol_count, symsize); if (_bfd_mul_overflow (symbol_count, symsize, &amt))
{
bfd_set_error (bfd_error_file_too_big);
goto error_return;
}
buf = bfd_malloc (amt);
if (buf == NULL) if (buf == NULL)
goto error_return; goto error_return;
if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) != 0) if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) != 0)
goto error_return; goto error_return;
amt = symbol_count;
amt *= symsize;
if (bfd_bread (buf, amt, abfd) != amt) if (bfd_bread (buf, amt, abfd) != amt)
goto error_return; goto error_return;
@ -5259,7 +5284,7 @@ som_slurp_reloc_table (bfd *abfd,
unsigned int fixup_stream_size; unsigned int fixup_stream_size;
arelent *internal_relocs; arelent *internal_relocs;
unsigned int num_relocs; unsigned int num_relocs;
bfd_size_type amt; size_t amt;
fixup_stream_size = som_section_data (section)->reloc_size; fixup_stream_size = som_section_data (section)->reloc_size;
/* If there were no relocations, then there is nothing to do. */ /* If there were no relocations, then there is nothing to do. */
@ -5303,7 +5328,12 @@ som_slurp_reloc_table (bfd *abfd,
if (section->relocation != NULL) if (section->relocation != NULL)
return TRUE; return TRUE;
internal_relocs = bfd_zalloc2 (abfd, num_relocs, sizeof (arelent)); if (_bfd_mul_overflow (num_relocs, sizeof (arelent), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
internal_relocs = bfd_zalloc (abfd, amt);
if (internal_relocs == NULL) if (internal_relocs == NULL)
return FALSE; return FALSE;
@ -5884,12 +5914,17 @@ som_bfd_count_ar_symbols (bfd *abfd,
{ {
unsigned int i; unsigned int i;
unsigned char *hash_table; unsigned char *hash_table;
bfd_size_type amt; size_t amt;
file_ptr lst_filepos; file_ptr lst_filepos;
lst_filepos = bfd_tell (abfd) - sizeof (struct som_external_lst_header); lst_filepos = bfd_tell (abfd) - sizeof (struct som_external_lst_header);
hash_table = bfd_malloc2 (lst_header->hash_size, 4); if (_bfd_mul_overflow (lst_header->hash_size, 4, &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
hash_table = bfd_malloc (amt);
if (hash_table == NULL && lst_header->hash_size != 0) if (hash_table == NULL && lst_header->hash_size != 0)
goto error_return; goto error_return;
@ -5898,7 +5933,6 @@ som_bfd_count_ar_symbols (bfd *abfd,
/* Read in the hash table. The hash table is an array of 32-bit /* Read in the hash table. The hash table is an array of 32-bit
file offsets which point to the hash chains. */ file offsets which point to the hash chains. */
amt = (bfd_size_type) lst_header->hash_size * 4;
if (bfd_bread ((void *) hash_table, amt, abfd) != amt) if (bfd_bread ((void *) hash_table, amt, abfd) != amt)
goto error_return; goto error_return;
@ -5975,18 +6009,22 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
carsym *set = syms[0]; carsym *set = syms[0];
unsigned char *hash_table; unsigned char *hash_table;
struct som_external_som_entry *som_dict = NULL; struct som_external_som_entry *som_dict = NULL;
bfd_size_type amt; size_t amt;
file_ptr lst_filepos; file_ptr lst_filepos;
unsigned int string_loc; unsigned int string_loc;
lst_filepos = bfd_tell (abfd) - sizeof (struct som_external_lst_header); lst_filepos = bfd_tell (abfd) - sizeof (struct som_external_lst_header);
hash_table = bfd_malloc2 (lst_header->hash_size, 4); if (_bfd_mul_overflow (lst_header->hash_size, 4, &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
hash_table = bfd_malloc (amt);
if (hash_table == NULL && lst_header->hash_size != 0) if (hash_table == NULL && lst_header->hash_size != 0)
goto error_return; goto error_return;
/* Read in the hash table. The has table is an array of 32bit file offsets /* Read in the hash table. The has table is an array of 32bit file offsets
which point to the hash chains. */ which point to the hash chains. */
amt = (bfd_size_type) lst_header->hash_size * 4;
if (bfd_bread ((void *) hash_table, amt, abfd) != amt) if (bfd_bread ((void *) hash_table, amt, abfd) != amt)
goto error_return; goto error_return;
@ -5995,13 +6033,16 @@ som_bfd_fill_in_ar_symbols (bfd *abfd,
if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) != 0) if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) != 0)
goto error_return; goto error_return;
som_dict = bfd_malloc2 (lst_header->module_count, if (_bfd_mul_overflow (lst_header->module_count,
sizeof (struct som_external_som_entry)); sizeof (struct som_external_som_entry), &amt))
{
bfd_set_error (bfd_error_file_too_big);
goto error_return;
}
som_dict = bfd_malloc (amt);
if (som_dict == NULL && lst_header->module_count != 0) if (som_dict == NULL && lst_header->module_count != 0)
goto error_return; goto error_return;
amt = lst_header->module_count;
amt *= sizeof (struct som_external_som_entry);
if (bfd_bread ((void *) som_dict, amt, abfd) != amt) if (bfd_bread ((void *) som_dict, amt, abfd) != amt)
goto error_return; goto error_return;
@ -6156,7 +6197,7 @@ som_slurp_armap (bfd *abfd)
unsigned int parsed_size; unsigned int parsed_size;
struct artdata *ardata = bfd_ardata (abfd); struct artdata *ardata = bfd_ardata (abfd);
char nextname[17]; char nextname[17];
bfd_size_type amt = 16; size_t amt = 16;
int i = bfd_bread ((void *) nextname, amt, abfd); int i = bfd_bread ((void *) nextname, amt, abfd);
/* Special cases. */ /* Special cases. */
@ -6225,7 +6266,12 @@ som_slurp_armap (bfd *abfd)
/* Initialize the cache and allocate space for the library symbols. */ /* Initialize the cache and allocate space for the library symbols. */
ardata->cache = 0; ardata->cache = 0;
ardata->symdefs = bfd_alloc2 (abfd, ardata->symdef_count, sizeof (carsym)); if (_bfd_mul_overflow (ardata->symdef_count, sizeof (carsym), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
ardata->symdefs = bfd_alloc (abfd, amt);
if (!ardata->symdefs) if (!ardata->symdefs)
return FALSE; return FALSE;
@ -6352,22 +6398,39 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd,
struct som_external_som_entry *som_dict = NULL; struct som_external_som_entry *som_dict = NULL;
struct som_external_lst_symbol_record **last_hash_entry = NULL; struct som_external_lst_symbol_record **last_hash_entry = NULL;
unsigned int curr_som_offset, som_index = 0; unsigned int curr_som_offset, som_index = 0;
bfd_size_type amt; size_t amt;
unsigned int module_count; unsigned int module_count;
unsigned int hash_size; unsigned int hash_size;
hash_size = bfd_getb32 (lst.hash_size); hash_size = bfd_getb32 (lst.hash_size);
hash_table = bfd_zmalloc2 (hash_size, 4); if (_bfd_mul_overflow (hash_size, 4, &amt))
{
bfd_set_error (bfd_error_no_memory);
return FALSE;
}
hash_table = bfd_zmalloc (amt);
if (hash_table == NULL && hash_size != 0) if (hash_table == NULL && hash_size != 0)
goto error_return; goto error_return;
module_count = bfd_getb32 (lst.module_count); module_count = bfd_getb32 (lst.module_count);
som_dict = bfd_zmalloc2 (module_count, sizeof (struct som_external_som_entry)); if (_bfd_mul_overflow (module_count,
sizeof (struct som_external_som_entry), &amt))
{
bfd_set_error (bfd_error_no_memory);
goto error_return;
}
som_dict = bfd_zmalloc (amt);
if (som_dict == NULL && module_count != 0) if (som_dict == NULL && module_count != 0)
goto error_return; goto error_return;
last_hash_entry if (_bfd_mul_overflow (hash_size,
= bfd_zmalloc2 (hash_size, sizeof (struct som_external_lst_symbol_record *)); sizeof (struct som_external_lst_symbol_record *),
&amt))
{
bfd_set_error (bfd_error_no_memory);
goto error_return;
}
last_hash_entry = bfd_zmalloc (amt);
if (last_hash_entry == NULL && hash_size != 0) if (last_hash_entry == NULL && hash_size != 0)
goto error_return; goto error_return;
@ -6395,10 +6458,16 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd,
curr_som_offset = (curr_som_offset + 0x1) & ~0x1; curr_som_offset = (curr_som_offset + 0x1) & ~0x1;
/* FIXME should be done with buffers just like everything else... */ /* FIXME should be done with buffers just like everything else... */
lst_syms = bfd_malloc2 (nsyms, sizeof (struct som_external_lst_symbol_record)); if (_bfd_mul_overflow (nsyms,
sizeof (struct som_external_lst_symbol_record), &amt))
{
bfd_set_error (bfd_error_no_memory);
goto error_return;
}
lst_syms = bfd_malloc (amt);
if (lst_syms == NULL && nsyms != 0) if (lst_syms == NULL && nsyms != 0)
goto error_return; goto error_return;
strings = bfd_malloc ((bfd_size_type) string_size); strings = bfd_malloc (string_size);
if (strings == NULL && string_size != 0) if (strings == NULL && string_size != 0)
goto error_return; goto error_return;
@ -6543,17 +6612,17 @@ som_bfd_ar_write_symbol_stuff (bfd *abfd,
} }
/* Now scribble out the hash table. */ /* Now scribble out the hash table. */
amt = (bfd_size_type) hash_size * 4; amt = (size_t) hash_size * 4;
if (bfd_bwrite ((void *) hash_table, amt, abfd) != amt) if (bfd_bwrite ((void *) hash_table, amt, abfd) != amt)
goto error_return; goto error_return;
/* Then the SOM dictionary. */ /* Then the SOM dictionary. */
amt = (bfd_size_type) module_count * sizeof (struct som_external_som_entry); amt = (size_t) module_count * sizeof (struct som_external_som_entry);
if (bfd_bwrite ((void *) som_dict, amt, abfd) != amt) if (bfd_bwrite ((void *) som_dict, amt, abfd) != amt)
goto error_return; goto error_return;
/* The library symbols. */ /* The library symbols. */
amt = (bfd_size_type) nsyms * sizeof (struct som_external_lst_symbol_record); amt = (size_t) nsyms * sizeof (struct som_external_lst_symbol_record);
if (bfd_bwrite ((void *) lst_syms, amt, abfd) != amt) if (bfd_bwrite ((void *) lst_syms, amt, abfd) != amt)
goto error_return; goto error_return;

View file

@ -2963,17 +2963,23 @@ vector_grow1 (struct vector_type *vec, size_t elsz)
if (vec->max_el == 0) if (vec->max_el == 0)
{ {
vec->max_el = 16; vec->max_el = 16;
vec->els = bfd_malloc2 (vec->max_el, elsz); vec->els = bfd_malloc (vec->max_el * elsz);
} }
else else
{ {
size_t amt;
if (vec->max_el > -1u / 2) if (vec->max_el > -1u / 2)
{ {
bfd_set_error (bfd_error_file_too_big); bfd_set_error (bfd_error_file_too_big);
return NULL; return NULL;
} }
vec->max_el *= 2; vec->max_el *= 2;
vec->els = bfd_realloc2 (vec->els, vec->max_el, elsz); if (_bfd_mul_overflow (vec->max_el, elsz, &amt))
{
bfd_set_error (bfd_error_file_too_big);
return NULL;
}
vec->els = bfd_realloc (vec->els, amt);
} }
} }
if (vec->els == NULL) if (vec->els == NULL)

View file

@ -134,12 +134,23 @@ vms_add_index (struct carsym_mem *cs, char *name,
if (cs->nbr == cs->max) if (cs->nbr == cs->max)
{ {
struct carsym *n; struct carsym *n;
size_t amt;
if (cs->max > -33u / 2)
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
cs->max = 2 * cs->max + 32; cs->max = 2 * cs->max + 32;
if (_bfd_mul_overflow (cs->max, sizeof (struct carsym), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
if (!cs->realloced) if (!cs->realloced)
{ {
n = bfd_malloc2 (cs->max, sizeof (struct carsym)); n = bfd_malloc (amt);
if (n == NULL) if (n == NULL)
return FALSE; return FALSE;
memcpy (n, cs->idx, cs->nbr * sizeof (struct carsym)); memcpy (n, cs->idx, cs->nbr * sizeof (struct carsym));
@ -147,7 +158,7 @@ vms_add_index (struct carsym_mem *cs, char *name,
} }
else else
{ {
n = bfd_realloc_or_free (cs->idx, cs->nbr * sizeof (struct carsym)); n = bfd_realloc_or_free (cs->idx, amt);
if (n == NULL) if (n == NULL)
return FALSE; return FALSE;
} }

View file

@ -245,6 +245,7 @@ wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
tdata_type *tdata = abfd->tdata.any; tdata_type *tdata = abfd->tdata.any;
asymbol *symbols = NULL; asymbol *symbols = NULL;
sec_ptr space_function_index; sec_ptr space_function_index;
size_t amt;
p = asect->contents; p = asect->contents;
end = asect->contents + asect->size; end = asect->contents + asect->size;
@ -301,7 +302,12 @@ wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
if (!space_function_index) if (!space_function_index)
return FALSE; return FALSE;
symbols = bfd_alloc2 (abfd, tdata->symcount, sizeof (asymbol)); if (_bfd_mul_overflow (tdata->symcount, sizeof (asymbol), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return FALSE;
}
symbols = bfd_alloc (abfd, amt);
if (!symbols) if (!symbols)
return FALSE; return FALSE;