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>
Mon, 7 Dec 2015 03:12:23 +0000 (13:42 +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.

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

bfd/ChangeLog
bfd/elfcode.h

index 0a92044..710b790 100644 (file)
@@ -1,5 +1,11 @@
 2015-12-07  Alan Modra  <amodra@gmail.com>
 
+       PR19323
+       * 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
        entry for R_PPC64_ENTRY.
index 26af1d1..915c8d5 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;