]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR19323 memory allocation greater than 4G
authorAlan Modra <amodra@gmail.com>
Mon, 7 Dec 2015 03:11:36 +0000 (13:41 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 10 Dec 2015 13:48:49 +0000 (00:18 +1030)
On 32-bit targets, memory requested for program/section headers on a
fuzzed binary can wrap to 0.  A bfd_alloc of zero bytes actually
returns a one byte allocation rather than a NULL pointer.  This then
leads to buffer overflows.

Making this check unconditional triggers an extremely annoying gcc-5
warning.

PR 19323
* elfcode.h (elf_object_p): Check for ridiculous e_shnum and
e_phnum values.

bfd/ChangeLog
bfd/elfcode.h

index 131435a83c0d7c9bfe54d3d271539003edf2eb67..0dc691dd3dcd571f2bc2149039031d51be7f86a0 100644 (file)
@@ -1,6 +1,11 @@
 2015-12-10  Alan Modra  <amodra@gmail.com>
 
        Apply from master.
+       2015-12-07  Alan Modra  <amodra@gmail.com>
+       PR 19323
+       * elfcode.h (elf_object_p): Check for ridiculous e_shnum and
+       e_phnum values.
+
        2015-12-07  Alan Modra  <amodra@gmail.com>
        * reloc.c (BFD_RELOC_PPC64_ENTRY): New.
        * elf64-ppc.c (reloc_howto_type ppc64_elf_howto_raw): Add
index 26af1d18c286e8dcf0795eb6440985021ac0c3c1..915c8d5f88ba4991416a2dc6e67b3530a413721d 100644 (file)
@@ -676,6 +676,10 @@ elf_object_p (bfd *abfd)
       Elf_Internal_Shdr *shdrp;
       unsigned int num_sec;
 
+#ifndef BFD64
+      if (i_ehdrp->e_shnum > ((bfd_size_type) -1) / sizeof (*i_shdrp))
+       goto got_wrong_format_error;
+#endif
       amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum;
       i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
       if (!i_shdrp)
@@ -766,7 +770,11 @@ elf_object_p (bfd *abfd)
       Elf_Internal_Phdr *i_phdr;
       unsigned int i;
 
-      amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr);
+#ifndef BFD64
+      if (i_ehdrp->e_phnum > ((bfd_size_type) -1) / sizeof (*i_phdr))
+       goto got_wrong_format_error;
+#endif
+      amt = i_ehdrp->e_phnum * sizeof (*i_phdr);
       elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
       if (elf_tdata (abfd)->phdr == NULL)
        goto got_no_match;