diff options
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 176 |
1 files changed, 119 insertions, 57 deletions
@@ -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; } @@ -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, so we can find them quickly. */ bfd_size_type amt; - + elf_tdata (abfd)->num_group = num_group; - amt = num_group * sizeof (Elf_Internal_Shdr *); - elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, 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; @@ -517,7 +517,8 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) /* 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) @@ -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) { 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 : "<corrupt>"); + if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL) { 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; a != NULL; a = a->vda_nextptr) - fprintf (f, "%s ", a->vda_nodename); + fprintf (f, "%s ", + a->vda_nodename ? a->vda_nodename : "<corrupt>"); fprintf (f, "\n"); } } @@ -1243,10 +1246,12 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg) { 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) 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; unsigned int section_number, secn; Elf_Internal_Shdr **i_shdrp; - bfd_size_type amt; struct bfd_elf_section_data *d; 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 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); @@ -3244,7 +3246,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"); @@ -3258,8 +3259,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; @@ -3332,8 +3332,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; @@ -3592,8 +3591,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; @@ -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 phdrs_vaddr, phdrs_paddr; Elf_Internal_Phdr *p; - bfd_size_type amt; 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) 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; @@ -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 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; @@ -5784,8 +5779,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); @@ -5798,7 +5792,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); @@ -6211,7 +6206,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) @@ -6220,11 +6214,12 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) 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; @@ -6232,11 +6227,22 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) 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++) @@ -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, 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)); @@ -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, 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)); @@ -6289,6 +6309,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) 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)); } @@ -6306,6 +6330,7 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) Elf_Internal_Verdef iverdefmem; unsigned int i; unsigned int maxidx; + bfd_byte *contents_end_def, *contents_end_aux; 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) 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. */ @@ -6328,6 +6363,10 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) 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)); } @@ -6339,8 +6378,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) 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; @@ -6356,15 +6395,32 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) _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)); @@ -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, 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; @@ -6409,8 +6470,8 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver) 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; @@ -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); 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; |