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 when disassembling a corrupt VMS binary.


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

commit 72e84f969481f52daf6741c6bb4d0e92f9668389
Author: Nick Clifton <nickc@redhat.com>
Date:   Mon Jun 19 12:31:07 2017 +0100

    Fix access violation when disassembling a corrupt VMS binary.
    
    	PR 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
    	does not exceed the size of the record.

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

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9fd767b..a900e1a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2017-06-19  Nick Clifton  <nickc@redhat.com>
+
+	PR 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
+	does not exceed the size of the record.
+
 2017-06-19  Alan Modra  <amodra@gmail.com>
 
 	* config.bfd: Correct targ_underscore for cris.
diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
index 83b6638..be5c06f 100644
--- a/bfd/vms-alpha.c
+++ b/bfd/vms-alpha.c
@@ -1121,7 +1121,8 @@ add_symbol (bfd *abfd, const unsigned char *ascic)
 static bfd_boolean
 _bfd_vms_slurp_egsd (bfd *abfd)
 {
-  int gsd_type, gsd_size;
+  int gsd_type;
+  unsigned int gsd_size;
   unsigned char *vms_rec;
   unsigned long base_addr;
 
@@ -1133,7 +1134,7 @@ _bfd_vms_slurp_egsd (bfd *abfd)
   /* Calculate base address for each section.  */
   base_addr = 0L;
 
-  while (PRIV (recrd.rec_size) > 0)
+  while (PRIV (recrd.rec_size) > 4)
     {
       vms_rec = PRIV (recrd.rec);
 
@@ -1142,6 +1143,15 @@ _bfd_vms_slurp_egsd (bfd *abfd)
 
       vms_debug2 ((3, "egsd_type %d\n", gsd_type));
 
+      /* PR 21615: Check for size overflow.  */
+      if (PRIV (recrd.rec_size) < gsd_size)
+	{
+	  _bfd_error_handler (_("Corrupt EGSD record: size (%#x) is larger than remaining space (%#x)"),
+			      gsd_size, PRIV (recrd.rec_size));
+	  bfd_set_error (bfd_error_bad_value);
+	  return FALSE;
+	}
+
       switch (gsd_type)
 	{
 	case EGSD__C_PSC:


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