asan: alpha-vms: null dereference

Message ID 20200316023612.GJ23597@bubble.grove.modra.org
State New
Headers show
Series
  • asan: alpha-vms: null dereference
Related show

Commit Message

David Faust via Binutils March 16, 2020, 2:36 a.m.
* vms-alpha.c (dst_restore_location): Validate index into
	dst_ptr_offsets array before accessing.  Return status.
	(dst_retrieve_location): Similarly, making "loc" parameter a
	pointer to return value.
	(_bfd_vms_slurp_etir): Update calls to above functions.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
index 241dab340d..c08d35d4b2 100644
--- a/bfd/vms-alpha.c
+++ b/bfd/vms-alpha.c
@@ -1570,22 +1570,32 @@  dst_define_location (bfd *abfd, unsigned int loc)
 
 /* Restore saved DST location counter from specified index.  */
 
-static void
+static bfd_boolean
 dst_restore_location (bfd *abfd, unsigned int loc)
 {
   vms_debug2 ((4, "dst_restore_location (%d)\n", (int)loc));
 
-  PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc];
+  if (loc < PRIV (dst_ptr_offsets_count))
+    {
+      PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc];
+      return TRUE;
+    }
+  return FALSE;
 }
 
 /* Retrieve saved DST location counter from specified index.  */
 
-static unsigned int
-dst_retrieve_location (bfd *abfd, unsigned int loc)
+static bfd_boolean
+dst_retrieve_location (bfd *abfd, bfd_vma *loc)
 {
-  vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int)loc));
+  vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int) *loc));
 
-  return PRIV (dst_ptr_offsets)[loc];
+  if (*loc < PRIV (dst_ptr_offsets_count))
+    {
+      *loc = PRIV (dst_ptr_offsets)[*loc];
+      return TRUE;
+    }
+  return FALSE;
 }
 
 /* Write multiple bytes to section image.  */
@@ -2326,7 +2336,12 @@  _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
 	    return FALSE;
 	  if (rel1 != RELC_NONE)
 	    goto bad_context;
-	  dst_restore_location (abfd, op1);
+	  if (!dst_restore_location (abfd, op1))
+	    {
+	      bfd_set_error (bfd_error_bad_value);
+	      _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STLOC");
+	      return FALSE;
+	    }
 	  break;
 
 	  /* Stack defined location: pop index, push location counter from index
@@ -2336,8 +2351,13 @@  _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
 	    return FALSE;
 	  if (rel1 != RELC_NONE)
 	    goto bad_context;
-	  if (!_bfd_vms_push (abfd, dst_retrieve_location (abfd, op1),
-			      RELC_NONE))
+	  if (!dst_retrieve_location (abfd, &op1))
+	    {
+	      bfd_set_error (bfd_error_bad_value);
+	      _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STKDL");
+	      return FALSE;
+	    }
+	  if (!_bfd_vms_push (abfd, op1, RELC_NONE))
 	    return FALSE;
 	  break;