2005-06-15 Jakub Jelinek * 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. * elf32-sparc.c (elf32_sparc_info_to_howto): Don't crash on bogus relocation values. * elf64-sparc.c (sparc64_elf_info_to_howto): Likewise. * 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. --- bfd/libbfd-in.h.jj 2004-11-22 15:33:31.000000000 -0500 +++ bfd/libbfd-in.h 2005-06-29 04:37:50.000000000 -0400 @@ -90,6 +90,12 @@ extern void *bfd_realloc (void *, bfd_size_type); extern void *bfd_zmalloc (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 bfd_error_handler_type _bfd_error_handler; @@ -100,6 +106,10 @@ extern void *bfd_alloc (bfd *, bfd_size_type); extern void *bfd_zalloc (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 (bfd *, void *); --- bfd/bfd-in.h.jj 2004-12-20 14:16:48.000000000 -0500 +++ bfd/bfd-in.h 2005-06-29 04:37:50.000000000 -0400 @@ -144,6 +144,9 @@ typedef unsigned long bfd_size_type; #endif /* not BFD64 */ +#define HALF_BFD_SIZE_TYPE \ + (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2)) + #ifndef BFD_HOST_64_BIT /* 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 --- bfd/libbfd.c.jj 2004-09-15 15:05:03.000000000 -0400 +++ bfd/libbfd.c 2005-06-29 04:37:50.000000000 -0400 @@ -156,6 +156,36 @@ bfd_malloc (bfd_size_type size) 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. */ void * @@ -180,6 +210,40 @@ bfd_realloc (void *ptr, bfd_size_type si 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. */ void * @@ -205,6 +269,44 @@ bfd_zmalloc (bfd_size_type size) 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 bfd_write_bigendian_4byte_int --- bfd/opncls.c.jj 2004-11-22 15:33:31.000000000 -0500 +++ bfd/opncls.c 2005-06-29 04:41:50.000000000 -0400 @@ -849,6 +849,54 @@ bfd_zalloc (bfd *abfd, bfd_size_type siz return res; } +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; +} + +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. Note: Also frees all more recently allocated blocks! */ --- bfd/elf.c.jj 2005-06-29 04:36:58.000000000 -0400 +++ bfd/elf.c 2005-06-29 04:46:03.000000000 -0400 @@ -340,7 +340,7 @@ bfd_elf_get_elf_syms (bfd *ibfd, pos = symtab_hdr->sh_offset + symoffset * extsym_size; if (extsym_buf == NULL) { - alloc_ext = bfd_malloc (amt); + alloc_ext = bfd_malloc2 (symcount, extsym_size); extsym_buf = alloc_ext; } 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); if (extshndx_buf == NULL) { - alloc_extshndx = bfd_malloc (amt); + alloc_extshndx = bfd_malloc2 (symcount, + sizeof (Elf_External_Sym_Shndx)); extshndx_buf = alloc_extshndx; } if (extshndx_buf == NULL @@ -373,8 +374,7 @@ bfd_elf_get_elf_syms (bfd *ibfd, if (intsym_buf == NULL) { - bfd_size_type amt = symcount * sizeof (Elf_Internal_Sym); - intsym_buf = bfd_malloc (amt); + intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym)); if (intsym_buf == NULL) goto out; } @@ -483,8 +483,9 @@ setup_group (bfd *abfd, Elf_Internal_Shd { /* We keep a list of elf section headers for group sections, so we can find them quickly. */ - bfd_size_type amt = num_group * sizeof (Elf_Internal_Shdr *); - elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, amt); + bfd_size_type amt; + elf_tdata (abfd)->group_sect_ptr + = bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *)); if (elf_tdata (abfd)->group_sect_ptr == NULL) return FALSE; @@ -504,7 +506,8 @@ setup_group (bfd *abfd, Elf_Internal_Shd /* Read the raw contents. */ BFD_ASSERT (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 || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0 || (bfd_bread (shdr->contents, shdr->sh_size, abfd) @@ -1207,8 +1210,9 @@ _bfd_elf_print_private_bfd_data (bfd *ab 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, - t->vd_flags, t->vd_hash, t->vd_nodename); - if (t->vd_auxptr->vda_nextptr != NULL) + t->vd_flags, t->vd_hash, + t->vd_nodename ? t->vd_nodename : ""); + if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL) { Elf_Internal_Verdaux *a; @@ -1216,7 +1220,8 @@ _bfd_elf_print_private_bfd_data (bfd *ab for (a = t->vd_auxptr->vda_nextptr; a != NULL; a = a->vda_nextptr) - fprintf (f, "%s ", a->vda_nodename); + fprintf (f, "%s ", + a->vda_nodename ? a->vda_nodename : ""); fprintf (f, "\n"); } } @@ -1231,10 +1236,12 @@ _bfd_elf_print_private_bfd_data (bfd *ab { 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 : ""); 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, - a->vna_flags, a->vna_other, a->vna_nodename); + a->vna_flags, a->vna_other, + a->vna_nodename ? a->vna_nodename : ""); } } @@ -2760,7 +2767,6 @@ assign_section_numbers (bfd *abfd) asection *sec; unsigned int section_number, secn; Elf_Internal_Shdr **i_shdrp; - bfd_size_type amt; struct bfd_elf_section_data *d; section_number = 1; @@ -2851,13 +2857,11 @@ assign_section_numbers (bfd *abfd) /* Set up the list of section header pointers, in agreement with the indices. */ - amt = section_number * sizeof (Elf_Internal_Shdr *); - i_shdrp = bfd_zalloc (abfd, amt); + i_shdrp = bfd_zalloc2 (abfd, section_number, sizeof (Elf_Internal_Shdr *)); if (i_shdrp == NULL) return FALSE; - amt = sizeof (Elf_Internal_Shdr); - i_shdrp[0] = bfd_zalloc (abfd, amt); + i_shdrp[0] = bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr)); if (i_shdrp[0] == NULL) { bfd_release (abfd, i_shdrp); @@ -3089,7 +3093,6 @@ elf_map_symbols (bfd *abfd) unsigned int idx; asection *asect; asymbol **new_syms; - bfd_size_type amt; #ifdef DEBUG fprintf (stderr, "elf_map_symbols\n"); @@ -3103,8 +3106,7 @@ elf_map_symbols (bfd *abfd) } max_index++; - amt = max_index * sizeof (asymbol *); - sect_syms = bfd_zalloc (abfd, amt); + sect_syms = bfd_zalloc2 (abfd, max_index, sizeof (asymbol *)); if (sect_syms == NULL) return FALSE; elf_section_syms (abfd) = sect_syms; @@ -3177,8 +3179,7 @@ elf_map_symbols (bfd *abfd) } /* Now sort the symbols so the local symbols are first. */ - amt = (num_locals + num_globals) * sizeof (asymbol *); - new_syms = bfd_alloc (abfd, amt); + new_syms = bfd_alloc2 (abfd, num_locals + num_globals, sizeof (asymbol *)); if (new_syms == NULL) return FALSE; @@ -3437,8 +3438,7 @@ map_sections_to_segments (bfd *abfd) /* Select the allocated sections, and sort them. */ - amt = bfd_count_sections (abfd) * sizeof (asection *); - sections = bfd_malloc (amt); + sections = bfd_malloc2 (bfd_count_sections (abfd), sizeof (asection *)); if (sections == NULL) goto error_return; @@ -3870,7 +3870,6 @@ assign_file_positions_for_segments (bfd bfd_vma filehdr_vaddr, filehdr_paddr; bfd_vma phdrs_vaddr, phdrs_paddr; Elf_Internal_Phdr *p; - bfd_size_type amt; if (elf_tdata (abfd)->segment_map == NULL) { @@ -3945,8 +3944,7 @@ assign_file_positions_for_segments (bfd if (alloc == 0) alloc = count; - amt = alloc * sizeof (Elf_Internal_Phdr); - phdrs = bfd_alloc (abfd, amt); + phdrs = bfd_alloc2 (abfd, alloc, sizeof (Elf_Internal_Phdr)); if (phdrs == NULL) return FALSE; @@ -5214,8 +5212,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *o /* Gcc 2.96 miscompiles this code on mips. Don't do casting here to work around this long long bug. */ - amt = section_count * sizeof (asection *); - sections = bfd_malloc (amt); + sections = bfd_malloc2 (section_count, sizeof (asection *)); if (sections == NULL) return FALSE; @@ -5657,8 +5654,7 @@ swap_out_syms (bfd *abfd, symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; symstrtab_hdr->sh_type = SHT_STRTAB; - amt = (bfd_size_type) (1 + symcount) * bed->s->sizeof_sym; - outbound_syms = bfd_alloc (abfd, amt); + outbound_syms = bfd_alloc2 (abfd, 1 + symcount, bed->s->sizeof_sym); if (outbound_syms == NULL) { _bfd_stringtab_free (stt); @@ -5671,7 +5667,8 @@ swap_out_syms (bfd *abfd, if (symtab_shndx_hdr->sh_name != 0) { 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) { _bfd_stringtab_free (stt); @@ -6083,7 +6080,6 @@ bfd_boolean _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) { bfd_byte *contents = NULL; - bfd_size_type amt; unsigned int freeidx = 0; if (elf_dynverref (abfd) != 0) @@ -6092,11 +6088,12 @@ _bfd_elf_slurp_version_tables (bfd *abfd Elf_External_Verneed *everneed; Elf_Internal_Verneed *iverneed; unsigned int i; + bfd_byte *contents_end; hdr = &elf_tdata (abfd)->dynverref_hdr; - amt = (bfd_size_type) hdr->sh_info * sizeof (Elf_Internal_Verneed); - elf_tdata (abfd)->verref = bfd_zalloc (abfd, amt); + elf_tdata (abfd)->verref = bfd_zalloc2 (abfd, hdr->sh_info, + sizeof (Elf_Internal_Verneed)); if (elf_tdata (abfd)->verref == NULL) goto error_return; @@ -6104,11 +6101,22 @@ _bfd_elf_slurp_version_tables (bfd *abfd contents = bfd_malloc (hdr->sh_size); 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 || 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; iverneed = elf_tdata (abfd)->verref; for (i = 0; i < hdr->sh_info; i++, iverneed++) @@ -6125,11 +6133,21 @@ _bfd_elf_slurp_version_tables (bfd *abfd bfd_elf_string_from_elf_section (abfd, hdr->sh_link, iverneed->vn_file); if (iverneed->vn_filename == NULL) - goto error_return; + goto error_return_verref; - amt = iverneed->vn_cnt; - amt *= sizeof (Elf_Internal_Vernaux); - iverneed->vn_auxptr = bfd_alloc (abfd, amt); + if (iverneed->vn_cnt == 0) + iverneed->vn_auxptr = NULL; + 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 *) ((bfd_byte *) everneed + iverneed->vn_aux)); @@ -6142,13 +6160,17 @@ _bfd_elf_slurp_version_tables (bfd *abfd bfd_elf_string_from_elf_section (abfd, hdr->sh_link, ivernaux->vna_name); if (ivernaux->vna_nodename == NULL) - goto error_return; + goto error_return_verref; if (j + 1 < iverneed->vn_cnt) ivernaux->vna_nextptr = ivernaux + 1; else ivernaux->vna_nextptr = NULL; + if (ivernaux->vna_next + > (size_t) (contents_end - (bfd_byte *) evernaux)) + goto error_return_verref; + evernaux = ((Elf_External_Vernaux *) ((bfd_byte *) evernaux + ivernaux->vna_next)); @@ -6161,6 +6183,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd else iverneed->vn_nextref = NULL; + if (iverneed->vn_next + > (size_t) (contents_end - (bfd_byte *) everneed)) + goto error_return_verref; + everneed = ((Elf_External_Verneed *) ((bfd_byte *) everneed + iverneed->vn_next)); } @@ -6178,6 +6204,7 @@ _bfd_elf_slurp_version_tables (bfd *abfd Elf_Internal_Verdef iverdefmem; unsigned int i; unsigned int maxidx; + bfd_byte *contents_end_def, *contents_end_aux; hdr = &elf_tdata (abfd)->dynverdef_hdr; @@ -6188,6 +6215,16 @@ _bfd_elf_slurp_version_tables (bfd *abfd || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size) 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 index. Therefore we have to run through all entries and find the maximum. */ @@ -6200,6 +6237,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx) 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 *) ((bfd_byte *) everdef + iverdefmem.vd_next)); } @@ -6211,8 +6252,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd else freeidx = ++maxidx; } - amt = (bfd_size_type) maxidx * sizeof (Elf_Internal_Verdef); - elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt); + elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, maxidx, + sizeof (Elf_Internal_Verdef)); if (elf_tdata (abfd)->verdef == NULL) goto error_return; @@ -6228,15 +6269,32 @@ _bfd_elf_slurp_version_tables (bfd *abfd _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]; memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef)); iverdef->vd_bfd = abfd; - amt = (bfd_size_type) iverdef->vd_cnt * sizeof (Elf_Internal_Verdaux); - iverdef->vd_auxptr = bfd_alloc (abfd, amt); - if (iverdef->vd_auxptr == NULL) - goto error_return; + if (iverdef->vd_cnt == 0) + iverdef->vd_auxptr = NULL; + else + { + 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 *) ((bfd_byte *) everdef + iverdef->vd_aux)); @@ -6249,20 +6307,25 @@ _bfd_elf_slurp_version_tables (bfd *abfd bfd_elf_string_from_elf_section (abfd, hdr->sh_link, iverdaux->vda_name); if (iverdaux->vda_nodename == NULL) - goto error_return; + goto error_return_verdef; if (j + 1 < iverdef->vd_cnt) iverdaux->vda_nextptr = iverdaux + 1; else iverdaux->vda_nextptr = NULL; + if (iverdaux->vda_next + > (size_t) (contents_end_aux - (bfd_byte *) everdaux)) + goto error_return_verdef; + everdaux = ((Elf_External_Verdaux *) ((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; else iverdef->vd_nextdef = NULL; @@ -6281,8 +6344,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd else freeidx++; - amt = (bfd_size_type) freeidx * sizeof (Elf_Internal_Verdef); - elf_tdata (abfd)->verdef = bfd_zalloc (abfd, amt); + elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, freeidx, + sizeof (Elf_Internal_Verdef)); if (elf_tdata (abfd)->verdef == NULL) goto error_return; @@ -6306,10 +6369,11 @@ _bfd_elf_slurp_version_tables (bfd *abfd iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd); if (iverdef->vd_nodename == NULL) - goto error_return; + goto error_return_verdef; iverdef->vd_nextdef = NULL; - amt = (bfd_size_type) sizeof (Elf_Internal_Verdaux); - iverdef->vd_auxptr = bfd_alloc (abfd, amt); + iverdef->vd_auxptr = bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux)); + if (iverdef->vd_auxptr == NULL) + goto error_return_verdef; iverdaux = iverdef->vd_auxptr; iverdaux->vda_nodename = iverdef->vd_nodename; --- bfd/elf64-ppc.c.jj 2004-12-20 14:16:48.000000000 -0500 +++ bfd/elf64-ppc.c 2005-06-29 04:38:02.000000000 -0400 @@ -2118,8 +2118,13 @@ ppc64_elf_info_to_howto (bfd *abfd ATTRI ppc_howto_init (); type = ELF64_R_TYPE (dst->r_info); - BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table) - / sizeof (ppc64_elf_howto_table[0]))); + if (type >= (sizeof (ppc64_elf_howto_table) + / sizeof (ppc64_elf_howto_table[0]))) + { + (*_bfd_error_handler) (_("%B: invalid relocation type %d"), + abfd, (int) type); + type = R_PPC64_NONE; + } cache_ptr->howto = ppc64_elf_howto_table[type]; } --- bfd/elf64-s390.c.jj 2004-11-22 15:33:31.000000000 -0500 +++ bfd/elf64-s390.c 2005-06-29 04:38:02.000000000 -0400 @@ -372,7 +372,8 @@ elf_s390_info_to_howto (abfd, cache_ptr, arelent *cache_ptr; 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: cache_ptr->howto = &elf64_s390_vtinherit_howto; @@ -383,8 +384,13 @@ elf_s390_info_to_howto (abfd, cache_ptr, break; default: - BFD_ASSERT (ELF64_R_TYPE(dst->r_info) < (unsigned int) R_390_max); - cache_ptr->howto = &elf_howto_table[ELF64_R_TYPE(dst->r_info)]; + if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0])) + { + (*_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]; } } --- bfd/elf32-s390.c.jj 2004-11-22 15:33:30.000000000 -0500 +++ bfd/elf32-s390.c 2005-06-29 04:38:02.000000000 -0400 @@ -350,7 +350,8 @@ elf_s390_info_to_howto (abfd, cache_ptr, arelent *cache_ptr; 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: cache_ptr->howto = &elf32_s390_vtinherit_howto; @@ -361,8 +362,13 @@ elf_s390_info_to_howto (abfd, cache_ptr, break; default: - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_390_max); - cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; + if (r_type >= sizeof (elf_howto_table) / sizeof (elf_howto_table[0])) + { + (*_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]; } } --- bfd/elf64-x86-64.c.jj 2005-02-07 14:42:44.000000000 -0500 +++ bfd/elf64-x86-64.c 2005-06-29 04:38:02.000000000 -0400 @@ -176,16 +176,19 @@ elf64_x86_64_info_to_howto (bfd *abfd AT unsigned r_type, i; 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_TPOFF32); + if (r_type > (unsigned int) R_X86_64_TPOFF32) + { + (*_bfd_error_handler) (_("%B: invalid relocation type %d"), + abfd, (int) r_type); + r_type = R_X86_64_NONE; + } i = r_type; } else - { - BFD_ASSERT (r_type < (unsigned int) R_X86_64_max); - i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_TPOFF32 - 1); - } + i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_TPOFF32 - 1); cache_ptr->howto = &x86_64_elf_howto_table[i]; BFD_ASSERT (r_type == cache_ptr->howto->type); } --- bfd/elfxx-ia64.c.jj 2005-02-18 01:14:30.000000000 -0500 +++ bfd/elfxx-ia64.c 2005-06-29 04:38:02.000000000 -0400 @@ -479,7 +479,8 @@ lookup_howto (rtype) 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]; if (i >= NELEMS (ia64_howto_table)) return 0; --- bfd/bfd-in2.h.jj 2004-12-20 14:16:48.000000000 -0500 +++ bfd/bfd-in2.h 2005-06-29 04:38:02.000000000 -0400 @@ -151,6 +151,9 @@ typedef unsigned long bfd_size_type; #endif /* not BFD64 */ +#define HALF_BFD_SIZE_TYPE \ + (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2)) + #ifndef BFD_HOST_64_BIT /* 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 --- bfd/libbfd.h.jj 2004-12-20 14:16:48.000000000 -0500 +++ bfd/libbfd.h 2005-06-29 04:38:02.000000000 -0400 @@ -95,6 +95,12 @@ extern void *bfd_realloc (void *, bfd_size_type); extern void *bfd_zmalloc (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 bfd_error_handler_type _bfd_error_handler; @@ -105,6 +111,10 @@ extern void *bfd_alloc (bfd *, bfd_size_type); extern void *bfd_zalloc (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 (bfd *, void *); --- bfd/elf32-sparc.c.jj 2004-11-22 15:33:30.000000000 -0500 +++ bfd/elf32-sparc.c 2005-06-29 04:48:04.000000000 -0400 @@ -313,7 +313,8 @@ elf32_sparc_info_to_howto (abfd, cache_p arelent *cache_ptr; 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_SPARC_GNU_VTINHERIT: cache_ptr->howto = &elf32_sparc_vtinherit_howto; @@ -328,8 +329,13 @@ elf32_sparc_info_to_howto (abfd, cache_p break; default: - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_SPARC_max_std); - cache_ptr->howto = &_bfd_sparc_elf_howto_table[ELF32_R_TYPE(dst->r_info)]; + if (r_type >= (unsigned int) R_SPARC_max_std) + { + (*_bfd_error_handler) (_("invalid relocation type %d"), + (int) r_type); + r_type = R_SPARC_NONE; + } + cache_ptr->howto = &_bfd_sparc_elf_howto_table[r_type]; } } --- bfd/elf64-sparc.c.jj 2004-11-22 15:33:31.000000000 -0500 +++ bfd/elf64-sparc.c 2005-06-29 04:49:42.000000000 -0400 @@ -310,8 +310,14 @@ sparc64_elf_info_to_howto (abfd, cache_p arelent *cache_ptr; Elf_Internal_Rela *dst; { - BFD_ASSERT (ELF64_R_TYPE_ID (dst->r_info) < (unsigned int) R_SPARC_max_std); - cache_ptr->howto = &sparc64_elf_howto_table[ELF64_R_TYPE_ID (dst->r_info)]; + unsigned int r_type = ELF64_R_TYPE_ID (dst->r_info); + if (r_type >= (unsigned int) R_SPARC_max_std) + { + (*_bfd_error_handler) (_("invalid relocation type %d"), + (int) r_type); + r_type = R_SPARC_NONE; + } + cache_ptr->howto = &sparc64_elf_howto_table[r_type]; } struct sparc64_elf_section_data