* libbfd-in.h (bfd_malloc2, bfd_realloc2, bfd_zmalloc2, bfd_alloc2,

bfd_zalloc2): New prototypes.
	* bfd-in.h (HALF_BFD_SIZE_TYPE): Define.
	* libbfd.c (bfd_malloc2, bfd_realloc2, bfd_zmalloc2): New functions.
	* opncls.c (bfd_alloc2, bfd_zalloc2): New functions.
	* elf.c (bfd_elf_get_elf_syms, setup_group, assign_section_numbers,
	elf_map_symbols, map_sections_to_segments,
	assign_file_positions_for_segments, copy_private_bfd_data,
	swap_out_syms, _bfd_elf_slurp_version_tables): Use bfd_*alloc2
	where appropriate.
	* bfd-in2.h: Rebuilt.
	* libbfd.h: Rebuilt.

	* elf.c (_bfd_elf_print_private_bfd_data): Don't crash on bogus
	verdef or verneed section.
	(_bfd_elf_slurp_version_tables): Handle corrupt verdef and/or
	verneed sections gracefully.
	* elfxx-sparc.c (_bfd_sparc_elf_info_to_howto_ptr): Don't crash on
	bogus relocation values.
	* elf64-ppc.c (ppc64_elf_info_to_howto): Likewise.
	* elf64-s390.c (elf_s390_info_to_howto): Likewise.
	* elf32-s390.c (elf_s390_info_to_howto): Likewise.
	* elf64-x86-64.c (elf64_x86_64_info_to_howto): Likewise.
	* elfxx-ia64.c (lookup_howto): Likewise.
This commit is contained in:
Jakub Jelinek 2005-07-05 09:44:20 +00:00
parent c6c60d09fd
commit d0fb9a8d03
14 changed files with 386 additions and 73 deletions

View File

@ -1,5 +1,30 @@
2005-07-05 Jakub Jelinek <jakub@redhat.com> 2005-07-05 Jakub Jelinek <jakub@redhat.com>
* libbfd-in.h (bfd_malloc2, bfd_realloc2, bfd_zmalloc2, bfd_alloc2,
bfd_zalloc2): New prototypes.
* bfd-in.h (HALF_BFD_SIZE_TYPE): Define.
* libbfd.c (bfd_malloc2, bfd_realloc2, bfd_zmalloc2): New functions.
* opncls.c (bfd_alloc2, bfd_zalloc2): New functions.
* elf.c (bfd_elf_get_elf_syms, setup_group, assign_section_numbers,
elf_map_symbols, map_sections_to_segments,
assign_file_positions_for_segments, copy_private_bfd_data,
swap_out_syms, _bfd_elf_slurp_version_tables): Use bfd_*alloc2
where appropriate.
* bfd-in2.h: Rebuilt.
* libbfd.h: Rebuilt.
* elf.c (_bfd_elf_print_private_bfd_data): Don't crash on bogus
verdef or verneed section.
(_bfd_elf_slurp_version_tables): Handle corrupt verdef and/or
verneed sections gracefully.
* elfxx-sparc.c (_bfd_sparc_elf_info_to_howto_ptr): Don't crash on
bogus relocation values.
* elf64-ppc.c (ppc64_elf_info_to_howto): Likewise.
* elf64-s390.c (elf_s390_info_to_howto): Likewise.
* elf32-s390.c (elf_s390_info_to_howto): Likewise.
* elf64-x86-64.c (elf64_x86_64_info_to_howto): Likewise.
* elfxx-ia64.c (lookup_howto): Likewise.
* elf.c (bfd_elf_get_str_section): Allocate an extra byte after * elf.c (bfd_elf_get_str_section): Allocate an extra byte after
the end of strtab and clear it. the end of strtab and clear it.
(elf_read): Remove. (elf_read): Remove.

View File

@ -136,6 +136,9 @@ typedef unsigned long bfd_size_type;
#endif /* not BFD64 */ #endif /* not BFD64 */
#define HALF_BFD_SIZE_TYPE \
(((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
#ifndef BFD_HOST_64_BIT #ifndef BFD_HOST_64_BIT
/* Fall back on a 32 bit type. The idea is to make these types always /* Fall back on a 32 bit type. The idea is to make these types always
available for function return types, but in the case that available for function return types, but in the case that

View File

@ -143,6 +143,9 @@ typedef unsigned long bfd_size_type;
#endif /* not BFD64 */ #endif /* not BFD64 */
#define HALF_BFD_SIZE_TYPE \
(((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
#ifndef BFD_HOST_64_BIT #ifndef BFD_HOST_64_BIT
/* Fall back on a 32 bit type. The idea is to make these types always /* Fall back on a 32 bit type. The idea is to make these types always
available for function return types, but in the case that available for function return types, but in the case that

176
bfd/elf.c
View File

@ -340,7 +340,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
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_malloc (amt); alloc_ext = bfd_malloc2 (symcount, extsym_size);
extsym_buf = alloc_ext; extsym_buf = alloc_ext;
} }
if (extsym_buf == NULL if (extsym_buf == NULL
@ -359,7 +359,8 @@ bfd_elf_get_elf_syms (bfd *ibfd,
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 = bfd_malloc (amt); alloc_extshndx = bfd_malloc2 (symcount,
sizeof (Elf_External_Sym_Shndx));
extshndx_buf = alloc_extshndx; extshndx_buf = alloc_extshndx;
} }
if (extshndx_buf == NULL if (extshndx_buf == NULL
@ -373,8 +374,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
if (intsym_buf == NULL) if (intsym_buf == NULL)
{ {
bfd_size_type amt = symcount * sizeof (Elf_Internal_Sym); intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
intsym_buf = bfd_malloc (amt);
if (intsym_buf == NULL) if (intsym_buf == NULL)
goto out; goto out;
} }
@ -494,10 +494,10 @@ 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; bfd_size_type amt;
elf_tdata (abfd)->num_group = num_group; elf_tdata (abfd)->num_group = num_group;
amt = num_group * sizeof (Elf_Internal_Shdr *); elf_tdata (abfd)->group_sect_ptr
elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, amt); = bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
if (elf_tdata (abfd)->group_sect_ptr == NULL) if (elf_tdata (abfd)->group_sect_ptr == NULL)
return FALSE; return FALSE;
@ -517,7 +517,8 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
/* Read the raw contents. */ /* Read the raw contents. */
BFD_ASSERT (sizeof (*dest) >= 4); BFD_ASSERT (sizeof (*dest) >= 4);
amt = shdr->sh_size * sizeof (*dest) / 4; amt = shdr->sh_size * sizeof (*dest) / 4;
shdr->contents = bfd_alloc (abfd, amt); shdr->contents = bfd_alloc2 (abfd, shdr->sh_size,
sizeof (*dest) / 4);
if (shdr->contents == NULL if (shdr->contents == NULL
|| bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0 || 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)
@ -1219,8 +1220,9 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef) for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
{ {
fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx, fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
t->vd_flags, t->vd_hash, t->vd_nodename); t->vd_flags, t->vd_hash,
if (t->vd_auxptr->vda_nextptr != NULL) t->vd_nodename ? t->vd_nodename : "<corrupt>");
if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL)
{ {
Elf_Internal_Verdaux *a; Elf_Internal_Verdaux *a;
@ -1228,7 +1230,8 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
for (a = t->vd_auxptr->vda_nextptr; for (a = t->vd_auxptr->vda_nextptr;
a != NULL; a != NULL;
a = a->vda_nextptr) a = a->vda_nextptr)
fprintf (f, "%s ", a->vda_nodename); fprintf (f, "%s ",
a->vda_nodename ? a->vda_nodename : "<corrupt>");
fprintf (f, "\n"); fprintf (f, "\n");
} }
} }
@ -1243,10 +1246,12 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
{ {
Elf_Internal_Vernaux *a; Elf_Internal_Vernaux *a;
fprintf (f, _(" required from %s:\n"), t->vn_filename); fprintf (f, _(" required from %s:\n"),
t->vn_filename ? t->vn_filename : "<corrupt>");
for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash, fprintf (f, " 0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
a->vna_flags, a->vna_other, a->vna_nodename); a->vna_flags, a->vna_other,
a->vna_nodename ? a->vna_nodename : "<corrupt>");
} }
} }
@ -2883,7 +2888,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
asection *sec; asection *sec;
unsigned int section_number, secn; unsigned int section_number, secn;
Elf_Internal_Shdr **i_shdrp; Elf_Internal_Shdr **i_shdrp;
bfd_size_type amt;
struct bfd_elf_section_data *d; struct bfd_elf_section_data *d;
section_number = 1; section_number = 1;
@ -2987,13 +2991,11 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
/* Set up the list of section header pointers, in agreement with the /* Set up the list of section header pointers, in agreement with the
indices. */ indices. */
amt = section_number * sizeof (Elf_Internal_Shdr *); i_shdrp = bfd_zalloc2 (abfd, section_number, sizeof (Elf_Internal_Shdr *));
i_shdrp = bfd_zalloc (abfd, amt);
if (i_shdrp == NULL) if (i_shdrp == NULL)
return FALSE; return FALSE;
amt = sizeof (Elf_Internal_Shdr); i_shdrp[0] = bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr));
i_shdrp[0] = bfd_zalloc (abfd, amt);
if (i_shdrp[0] == NULL) if (i_shdrp[0] == NULL)
{ {
bfd_release (abfd, i_shdrp); bfd_release (abfd, i_shdrp);
@ -3244,7 +3246,6 @@ elf_map_symbols (bfd *abfd)
unsigned int idx; unsigned int idx;
asection *asect; asection *asect;
asymbol **new_syms; asymbol **new_syms;
bfd_size_type amt;
#ifdef DEBUG #ifdef DEBUG
fprintf (stderr, "elf_map_symbols\n"); fprintf (stderr, "elf_map_symbols\n");
@ -3258,8 +3259,7 @@ elf_map_symbols (bfd *abfd)
} }
max_index++; max_index++;
amt = max_index * sizeof (asymbol *); sect_syms = bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
sect_syms = bfd_zalloc (abfd, amt);
if (sect_syms == NULL) if (sect_syms == NULL)
return FALSE; return FALSE;
elf_section_syms (abfd) = sect_syms; elf_section_syms (abfd) = sect_syms;
@ -3332,8 +3332,7 @@ elf_map_symbols (bfd *abfd)
} }
/* Now sort the symbols so the local symbols are first. */ /* Now sort the symbols so the local symbols are first. */
amt = (num_locals + num_globals) * sizeof (asymbol *); new_syms = bfd_alloc2 (abfd, num_locals + num_globals, sizeof (asymbol *));
new_syms = bfd_alloc (abfd, amt);
if (new_syms == NULL) if (new_syms == NULL)
return FALSE; return FALSE;
@ -3592,8 +3591,7 @@ map_sections_to_segments (bfd *abfd)
/* Select the allocated sections, and sort them. */ /* Select the allocated sections, and sort them. */
amt = bfd_count_sections (abfd) * sizeof (asection *); sections = bfd_malloc2 (bfd_count_sections (abfd), sizeof (asection *));
sections = bfd_malloc (amt);
if (sections == NULL) if (sections == NULL)
goto error_return; goto error_return;
@ -4025,7 +4023,6 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
bfd_vma filehdr_vaddr, filehdr_paddr; bfd_vma filehdr_vaddr, filehdr_paddr;
bfd_vma phdrs_vaddr, phdrs_paddr; bfd_vma phdrs_vaddr, phdrs_paddr;
Elf_Internal_Phdr *p; Elf_Internal_Phdr *p;
bfd_size_type amt;
if (elf_tdata (abfd)->segment_map == NULL) if (elf_tdata (abfd)->segment_map == NULL)
{ {
@ -4100,8 +4097,7 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
if (alloc == 0) if (alloc == 0)
alloc = count; alloc = count;
amt = alloc * sizeof (Elf_Internal_Phdr); phdrs = bfd_alloc2 (abfd, alloc, sizeof (Elf_Internal_Phdr));
phdrs = bfd_alloc (abfd, amt);
if (phdrs == NULL) if (phdrs == NULL)
return FALSE; return FALSE;
@ -5361,8 +5357,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
/* Gcc 2.96 miscompiles this code on mips. Don't do casting here /* Gcc 2.96 miscompiles this code on mips. Don't do casting here
to work around this long long bug. */ to work around this long long bug. */
amt = section_count * sizeof (asection *); sections = bfd_malloc2 (section_count, sizeof (asection *));
sections = bfd_malloc (amt);
if (sections == NULL) if (sections == NULL)
return FALSE; return FALSE;
@ -5784,8 +5779,7 @@ swap_out_syms (bfd *abfd,
symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
symstrtab_hdr->sh_type = SHT_STRTAB; symstrtab_hdr->sh_type = SHT_STRTAB;
amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym; outbound_syms = bfd_alloc2 (abfd, 1 + symcount, bed->s->sizeof_sym);
outbound_syms = bfd_alloc (abfd, amt);
if (outbound_syms == NULL) if (outbound_syms == NULL)
{ {
_bfd_stringtab_free (stt); _bfd_stringtab_free (stt);
@ -5798,7 +5792,8 @@ swap_out_syms (bfd *abfd,
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); amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
outbound_shndx = bfd_zalloc (abfd, amt); outbound_shndx = bfd_zalloc2 (abfd, 1 + symcount,
sizeof (Elf_External_Sym_Shndx));
if (outbound_shndx == NULL) if (outbound_shndx == NULL)
{ {
_bfd_stringtab_free (stt); _bfd_stringtab_free (stt);
@ -6211,7 +6206,6 @@ bfd_boolean
_bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
{ {
bfd_byte *contents = NULL; bfd_byte *contents = NULL;
bfd_size_type amt;
unsigned int freeidx = 0; unsigned int freeidx = 0;
if (elf_dynverref (abfd) != 0) if (elf_dynverref (abfd) != 0)
@ -6220,11 +6214,12 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
Elf_External_Verneed *everneed; Elf_External_Verneed *everneed;
Elf_Internal_Verneed *iverneed; Elf_Internal_Verneed *iverneed;
unsigned int i; unsigned int i;
bfd_byte *contents_end;
hdr = &elf_tdata (abfd)->dynverref_hdr; hdr = &elf_tdata (abfd)->dynverref_hdr;
amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed); elf_tdata (abfd)->verref = bfd_zalloc2 (abfd, hdr->sh_info,
elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt); sizeof (Elf_Internal_Verneed));
if (elf_tdata (abfd)->verref == NULL) if (elf_tdata (abfd)->verref == NULL)
goto error_return; goto error_return;
@ -6232,11 +6227,22 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
contents = bfd_malloc (hdr->sh_size); contents = bfd_malloc (hdr->sh_size);
if (contents == NULL) if (contents == NULL)
goto error_return; {
error_return_verref:
elf_tdata (abfd)->verref = NULL;
elf_tdata (abfd)->cverrefs = 0;
goto error_return;
}
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
|| bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
goto error_return; goto error_return_verref;
if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed))
goto error_return_verref;
BFD_ASSERT (sizeof (Elf_External_Verneed)
== sizeof (Elf_External_Vernaux));
contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed);
everneed = (Elf_External_Verneed *) contents; everneed = (Elf_External_Verneed *) contents;
iverneed = elf_tdata (abfd)->verref; iverneed = elf_tdata (abfd)->verref;
for (i = 0; i < hdr->sh_info; i++, iverneed++) for (i = 0; i < hdr->sh_info; i++, iverneed++)
@ -6253,11 +6259,21 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
bfd_elf_string_from_elf_section (abfd, hdr->sh_link, bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
iverneed->vn_file); iverneed->vn_file);
if (iverneed->vn_filename == NULL) if (iverneed->vn_filename == NULL)
goto error_return; goto error_return_verref;
amt = iverneed->vn_cnt; if (iverneed->vn_cnt == 0)
amt *= sizeof (Elf_Internal_Vernaux); iverneed->vn_auxptr = NULL;
iverneed->vn_auxptr = bfd_alloc (abfd, amt); else
{
iverneed->vn_auxptr = bfd_alloc2 (abfd, iverneed->vn_cnt,
sizeof (Elf_Internal_Vernaux));
if (iverneed->vn_auxptr == NULL)
goto error_return_verref;
}
if (iverneed->vn_aux
> (size_t) (contents_end - (bfd_byte *) everneed))
goto error_return_verref;
evernaux = ((Elf_External_Vernaux *) evernaux = ((Elf_External_Vernaux *)
((bfd_byte *) everneed + iverneed->vn_aux)); ((bfd_byte *) everneed + iverneed->vn_aux));
@ -6270,13 +6286,17 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
bfd_elf_string_from_elf_section (abfd, hdr->sh_link, bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
ivernaux->vna_name); ivernaux->vna_name);
if (ivernaux->vna_nodename == NULL) if (ivernaux->vna_nodename == NULL)
goto error_return; goto error_return_verref;
if (j + 1 < iverneed->vn_cnt) if (j + 1 < iverneed->vn_cnt)
ivernaux->vna_nextptr = ivernaux + 1; ivernaux->vna_nextptr = ivernaux + 1;
else else
ivernaux->vna_nextptr = NULL; ivernaux->vna_nextptr = NULL;
if (ivernaux->vna_next
> (size_t) (contents_end - (bfd_byte *) evernaux))
goto error_return_verref;
evernaux = ((Elf_External_Vernaux *) evernaux = ((Elf_External_Vernaux *)
((bfd_byte *) evernaux + ivernaux->vna_next)); ((bfd_byte *) evernaux + ivernaux->vna_next));
@ -6289,6 +6309,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
else else
iverneed->vn_nextref = NULL; iverneed->vn_nextref = NULL;
if (iverneed->vn_next
> (size_t) (contents_end - (bfd_byte *) everneed))
goto error_return_verref;
everneed = ((Elf_External_Verneed *) everneed = ((Elf_External_Verneed *)
((bfd_byte *) everneed + iverneed->vn_next)); ((bfd_byte *) everneed + iverneed->vn_next));
} }
@ -6306,6 +6330,7 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
Elf_Internal_Verdef iverdefmem; Elf_Internal_Verdef iverdefmem;
unsigned int i; unsigned int i;
unsigned int maxidx; unsigned int maxidx;
bfd_byte *contents_end_def, *contents_end_aux;
hdr = &elf_tdata (abfd)->dynverdef_hdr; hdr = &elf_tdata (abfd)->dynverdef_hdr;
@ -6316,6 +6341,16 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
|| bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
goto error_return; goto error_return;
if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef))
goto error_return;
BFD_ASSERT (sizeof (Elf_External_Verdef)
>= sizeof (Elf_External_Verdaux));
contents_end_def = contents + hdr->sh_size
- sizeof (Elf_External_Verdef);
contents_end_aux = contents + hdr->sh_size
- sizeof (Elf_External_Verdaux);
/* We know the number of entries in the section but not the maximum /* We know the number of entries in the section but not the maximum
index. Therefore we have to run through all entries and find index. Therefore we have to run through all entries and find
the maximum. */ the maximum. */
@ -6328,6 +6363,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx) if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION); maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
if (iverdefmem.vd_next
> (size_t) (contents_end_def - (bfd_byte *) everdef))
goto error_return;
everdef = ((Elf_External_Verdef *) everdef = ((Elf_External_Verdef *)
((bfd_byte *) everdef + iverdefmem.vd_next)); ((bfd_byte *) everdef + iverdefmem.vd_next));
} }
@ -6339,8 +6378,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
else else
freeidx = ++maxidx; freeidx = ++maxidx;
} }
amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef); elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, maxidx,
elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt); sizeof (Elf_Internal_Verdef));
if (elf_tdata (abfd)->verdef == NULL) if (elf_tdata (abfd)->verdef == NULL)
goto error_return; goto error_return;
@ -6356,15 +6395,32 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
_bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem); _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
{
error_return_verdef:
elf_tdata (abfd)->verdef = NULL;
elf_tdata (abfd)->cverdefs = 0;
goto error_return;
}
iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1]; iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef)); memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
iverdef->vd_bfd = abfd; iverdef->vd_bfd = abfd;
amt = (bfd_size_type) iverdef->vd_cnt * sizeof (Elf_Internal_Verdaux); if (iverdef->vd_cnt == 0)
iverdef->vd_auxptr = bfd_alloc (abfd, amt); iverdef->vd_auxptr = NULL;
if (iverdef->vd_auxptr == NULL) else
goto error_return; {
iverdef->vd_auxptr = bfd_alloc2 (abfd, iverdef->vd_cnt,
sizeof (Elf_Internal_Verdaux));
if (iverdef->vd_auxptr == NULL)
goto error_return_verdef;
}
if (iverdef->vd_aux
> (size_t) (contents_end_aux - (bfd_byte *) everdef))
goto error_return_verdef;
everdaux = ((Elf_External_Verdaux *) everdaux = ((Elf_External_Verdaux *)
((bfd_byte *) everdef + iverdef->vd_aux)); ((bfd_byte *) everdef + iverdef->vd_aux));
@ -6377,20 +6433,25 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
bfd_elf_string_from_elf_section (abfd, hdr->sh_link, bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
iverdaux->vda_name); iverdaux->vda_name);
if (iverdaux->vda_nodename == NULL) if (iverdaux->vda_nodename == NULL)
goto error_return; goto error_return_verdef;
if (j + 1 < iverdef->vd_cnt) if (j + 1 < iverdef->vd_cnt)
iverdaux->vda_nextptr = iverdaux + 1; iverdaux->vda_nextptr = iverdaux + 1;
else else
iverdaux->vda_nextptr = NULL; iverdaux->vda_nextptr = NULL;
if (iverdaux->vda_next
> (size_t) (contents_end_aux - (bfd_byte *) everdaux))
goto error_return_verdef;
everdaux = ((Elf_External_Verdaux *) everdaux = ((Elf_External_Verdaux *)
((bfd_byte *) everdaux + iverdaux->vda_next)); ((bfd_byte *) everdaux + iverdaux->vda_next));
} }
iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename; if (iverdef->vd_cnt)
iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
if (i + 1 < hdr->sh_info) if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
iverdef->vd_nextdef = iverdef + 1; iverdef->vd_nextdef = iverdef + 1;
else else
iverdef->vd_nextdef = NULL; iverdef->vd_nextdef = NULL;
@ -6409,8 +6470,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
else else
freeidx++; freeidx++;
amt = (bfd_size_type) freeidx * sizeof (Elf_Internal_Verdef); elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, freeidx,
elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt); sizeof (Elf_Internal_Verdef));
if (elf_tdata (abfd)->verdef == NULL) if (elf_tdata (abfd)->verdef == NULL)
goto error_return; goto error_return;
@ -6434,10 +6495,11 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd); iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
if (iverdef->vd_nodename == NULL) if (iverdef->vd_nodename == NULL)
goto error_return; goto error_return_verdef;
iverdef->vd_nextdef = NULL; iverdef->vd_nextdef = NULL;
amt = (bfd_size_type) sizeof (Elf_Internal_Verdaux); iverdef->vd_auxptr = bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
iverdef->vd_auxptr = bfd_alloc (abfd, amt); if (iverdef->vd_auxptr == NULL)
goto error_return_verdef;
iverdaux = iverdef->vd_auxptr; iverdaux = iverdef->vd_auxptr;
iverdaux->vda_nodename = iverdef->vd_nodename; iverdaux->vda_nodename = iverdef->vd_nodename;

View File

@ -351,7 +351,8 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
arelent *cache_ptr; arelent *cache_ptr;
Elf_Internal_Rela *dst; Elf_Internal_Rela *dst;
{ {
switch (ELF32_R_TYPE(dst->r_info)) unsigned int r_type = ELF32_R_TYPE(dst->r_info);
switch (r_type)
{ {
case R_390_GNU_VTINHERIT: case R_390_GNU_VTINHERIT:
cache_ptr->howto = &elf32_s390_vtinherit_howto; cache_ptr->howto = &elf32_s390_vtinherit_howto;
@ -362,8 +363,13 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
break; break;
default: default:
BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_390_max); if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; {
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
abfd, (int) r_type);
r_type = R_390_NONE;
}
cache_ptr->howto = &elf_howto_table[r_type];
} }
} }

View File

@ -2117,8 +2117,13 @@ ppc64_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
ppc_howto_init (); ppc_howto_init ();
type = ELF64_R_TYPE (dst->r_info); type = ELF64_R_TYPE (dst->r_info);
BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table) if (type >= (sizeof (ppc64_elf_howto_table)
/ sizeof (ppc64_elf_howto_table[0]))); / sizeof (ppc64_elf_howto_table[0])))
{
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
abfd, (int) r_type);
r_type = R_PPC64_NONE;
}
cache_ptr->howto = ppc64_elf_howto_table[type]; cache_ptr->howto = ppc64_elf_howto_table[type];
} }

View File

@ -373,7 +373,8 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
arelent *cache_ptr; arelent *cache_ptr;
Elf_Internal_Rela *dst; Elf_Internal_Rela *dst;
{ {
switch (ELF64_R_TYPE(dst->r_info)) unsigned int r_type = ELF64_R_TYPE(dst->r_info);
switch (r_type)
{ {
case R_390_GNU_VTINHERIT: case R_390_GNU_VTINHERIT:
cache_ptr->howto = &elf64_s390_vtinherit_howto; cache_ptr->howto = &elf64_s390_vtinherit_howto;
@ -384,8 +385,13 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
break; break;
default: default:
BFD_ASSERT (ELF64_R_TYPE(dst->r_info) < (unsigned int) R_390_max); if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0]))
cache_ptr->howto = &elf_howto_table[ELF64_R_TYPE(dst->r_info)]; {
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
abfd, (int) r_type);
r_type = R_390_NONE;
}
cache_ptr->howto = &elf_howto_table[r_type];
} }
} }

View File

@ -189,16 +189,19 @@ elf64_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
unsigned r_type, i; unsigned r_type, i;
r_type = ELF64_R_TYPE (dst->r_info); r_type = ELF64_R_TYPE (dst->r_info);
if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT) if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
|| r_type >= (unsigned int) R_X86_64_max)
{ {
BFD_ASSERT (r_type <= (unsigned int) R_X86_64_GOTPC32); if (r_type > (unsigned int) R_X86_64_GOTPC32)
{
(*_bfd_error_handler) (_("%B: invalid relocation type %d"),
abfd, (int) r_type);
r_type = R_X86_64_NONE;
}
i = r_type; i = r_type;
} }
else else
{ i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_GOTPC32 - 1);
BFD_ASSERT (r_type < (unsigned int) R_X86_64_max);
i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_GOTPC32 - 1);
}
cache_ptr->howto = &x86_64_elf_howto_table[i]; cache_ptr->howto = &x86_64_elf_howto_table[i];
BFD_ASSERT (r_type == cache_ptr->howto->type); BFD_ASSERT (r_type == cache_ptr->howto->type);
} }

View File

@ -487,7 +487,8 @@ lookup_howto (rtype)
elf_code_to_howto_index[ia64_howto_table[i].type] = i; elf_code_to_howto_index[ia64_howto_table[i].type] = i;
} }
BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE); if (rtype > R_IA64_MAX_RELOC_CODE)
return 0;
i = elf_code_to_howto_index[rtype]; i = elf_code_to_howto_index[rtype];
if (i >= NELEMS (ia64_howto_table)) if (i >= NELEMS (ia64_howto_table))
return 0; return 0;

View File

@ -397,7 +397,12 @@ _bfd_sparc_elf_info_to_howto_ptr (unsigned int r_type)
return &sparc_rev32_howto; return &sparc_rev32_howto;
default: default:
BFD_ASSERT (r_type < (unsigned int) R_SPARC_max_std); if (r_type >= (unsigned int) R_SPARC_max_std)
{
(*_bfd_error_handler) (_("invalid relocation type %d"),
(int) r_type);
r_type = R_SPARC_NONE;
}
return &_bfd_sparc_elf_howto_table[r_type]; return &_bfd_sparc_elf_howto_table[r_type];
} }
} }

View File

@ -93,6 +93,12 @@ extern void *bfd_realloc
(void *, bfd_size_type); (void *, bfd_size_type);
extern void *bfd_zmalloc extern void *bfd_zmalloc
(bfd_size_type); (bfd_size_type);
extern void *bfd_malloc2
(bfd_size_type, bfd_size_type);
extern void *bfd_realloc2
(void *, bfd_size_type, bfd_size_type);
extern void *bfd_zmalloc2
(bfd_size_type, bfd_size_type);
extern void _bfd_default_error_handler (const char *s, ...); extern void _bfd_default_error_handler (const char *s, ...);
extern bfd_error_handler_type _bfd_error_handler; extern bfd_error_handler_type _bfd_error_handler;
@ -103,6 +109,10 @@ extern void *bfd_alloc
(bfd *, bfd_size_type); (bfd *, bfd_size_type);
extern void *bfd_zalloc extern void *bfd_zalloc
(bfd *, bfd_size_type); (bfd *, bfd_size_type);
extern void *bfd_alloc2
(bfd *, bfd_size_type, bfd_size_type);
extern void *bfd_zalloc2
(bfd *, bfd_size_type, bfd_size_type);
extern void bfd_release extern void bfd_release
(bfd *, void *); (bfd *, void *);

View File

@ -156,6 +156,36 @@ 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)
{
void *ptr;
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;
if (size != (size_t) size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
ptr = malloc ((size_t) size);
if (ptr == NULL && (size_t) size != 0)
bfd_set_error (bfd_error_no_memory);
return ptr;
}
/* Reallocate memory using realloc. */ /* Reallocate memory using realloc. */
void * void *
@ -180,6 +210,40 @@ 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)
{
void *ret;
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;
if (size != (size_t) size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
if (ptr == NULL)
ret = malloc ((size_t) size);
else
ret = realloc (ptr, (size_t) size);
if (ret == NULL && (size_t) size != 0)
bfd_set_error (bfd_error_no_memory);
return ret;
}
/* Allocate memory using malloc and clear it. */ /* Allocate memory using malloc and clear it. */
void * void *
@ -205,6 +269,44 @@ 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;
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;
if (size != (size_t) size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
ptr = malloc ((size_t) size);
if ((size_t) size != 0)
{
if (ptr == NULL)
bfd_set_error (bfd_error_no_memory);
else
memset (ptr, 0, (size_t) size);
}
return ptr;
}
/* /*
INTERNAL_FUNCTION INTERNAL_FUNCTION
bfd_write_bigendian_4byte_int bfd_write_bigendian_4byte_int

View File

@ -98,6 +98,12 @@ extern void *bfd_realloc
(void *, bfd_size_type); (void *, bfd_size_type);
extern void *bfd_zmalloc extern void *bfd_zmalloc
(bfd_size_type); (bfd_size_type);
extern void *bfd_malloc2
(bfd_size_type, bfd_size_type);
extern void *bfd_realloc2
(void *, bfd_size_type, bfd_size_type);
extern void *bfd_zmalloc2
(bfd_size_type, bfd_size_type);
extern void _bfd_default_error_handler (const char *s, ...); extern void _bfd_default_error_handler (const char *s, ...);
extern bfd_error_handler_type _bfd_error_handler; extern bfd_error_handler_type _bfd_error_handler;
@ -108,6 +114,10 @@ extern void *bfd_alloc
(bfd *, bfd_size_type); (bfd *, bfd_size_type);
extern void *bfd_zalloc extern void *bfd_zalloc
(bfd *, bfd_size_type); (bfd *, bfd_size_type);
extern void *bfd_alloc2
(bfd *, bfd_size_type, bfd_size_type);
extern void *bfd_zalloc2
(bfd *, bfd_size_type, bfd_size_type);
extern void bfd_release extern void bfd_release
(bfd *, void *); (bfd *, void *);

View File

@ -856,6 +856,45 @@ 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)
{
void *ret;
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;
if (size != (unsigned long) size)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
ret = objalloc_alloc (abfd->memory, (unsigned long) size);
if (ret == NULL)
bfd_set_error (bfd_error_no_memory);
return ret;
}
/* /*
INTERNAL_FUNCTION INTERNAL_FUNCTION
bfd_zalloc bfd_zalloc
@ -879,6 +918,39 @@ 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! */