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 0a92044f3bfc70c177d7a4286033189c05e4ec69..710b790caf49a4bb7e414026c03877de5677f31a 100644 (file)
@@ -1,3 +1,9 @@
+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.
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;