This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix access violation disassembling a corrupt VMS binary.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=80053e466b3a8055334b9be9bac7d99e0d617cbe

commit 80053e466b3a8055334b9be9bac7d99e0d617cbe
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Jun 19 13:01:57 2017 +0100

    Fix access violation disassembling a corrupt VMS binary.
    
    	PR binutils/21611
    	* vms-alpha.c (_bfd_vms_slurp_eihs): Check for invalid offset
    	before reading the EIHS structure entries.

Diff:
---
 bfd/ChangeLog   |  8 +++++++-
 bfd/vms-alpha.c | 27 +++++++++++++++++++++------
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a900e1a..6aa4c90 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,6 +1,12 @@
 2017-06-19  Nick Clifton  <nickc@redhat.com>
 
-	PR 21615
+	PR binutils/21611
+	* vms-alpha.c (_bfd_vms_slurp_eihs): Check for invalid offset
+	before reading the EIHS structure entries.
+
+2017-06-19  Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/21615
 	* vms-alpha.c (_bfd_vms_slurp_egsd): Use unsigned int for
 	gsd_size.  Check that there are enough bytes remaining to read the
 	type and size of the next egsd.  Check that the size of the egsd
diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
index be5c06f..73f6976 100644
--- a/bfd/vms-alpha.c
+++ b/bfd/vms-alpha.c
@@ -622,14 +622,29 @@ static bfd_boolean
 _bfd_vms_slurp_eihs (bfd *abfd, unsigned int offset)
 {
   unsigned char *p = PRIV (recrd.rec) + offset;
-  unsigned int gstvbn = bfd_getl32 (p + EIHS__L_GSTVBN);
-  unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS__L_GSTSIZE);
-  unsigned int dstvbn = bfd_getl32 (p + EIHS__L_DSTVBN);
-  unsigned int dstsize = bfd_getl32 (p + EIHS__L_DSTSIZE);
-  unsigned int dmtvbn = bfd_getl32 (p + EIHS__L_DMTVBN);
-  unsigned int dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES);
+  unsigned int gstvbn;
+  unsigned int gstsize ATTRIBUTE_UNUSED;
+  unsigned int dstvbn;
+  unsigned int dstsize;
+  unsigned int dmtvbn;
+  unsigned int dmtbytes;
   asection *section;
 
+  /* PR 21611: Check that offset is valid.  */
+  if (offset > PRIV (recrd.rec_size) - (EIHS__L_DMTBYTES + 4))
+    {
+      _bfd_error_handler (_("Unable to read EIHS record at offset %#x"), offset); 
+      bfd_set_error (bfd_error_file_truncated);
+      return FALSE;
+    }
+
+  gstvbn   = bfd_getl32 (p + EIHS__L_GSTVBN);
+  gstsize  = bfd_getl32 (p + EIHS__L_GSTSIZE);
+  dstvbn   = bfd_getl32 (p + EIHS__L_DSTVBN);
+  dstsize  = bfd_getl32 (p + EIHS__L_DSTSIZE);
+  dmtvbn   = bfd_getl32 (p + EIHS__L_DMTVBN);
+  dmtbytes = bfd_getl32 (p + EIHS__L_DMTBYTES);
+
 #if VMS_DEBUG
   vms_debug (8, "_bfd_vms_slurp_ihs\n");
   vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]