asan: alpha-vms: null dereference
authorAlan Modra <amodra@gmail.com>
Sun, 15 Mar 2020 22:14:38 +0000 (08:44 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 16 Mar 2020 00:21:53 +0000 (10:51 +1030)
* 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.

bfd/ChangeLog
bfd/vms-alpha.c

index 5f85a4b37c07b56ca31f552a1d71d614f54f8861..cd421649cc824abc5b2e866a8d3f761e166c5fc9 100644 (file)
@@ -1,3 +1,11 @@
+2020-03-16  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2020-03-14  Kamil Rytarowski  <n54@gmx.com>
 
        * configure.ac: Include netbsd-core.lo for all NetBSD arm and mips
index 241dab340d7c723f902c3337e79c6f68ca3b39bc..c08d35d4b2e29b335324e1e40cee233779771661 100644 (file)
@@ -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;