alpha-vms: Sanity check ETIR__C_CTL_DFLOC index
authorAlan Modra <amodra@gmail.com>
Thu, 26 Mar 2020 00:19:27 +0000 (10:49 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 26 Mar 2020 00:32:58 +0000 (11:02 +1030)
I doubt anyone will want to create more than 16M debug location
entries.  If there is no bound the object format allows for 32-bit
indices and of course fuzzers find that and attempt allocation of up
to a 16G byte array.  The patch also fixes potential integer overflows
in calculating the array size.

* vms-alpha.c (dst_define_location): Limit size of dst_ptr_offsets
array.
(_bfd_vms_slurp_object_records): Rename "err" to "ok".

bfd/ChangeLog
bfd/vms-alpha.c

index cac27e37ec96666ef3f6172660690ea7c933738e..b5a2e7d447d5b13afa0c8c98de5aea278046b0ae 100644 (file)
@@ -1,3 +1,9 @@
+2020-03-26  Alan Modra  <amodra@gmail.com>
+
+       * vms-alpha.c (dst_define_location): Limit size of dst_ptr_offsets
+       array.
+       (_bfd_vms_slurp_object_records): Rename "err" to "ok".
+
 2020-03-25  Nick Clifton  <nickc@redhat.com>
 
        * cofflink.c (bfd_coff_get_internal_extra_pe_aouthdr): New
index c08d35d4b2e29b335324e1e40cee233779771661..594363b32afe7ad590515f9610851e5bf68a0402 100644 (file)
@@ -1553,6 +1553,14 @@ dst_define_location (bfd *abfd, unsigned int loc)
 {
   vms_debug2 ((4, "dst_define_location (%d)\n", (int)loc));
 
+  if (loc > 1 << 24)
+    {
+      /* 16M entries ought to be plenty.  */
+      bfd_set_error (bfd_error_bad_value);
+      _bfd_error_handler (_("dst_define_location %u too large"), loc);
+      return FALSE;
+    }
+
   /* Grow the ptr offset table if necessary.  */
   if (loc + 1 > PRIV (dst_ptr_offsets_count))
     {
@@ -2634,7 +2642,7 @@ _bfd_vms_slurp_eeom (bfd *abfd)
 static bfd_boolean
 _bfd_vms_slurp_object_records (bfd * abfd)
 {
-  bfd_boolean err;
+  bfd_boolean ok;
   int type;
 
   do
@@ -2651,27 +2659,27 @@ _bfd_vms_slurp_object_records (bfd * abfd)
       switch (type)
        {
        case EOBJ__C_EMH:
-         err = _bfd_vms_slurp_ehdr (abfd);
+         ok = _bfd_vms_slurp_ehdr (abfd);
          break;
        case EOBJ__C_EEOM:
-         err = _bfd_vms_slurp_eeom (abfd);
+         ok = _bfd_vms_slurp_eeom (abfd);
          break;
        case EOBJ__C_EGSD:
-         err = _bfd_vms_slurp_egsd (abfd);
+         ok = _bfd_vms_slurp_egsd (abfd);
          break;
        case EOBJ__C_ETIR:
-         err = TRUE; /* _bfd_vms_slurp_etir (abfd); */
+         ok = TRUE; /* _bfd_vms_slurp_etir (abfd); */
          break;
        case EOBJ__C_EDBG:
-         err = _bfd_vms_slurp_edbg (abfd);
+         ok = _bfd_vms_slurp_edbg (abfd);
          break;
        case EOBJ__C_ETBT:
-         err = _bfd_vms_slurp_etbt (abfd);
+         ok = _bfd_vms_slurp_etbt (abfd);
          break;
        default:
-         err = FALSE;
+         ok = FALSE;
        }
-      if (!err)
+      if (!ok)
        {
          vms_debug2 ((2, "slurp type %d failed\n", type));
          return FALSE;