diff options
author | Alan Modra <amodra@gmail.com> | 2019-03-12 16:19:25 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2019-03-12 23:54:09 +1030 |
commit | 7a6e0d89bb018cef0d8d13c497d8f340aa2a0fc8 (patch) | |
tree | 651ca43c71bbdac13aba4be8a5a106e23ac494e5 /bfd/elf.c | |
parent | 0919bfe915906382611011f123b5ae68a0bafbb2 (diff) | |
download | gdb-7a6e0d89bb018cef0d8d13c497d8f340aa2a0fc8.zip gdb-7a6e0d89bb018cef0d8d13c497d8f340aa2a0fc8.tar.gz gdb-7a6e0d89bb018cef0d8d13c497d8f340aa2a0fc8.tar.bz2 |
Don't use bfd_get_file_size in objdump
Compressed debug sections can have uncompressed sizes that exceed the
original file size, so we can't use bfd_get_file_size. objdump also
used bfd_get_file_size to limit reloc section size, but I believe the
underlying bug causing the PR22508 out of bounds buffer access was
that we had an integer overflow when calculating the reloc buffer
size. I've fixed that instead in most of the backends, som and
vms-alpha being the exceptions. SOM and vmd-alpha have rather more
serious bugs in their slurp_relocs routines that would need fixing
first if we want to fuss about making them safe against fuzzed object
files.
The patch also fixes a number of other potential overflows by using
the bfd_alloc2/malloc2/zalloc2 memory allocation functions.
bfd/
* coffcode.h (buy_and_read): Delete unnecessary forward decl. Add
nmemb parameter. Use bfd_alloc2.
(coff_slurp_line_table): Use bfd_alloc2. Update buy_and_read calls.
Delete assertion.
(coff_slurp_symbol_table): Use bfd_alloc2 and bfd_zalloc2.
(coff_slurp_reloc_table): Use bfd_alloc2. Update buy_and_read calls.
* coffgen.c (coff_get_reloc_upper_bound): Ensure size calculation
doesn't overflow.
* elf.c (bfd_section_from_shdr): Use bfd_zalloc2. Style fix.
(assign_section_numbers): Style fix.
(swap_out_syms): Use bfd_malloc2.
(_bfd_elf_get_reloc_upper_bound): Ensure size calculation doesn't
overflow.
(_bfd_elf_make_empty_symbol): Style fix.
(elfobj_grok_stapsdt_note_1): Formatting.
* elfcode.h (elf_object_p): Use bfd_alloc2.
(elf_write_relocs, elf_write_shdrs_and_ehdr): Likewise.
(elf_slurp_symbol_table): Use bfd_zalloc2.
(elf_slurp_reloc_table): Use bfd_alloc2.
(_bfd_elf_bfd_from_remote_memory): Use bfd_malloc2.
* elf64-sparc (elf64_sparc_get_reloc_upper_bound): Ensure
size calculation doesn't overflow.
(elf64_sparc_get_dynamic_reloc_upper_bound): Likewise.
* mach-o.c (bfd_mach_o_get_reloc_upper_bound): Likewise.
* pdp11.c (get_reloc_upper_bound): Copy aoutx.h version.
binutils/
* objdump.c (load_specific_debug_section): Don't compare section
size against file size.
(dump_relocs_in_section): Don't compare reloc size against file size.
Print "failed to read relocs" on bfd_get_reloc_upper_bound error.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 32 |
1 files changed, 22 insertions, 10 deletions
@@ -2036,9 +2036,8 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) sections_being_created = NULL; if (sections_being_created == NULL) { - /* FIXME: It would be more efficient to attach this array to the bfd somehow. */ sections_being_created = (bfd_boolean *) - bfd_zalloc (abfd, elf_numsections (abfd) * sizeof (bfd_boolean)); + bfd_zalloc2 (abfd, elf_numsections (abfd), sizeof (bfd_boolean)); sections_being_created_abfd = abfd; } if (sections_being_created [shindex]) @@ -2259,7 +2258,7 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) if (entry->ndx == shindex) goto success; - entry = bfd_alloc (abfd, sizeof * entry); + entry = bfd_alloc (abfd, sizeof (*entry)); if (entry == NULL) goto fail; entry->ndx = shindex; @@ -3737,11 +3736,11 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name); if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF)) { - elf_section_list * entry; + elf_section_list *entry; BFD_ASSERT (elf_symtab_shndx_list (abfd) == NULL); - entry = bfd_zalloc (abfd, sizeof * entry); + entry = bfd_zalloc (abfd, sizeof (*entry)); entry->ndx = section_number++; elf_symtab_shndx_list (abfd) = entry; entry->hdr.sh_name @@ -7901,8 +7900,8 @@ swap_out_syms (bfd *abfd, symstrtab_hdr->sh_type = SHT_STRTAB; /* Allocate buffer to swap out the .strtab section. */ - symstrtab = (struct elf_sym_strtab *) bfd_malloc ((symcount + 1) - * sizeof (*symstrtab)); + symstrtab = (struct elf_sym_strtab *) bfd_malloc2 (symcount + 1, + sizeof (*symstrtab)); if (symstrtab == NULL) { _bfd_elf_strtab_free (stt); @@ -8269,12 +8268,25 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) return symtab_size; } +#if GCC_VERSION >= 4003 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wtype-limits" +#endif long _bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr asect) { + + if (asect->reloc_count >= LONG_MAX / sizeof (arelent *)) + { + bfd_set_error (bfd_error_file_too_big); + return -1; + } return (asect->reloc_count + 1) * sizeof (arelent *); } +#if GCC_VERSION >= 4003 +# pragma GCC diagnostic pop +#endif /* Canonicalize the relocs. */ @@ -8753,7 +8765,7 @@ _bfd_elf_make_empty_symbol (bfd *abfd) { elf_symbol_type *newsym; - newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof * newsym); + newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (*newsym)); if (!newsym) return NULL; newsym->symbol.the_bfd = abfd; @@ -10233,8 +10245,8 @@ static bfd_boolean elfobj_grok_stapsdt_note_1 (bfd *abfd, Elf_Internal_Note *note) { struct sdt_note *cur = - (struct sdt_note *) bfd_alloc (abfd, sizeof (struct sdt_note) - + note->descsz); + (struct sdt_note *) bfd_alloc (abfd, + sizeof (struct sdt_note) + note->descsz); cur->next = (struct sdt_note *) (elf_tdata (abfd))->sdt_note_head; cur->size = (bfd_size_type) note->descsz; |