Fix seg-fault in objdump when run on a fuzzed PE binary.
authorNick Clifton <nickc@redhat.com>
Wed, 14 Sep 2016 14:32:01 +0000 (15:32 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 14 Sep 2016 14:32:01 +0000 (15:32 +0100)
PR binutils/20605
* peicode.h (pe_bfd_read_buildid): Check that the Data Directory
contains a valid size for the Debug directory.

bfd/ChangeLog
bfd/peicode.h

index 7414c39f3768328e438b0803326199d3c0d3f351..567e18f195b26fb60fee8d6518fe955770f24d45 100644 (file)
@@ -1,3 +1,9 @@
+2016-09-14  Nick Clifton  <nickc@redhat.com>
+
+       PR binutils/20605
+       * peicode.h (pe_bfd_read_buildid): Check that the Data Directory
+       contains a valid size for the Debug directory.
+
 2016-09-14  Bhushan Attarde  <bhushan.attarde@imgtec.com>
 
        * format.c (struct bfd_preserve): New "build_id" field.
index a33e71bebef584df0fe362060d670c483b2a2ebb..fc8b20f7f63d9b5800338faf1fd72d6f559b5e92 100644 (file)
@@ -1289,7 +1289,7 @@ pe_ILF_object_p (bfd * abfd)
 }
 
 static void
-pe_bfd_read_buildid(bfd *abfd)
+pe_bfd_read_buildid (bfd *abfd)
 {
   pe_data_type *pe = pe_data (abfd);
   struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
@@ -1306,7 +1306,7 @@ pe_bfd_read_buildid(bfd *abfd)
 
   addr += extra->ImageBase;
 
-  /* Search for the section containing the DebugDirectory */
+  /* Search for the section containing the DebugDirectory */
   for (section = abfd->sections; section != NULL; section = section->next)
     {
       if ((addr >= section->vma) && (addr < (section->vma + section->size)))
@@ -1314,16 +1314,21 @@ pe_bfd_read_buildid(bfd *abfd)
     }
 
   if (section == NULL)
-    {
-      return;
-    }
-  else if (!(section->flags & SEC_HAS_CONTENTS))
-    {
-      return;
-    }
+    return;
+
+  if (!(section->flags & SEC_HAS_CONTENTS))
+    return;
 
   dataoff = addr - section->vma;
 
+  /* PR 20605: Make sure that the data is really there.  */
+  if (dataoff + size > section->size)
+    {
+      _bfd_error_handler (_("%B: Error: Debug Data ends beyond end of debug directory."),
+                         abfd);
+      return;
+    }
+  
   /* Read the whole section. */
   if (!bfd_malloc_and_get_section (abfd, section, &data))
     {
@@ -1354,8 +1359,8 @@ pe_bfd_read_buildid(bfd *abfd)
                                               (file_ptr) idd.PointerToRawData,
                                               idd.SizeOfData, cvinfo))
             {
-              struct bfd_build_id* build_id = bfd_alloc(abfd,
-                         sizeof(struct bfd_build_id) + cvinfo->SignatureLength);
+              struct bfd_build_id* build_id = bfd_alloc (abfd,
+                         sizeof (struct bfd_build_id) + cvinfo->SignatureLength);
               if (build_id)
                 {
                   build_id->size = cvinfo->SignatureLength;