diff options
author | Alan Modra <amodra@gmail.com> | 2018-12-16 23:02:50 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2018-12-17 12:49:38 +1030 |
commit | 3a551c7a1b80fca579461774860574eabfd7f18f (patch) | |
tree | 5d0b9463f405cd293b2571a6dd3dc04cb914d695 /bfd/elf.c | |
parent | 40b9228581bb9bfaa3a444a6a19a9b41ebc68c40 (diff) | |
download | gdb-3a551c7a1b80fca579461774860574eabfd7f18f.zip gdb-3a551c7a1b80fca579461774860574eabfd7f18f.tar.gz gdb-3a551c7a1b80fca579461774860574eabfd7f18f.tar.bz2 |
PR23994, libbfd integer overflow
PR 23994
* aoutx.h: Include limits.h.
(get_reloc_upper_bound): Detect long overflow and return a file
too big error if it occurs.
* elf.c: Include limits.h.
(_bfd_elf_get_symtab_upper_bound): Detect long overflow and return
a file too big error if it occurs.
(_bfd_elf_get_dynamic_symtab_upper_bound): Likewise.
(_bfd_elf_get_dynamic_reloc_upper_bound): Likewise.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 32 |
1 files changed, 24 insertions, 8 deletions
@@ -35,6 +35,7 @@ SECTION /* For sparc64-cross-sparc32. */ #define _SYSCALL32 #include "sysdep.h" +#include <limits.h> #include "bfd.h" #include "bfdlink.h" #include "libbfd.h" @@ -8215,11 +8216,16 @@ error_return: long _bfd_elf_get_symtab_upper_bound (bfd *abfd) { - long symcount; + bfd_size_type symcount; long symtab_size; Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; + if (symcount >= LONG_MAX / sizeof (asymbol *)) + { + bfd_set_error (bfd_error_file_too_big); + return -1; + } symtab_size = (symcount + 1) * (sizeof (asymbol *)); if (symcount > 0) symtab_size -= sizeof (asymbol *); @@ -8230,7 +8236,7 @@ _bfd_elf_get_symtab_upper_bound (bfd *abfd) long _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) { - long symcount; + bfd_size_type symcount; long symtab_size; Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr; @@ -8241,6 +8247,11 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) } symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; + if (symcount >= LONG_MAX / sizeof (asymbol *)) + { + bfd_set_error (bfd_error_file_too_big); + return -1; + } symtab_size = (symcount + 1) * (sizeof (asymbol *)); if (symcount > 0) symtab_size -= sizeof (asymbol *); @@ -8310,7 +8321,7 @@ _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd, long _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) { - long ret; + bfd_size_type count; asection *s; if (elf_dynsymtab (abfd) == 0) @@ -8319,15 +8330,20 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) return -1; } - ret = sizeof (arelent *); + count = 1; for (s = abfd->sections; s != NULL; s = s->next) if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd) && (elf_section_data (s)->this_hdr.sh_type == SHT_REL || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)) - ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize) - * sizeof (arelent *)); - - return ret; + { + count += s->size / elf_section_data (s)->this_hdr.sh_entsize; + if (count > LONG_MAX / sizeof (arelent *)) + { + bfd_set_error (bfd_error_file_too_big); + return -1; + } + } + return count * sizeof (arelent *); } /* Canonicalize the dynamic relocation entries. Note that we return the |