Upstream-Status: Backport

CVE-2014-8502 fix.

[YOCTO #7084]

Signed-off-by: Armin Kuster <akuster808@gmail.com>

From 5a4b0ccc20ba30caef53b01bee2c0aaa5b855339 Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
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;
 }
 
