aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog28
-rw-r--r--bfd/coffcode.h51
-rw-r--r--bfd/coffgen.c13
-rw-r--r--bfd/elf.c32
-rw-r--r--bfd/elf64-sparc.c23
-rw-r--r--bfd/elfcode.h39
-rw-r--r--bfd/mach-o.c15
-rw-r--r--bfd/pdp11.c42
-rw-r--r--binutils/ChangeLog7
-rw-r--r--binutils/objdump.c37
10 files changed, 180 insertions, 107 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 18f1804..3e7d683 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,31 @@
+2019-03-12 Alan Modra <amodra@gmail.com>
+
+ * 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.
+
2019-03-08 Alan Modra <amodra@gmail.com>
PR 24311
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 2cea998..f4bfea0 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -423,8 +423,6 @@ static bfd_boolean coff_write_object_contents
(bfd *) ATTRIBUTE_UNUSED;
static bfd_boolean coff_set_section_contents
(bfd *, asection *, const void *, file_ptr, bfd_size_type);
-static void * buy_and_read
- (bfd *, file_ptr, bfd_size_type);
static bfd_boolean coff_slurp_line_table
(bfd *, asection *);
static bfd_boolean coff_slurp_symbol_table
@@ -4197,12 +4195,14 @@ coff_set_section_contents (bfd * abfd,
}
static void *
-buy_and_read (bfd *abfd, file_ptr where, bfd_size_type size)
+buy_and_read (bfd *abfd, file_ptr where,
+ bfd_size_type nmemb, bfd_size_type size)
{
- void * area = bfd_alloc (abfd, size);
+ void *area = bfd_alloc2 (abfd, nmemb, size);
if (!area)
return NULL;
+ size *= nmemb;
if (bfd_seek (abfd, where, SEEK_SET) != 0
|| bfd_bread (area, size, abfd) != size)
return NULL;
@@ -4255,7 +4255,6 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
{
LINENO *native_lineno;
alent *lineno_cache;
- bfd_size_type amt;
unsigned int counter;
alent *cache_ptr;
bfd_vma prev_offset = 0;
@@ -4278,13 +4277,15 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
return FALSE;
}
- amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent);
- lineno_cache = (alent *) bfd_alloc (abfd, amt);
+ lineno_cache = (alent *) bfd_alloc2 (abfd,
+ (bfd_size_type) asect->lineno_count + 1,
+ sizeof (alent));
if (lineno_cache == NULL)
return FALSE;
- amt = (bfd_size_type) bfd_coff_linesz (abfd) * asect->lineno_count;
- native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos, amt);
+ native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos,
+ asect->lineno_count,
+ bfd_coff_linesz (abfd));
if (native_lineno == NULL)
{
_bfd_error_handler
@@ -4393,7 +4394,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
alent *n_lineno_cache;
/* Create a table of functions. */
- func_table = (alent **) bfd_alloc (abfd, nbr_func * sizeof (alent *));
+ func_table = (alent **) bfd_alloc2 (abfd, nbr_func, sizeof (alent *));
if (func_table != NULL)
{
alent **p = func_table;
@@ -4409,8 +4410,8 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent);
/* Create the new sorted table. */
- amt = (bfd_size_type) asect->lineno_count * sizeof (alent);
- n_lineno_cache = (alent *) bfd_alloc (abfd, amt);
+ n_lineno_cache = (alent *) bfd_alloc2 (abfd, asect->lineno_count,
+ sizeof (alent));
if (n_lineno_cache != NULL)
{
alent *n_cache_ptr = n_lineno_cache;
@@ -4430,9 +4431,9 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
*n_cache_ptr++ = *old_ptr++;
while (old_ptr->line_number != 0);
}
- BFD_ASSERT ((bfd_size_type) (n_cache_ptr - n_lineno_cache) == (amt / sizeof (alent)));
- memcpy (lineno_cache, n_lineno_cache, amt);
+ memcpy (lineno_cache, n_lineno_cache,
+ asect->lineno_count * sizeof (alent));
}
else
ret = FALSE;
@@ -4455,7 +4456,6 @@ coff_slurp_symbol_table (bfd * abfd)
combined_entry_type *native_symbols;
coff_symbol_type *cached_area;
unsigned int *table_ptr;
- bfd_size_type amt;
unsigned int number_of_symbols = 0;
bfd_boolean ret = TRUE;
@@ -4467,15 +4467,14 @@ coff_slurp_symbol_table (bfd * abfd)
return FALSE;
/* Allocate enough room for all the symbols in cached form. */
- amt = obj_raw_syment_count (abfd);
- amt *= sizeof (coff_symbol_type);
- cached_area = (coff_symbol_type *) bfd_alloc (abfd, amt);
+ cached_area = (coff_symbol_type *) bfd_alloc2 (abfd,
+ obj_raw_syment_count (abfd),
+ sizeof (coff_symbol_type));
if (cached_area == NULL)
return FALSE;
- amt = obj_raw_syment_count (abfd);
- amt *= sizeof (unsigned int);
- table_ptr = (unsigned int *) bfd_zalloc (abfd, amt);
+ table_ptr = (unsigned int *) bfd_zalloc2 (abfd, obj_raw_syment_count (abfd),
+ sizeof (unsigned int));
if (table_ptr == NULL)
return FALSE;
@@ -4963,7 +4962,6 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
arelent *reloc_cache;
arelent *cache_ptr;
unsigned int idx;
- bfd_size_type amt;
if (asect->relocation)
return TRUE;
@@ -4974,10 +4972,11 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
if (!coff_slurp_symbol_table (abfd))
return FALSE;
- amt = (bfd_size_type) bfd_coff_relsz (abfd) * asect->reloc_count;
- native_relocs = (RELOC *) buy_and_read (abfd, asect->rel_filepos, amt);
- amt = (bfd_size_type) asect->reloc_count * sizeof (arelent);
- reloc_cache = (arelent *) bfd_alloc (abfd, amt);
+ native_relocs = (RELOC *) buy_and_read (abfd, asect->rel_filepos,
+ asect->reloc_count,
+ bfd_coff_relsz (abfd));
+ reloc_cache = (arelent *) bfd_alloc2 (abfd, asect->reloc_count,
+ sizeof (arelent));
if (reloc_cache == NULL || native_relocs == NULL)
return FALSE;
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 5f5c5f6..5db35c7 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -37,6 +37,7 @@
coff_data (abfd). */
#include "sysdep.h"
+#include <limits.h>
#include "bfd.h"
#include "libbfd.h"
#include "coff/internal.h"
@@ -2006,6 +2007,10 @@ coff_get_normalized_symtab (bfd *abfd)
return internal;
}
+#if GCC_VERSION >= 4003
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
long
coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
{
@@ -2014,8 +2019,16 @@ coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
+ 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
asymbol *
coff_make_empty_symbol (bfd *abfd)
diff --git a/bfd/elf.c b/bfd/elf.c
index 852b966..73fb869 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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;
diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c
index bd29be3..f523ce7 100644
--- a/bfd/elf64-sparc.c
+++ b/bfd/elf64-sparc.c
@@ -19,6 +19,7 @@
MA 02110-1301, USA. */
#include "sysdep.h"
+#include <limits.h>
#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
@@ -33,16 +34,36 @@
section can represent up to two relocs, we must tell the user to allocate
more space. */
+#if GCC_VERSION >= 4003
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
static long
elf64_sparc_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
{
+ if (sec->reloc_count >= LONG_MAX / 2 / sizeof (arelent *))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ return -1;
+ }
return (sec->reloc_count * 2 + 1) * sizeof (arelent *);
}
+#if GCC_VERSION >= 4003
+# pragma GCC diagnostic pop
+#endif
static long
elf64_sparc_get_dynamic_reloc_upper_bound (bfd *abfd)
{
- return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 2;
+ long ret = _bfd_elf_get_dynamic_reloc_upper_bound (abfd);
+ if (ret > LONG_MAX / 2)
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ ret = -1;
+ }
+ else if (ret > 0)
+ ret *= 2;
+ return ret;
}
/* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index ec5ea76..a0487b0 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -503,7 +503,6 @@ elf_object_p (bfd *abfd)
unsigned int shindex;
const struct elf_backend_data *ebd;
asection *s;
- bfd_size_type amt;
const bfd_target *target;
/* Read in the ELF header in external format. */
@@ -688,14 +687,14 @@ elf_object_p (bfd *abfd)
if (i_ehdrp->e_shnum > ((bfd_size_type) -1) / sizeof (*i_shdrp))
goto got_wrong_format_error;
#endif
- amt = sizeof (*i_shdrp) * (bfd_size_type) i_ehdrp->e_shnum;
- i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
+ i_shdrp = (Elf_Internal_Shdr *) bfd_alloc2 (abfd, i_ehdrp->e_shnum,
+ sizeof (*i_shdrp));
if (!i_shdrp)
goto got_no_match;
num_sec = i_ehdrp->e_shnum;
elf_numsections (abfd) = num_sec;
- amt = sizeof (i_shdrp) * num_sec;
- elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt);
+ elf_elfsections (abfd)
+ = (Elf_Internal_Shdr **) bfd_alloc2 (abfd, num_sec, sizeof (i_shdrp));
if (!elf_elfsections (abfd))
goto got_no_match;
@@ -789,8 +788,9 @@ elf_object_p (bfd *abfd)
if (bfd_get_file_size (abfd) > 0
&& i_ehdrp->e_phnum > bfd_get_file_size (abfd))
goto got_no_match;
- amt = (bfd_size_type) i_ehdrp->e_phnum * sizeof (*i_phdr);
- elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
+ elf_tdata (abfd)->phdr
+ = (Elf_Internal_Phdr *) bfd_alloc2 (abfd, i_ehdrp->e_phnum,
+ sizeof (*i_phdr));
if (elf_tdata (abfd)->phdr == NULL)
goto got_no_match;
if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
@@ -903,7 +903,8 @@ elf_write_relocs (bfd *abfd, asection *sec, void *data)
rela_hdr = elf_section_data (sec)->rel.hdr;
rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
- rela_hdr->contents = (unsigned char *) bfd_alloc (abfd, rela_hdr->sh_size);
+ rela_hdr->contents = (unsigned char *) bfd_alloc2 (abfd, sec->reloc_count,
+ rela_hdr->sh_entsize);
if (rela_hdr->contents == NULL)
{
*failedp = TRUE;
@@ -1040,9 +1041,8 @@ elf_write_shdrs_and_ehdr (bfd *abfd)
i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx;
/* at this point we've concocted all the ELF sections... */
- amt = i_ehdrp->e_shnum;
- amt *= sizeof (*x_shdrp);
- x_shdrp = (Elf_External_Shdr *) bfd_alloc (abfd, amt);
+ x_shdrp = (Elf_External_Shdr *) bfd_alloc2 (abfd, i_ehdrp->e_shnum,
+ sizeof (*x_shdrp));
if (!x_shdrp)
return FALSE;
@@ -1053,6 +1053,7 @@ elf_write_shdrs_and_ehdr (bfd *abfd)
#endif
elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count);
}
+ amt = (bfd_size_type) i_ehdrp->e_shnum * sizeof (*x_shdrp);
if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0
|| bfd_bwrite (x_shdrp, amt, abfd) != amt)
return FALSE;
@@ -1152,7 +1153,6 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
Elf_External_Versym *xver;
Elf_External_Versym *xverbuf = NULL;
const struct elf_backend_data *ebd;
- bfd_size_type amt;
/* Read each raw ELF symbol, converting from external ELF form to
internal ELF form, and then using the information to create a
@@ -1197,9 +1197,8 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
if (isymbuf == NULL)
return -1;
- amt = symcount;
- amt *= sizeof (elf_symbol_type);
- symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt);
+ symbase = (elf_symbol_type *) bfd_zalloc2 (abfd, symcount,
+ sizeof (elf_symbol_type));
if (symbase == (elf_symbol_type *) NULL)
goto error_return;
@@ -1519,7 +1518,6 @@ elf_slurp_reloc_table (bfd *abfd,
bfd_size_type reloc_count;
bfd_size_type reloc_count2;
arelent *relents;
- bfd_size_type amt;
if (asect->relocation != NULL)
return TRUE;
@@ -1557,8 +1555,8 @@ elf_slurp_reloc_table (bfd *abfd,
reloc_count2 = 0;
}
- amt = (reloc_count + reloc_count2) * sizeof (arelent);
- relents = (arelent *) bfd_alloc (abfd, amt);
+ relents = (arelent *) bfd_alloc2 (abfd, reloc_count + reloc_count2,
+ sizeof (arelent));
if (relents == NULL)
return FALSE;
@@ -1713,8 +1711,9 @@ NAME(_bfd_elf,bfd_from_remote_memory)
return NULL;
}
- x_phdrs = (Elf_External_Phdr *)
- bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs));
+ x_phdrs
+ = (Elf_External_Phdr *) bfd_malloc2 (i_ehdr.e_phnum,
+ sizeof (*x_phdrs) + sizeof (*i_phdrs));
if (x_phdrs == NULL)
return NULL;
err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs,
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 917335d..a9ca313 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -19,6 +19,7 @@
MA 02110-1301, USA. */
#include "sysdep.h"
+#include <limits.h>
#include "bfd.h"
#include "libbfd.h"
#include "libiberty.h"
@@ -1416,12 +1417,24 @@ bfd_mach_o_write_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
return TRUE;
}
+#if GCC_VERSION >= 4003
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
long
bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
asection *asect)
{
- return (asect->reloc_count + 1) * sizeof (arelent *);
+ 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
/* In addition to the need to byte-swap the symbol number, the bit positions
of the fields in the relocation information vary per target endian-ness. */
diff --git a/bfd/pdp11.c b/bfd/pdp11.c
index b16c78f..1d34047 100644
--- a/bfd/pdp11.c
+++ b/bfd/pdp11.c
@@ -66,6 +66,7 @@
&& N_MAGIC(x) != ZMAGIC)
#include "sysdep.h"
+#include <limits.h>
#include "bfd.h"
#define external_exec pdp11_external_exec
@@ -1980,6 +1981,8 @@ NAME (aout, canonicalize_reloc) (bfd *abfd,
long
NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect)
{
+ bfd_size_type count;
+
if (bfd_get_format (abfd) != bfd_object)
{
bfd_set_error (bfd_error_invalid_operation);
@@ -1987,28 +1990,25 @@ NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect)
}
if (asect->flags & SEC_CONSTRUCTOR)
- return (sizeof (arelent *) * (asect->reloc_count + 1));
-
- if (asect == obj_datasec (abfd))
- return (sizeof (arelent *)
- * ((exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd))
- + 1));
-
- if (asect == obj_textsec (abfd))
- return (sizeof (arelent *)
- * ((exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd))
- + 1));
-
- /* TODO: why are there two if statements for obj_bsssec()? */
-
- if (asect == obj_bsssec (abfd))
- return sizeof (arelent *);
-
- if (asect == obj_bsssec (abfd))
- return 0;
+ count = asect->reloc_count;
+ else if (asect == obj_datasec (abfd))
+ count = exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
+ else if (asect == obj_textsec (abfd))
+ count = exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
+ else if (asect == obj_bsssec (abfd))
+ count = 0;
+ else
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
- bfd_set_error (bfd_error_invalid_operation);
- return -1;
+ if (count >= LONG_MAX / sizeof (arelent *))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ return -1;
+ }
+ return (count + 1) * sizeof (arelent *);
}
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 605a7b3..d62f94a 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,10 @@
+2019-03-12 Alan Modra <amodra@gmail.com>
+
+ * 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.
+
2019-03-05 Nick Clifton <nickc@redhat.com>
PR 24295
diff --git a/binutils/objdump.c b/binutils/objdump.c
index ab091c1..3ef2716 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -2695,7 +2695,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
section->user_data = sec;
section->size = bfd_get_section_size (sec);
amt = section->size + 1;
- if (amt == 0 || amt > bfd_get_file_size (abfd))
+ if (amt == 0)
{
section->start = NULL;
free_debug_section (debug);
@@ -3640,47 +3640,28 @@ dump_relocs_in_section (bfd *abfd,
|| ((section->flags & SEC_RELOC) == 0))
return;
- relsize = bfd_get_reloc_upper_bound (abfd, section);
- if (relsize < 0)
- bfd_fatal (bfd_get_filename (abfd));
-
printf ("RELOCATION RECORDS FOR [%s]:", sanitize_string (section->name));
+ relsize = bfd_get_reloc_upper_bound (abfd, section);
if (relsize == 0)
{
printf (" (none)\n\n");
return;
}
- if ((bfd_get_file_flags (abfd) & (BFD_IN_MEMORY | BFD_LINKER_CREATED)) == 0
- && (/* Check that the size of the relocs is reasonable. Note that some
- file formats, eg aout, can have relocs whose internal size is
- larger than their external size, thus we check the size divided
- by four against the file size. See PR 23931 for an example of
- this. */
- ((ufile_ptr) (relsize / 4) > bfd_get_file_size (abfd))
- /* Also check the section's reloc count since if this is negative
- (or very large) the computation in bfd_get_reloc_upper_bound
- may have resulted in returning a small, positive integer.
- See PR 22508 for a reproducer.
-
- Note - we check against file size rather than section size as
- it is possible for there to be more relocs that apply to a
- section than there are bytes in that section. */
- || (section->reloc_count > bfd_get_file_size (abfd))))
+ if (relsize < 0)
+ relcount = relsize;
+ else
{
- printf (" (too many: %#x relocs)\n", section->reloc_count);
- bfd_set_error (bfd_error_file_truncated);
- bfd_fatal (bfd_get_filename (abfd));
+ relpp = (arelent **) xmalloc (relsize);
+ relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
}
- relpp = (arelent **) xmalloc (relsize);
- relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
-
if (relcount < 0)
{
printf ("\n");
- non_fatal (_("failed to read relocs in: %s"), sanitize_string (bfd_get_filename (abfd)));
+ non_fatal (_("failed to read relocs in: %s"),
+ sanitize_string (bfd_get_filename (abfd)));
bfd_fatal (_("error message was"));
}
else if (relcount == 0)