Upstream-Status: Backport CVE-2014-8502 fix. [YOCTO #7084] Signed-off-by: Armin Kuster From 5a4b0ccc20ba30caef53b01bee2c0aaa5b855339 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 28 Oct 2014 15:42:56 +0000 Subject: [PATCH] More fixes for corrupt binaries crashing the binutils. PR binutils/17512 * elf.c (bfd_section_from_shdr): Allocate and free the recursion detection table on a per-bfd basis. * peXXigen.c (pe_print_edata): Handle binaries with a truncated export table. --- bfd/ChangeLog | 8 ++++++++ bfd/elf.c | 16 +++++++++++++--- bfd/peXXigen.c | 9 +++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) Index: binutils-2.24/bfd/peXXigen.c =================================================================== --- binutils-2.24.orig/bfd/peXXigen.c +++ binutils-2.24/bfd/peXXigen.c @@ -1438,6 +1438,15 @@ pe_print_edata (bfd * abfd, void * vfile } } + /* PR 17512: Handle corrupt PE binaries. */ + if (datasize < 36) + { + fprintf (file, + _("\nThere is an export table in %s, but it is too small (%d)\n"), + section->name, (int) datasize); + return TRUE; + } + fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"), section->name, (unsigned long) addr); Index: binutils-2.24/bfd/elf.c =================================================================== --- binutils-2.24.orig/bfd/elf.c +++ binutils-2.24/bfd/elf.c @@ -1576,6 +1576,7 @@ bfd_section_from_shdr (bfd *abfd, unsign const char *name; bfd_boolean ret = TRUE; static bfd_boolean * sections_being_created = NULL; + static bfd * sections_being_created_abfd = NULL; static unsigned int nesting = 0; if (shindex >= elf_numsections (abfd)) @@ -1588,13 +1589,20 @@ bfd_section_from_shdr (bfd *abfd, unsign loop. Detect this here, by refusing to load a section that we are already in the process of loading. We only trigger this test if we have nested at least three sections deep as normal ELF binaries - can expect to recurse at least once. */ + can expect to recurse at least once. + + FIXME: It would be better if this array was attached to the bfd, + rather than being held in a static pointer. */ + + if (sections_being_created_abfd != abfd) + 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)); + sections_being_created_abfd = abfd; } if (sections_being_created [shindex]) { @@ -2098,7 +2106,10 @@ bfd_section_from_shdr (bfd *abfd, unsign if (sections_being_created) sections_being_created [shindex] = FALSE; if (-- nesting == 0) + { sections_being_created = NULL; + sections_being_created_abfd = abfd; + } return ret; }