PR19323 memory allocation greater than 4G

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.
This commit is contained in:
Alan Modra 2015-12-07 13:41:36 +10:30
parent 549dba7104
commit c20f6f63ed
2 changed files with 15 additions and 1 deletions

View 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> 2015-12-07 Alan Modra <amodra@gmail.com>
* reloc.c (BFD_RELOC_PPC64_ENTRY): New. * reloc.c (BFD_RELOC_PPC64_ENTRY): New.

View File

@ -676,6 +676,10 @@ elf_object_p (bfd *abfd)
Elf_Internal_Shdr *shdrp; Elf_Internal_Shdr *shdrp;
unsigned int num_sec; 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; amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum;
i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt); i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
if (!i_shdrp) if (!i_shdrp)
@ -766,7 +770,11 @@ elf_object_p (bfd *abfd)
Elf_Internal_Phdr *i_phdr; Elf_Internal_Phdr *i_phdr;
unsigned int i; 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); elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
if (elf_tdata (abfd)->phdr == NULL) if (elf_tdata (abfd)->phdr == NULL)
goto got_no_match; goto got_no_match;