]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR 33385 DST handling
authorAlan Modra <amodra@gmail.com>
Sun, 7 Sep 2025 22:56:43 +0000 (08:26 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 8 Sep 2025 12:47:46 +0000 (22:17 +0930)
Commit 816995444667, a fix for a fuzzer testcase resulting in a buffer
overflow, broke reading of DST.  DST is a special case where a first
pass over the section just sizes it.
Commit a3c0896d80d2, another buffer overflow fix, wrongly removed a
line incrementing DST record length.

* vms-alpha.c (image_write): Don't do bounds check for
sections in memory without contents.
(evax_bfd_print_dst): Add one to length.

bfd/vms-alpha.c

index d963ff7bb483494ec67d4da3b875cf1f22ff0ffd..1924a7611414907f42ffb4f17b13774a3420bbb1 100644 (file)
@@ -1605,37 +1605,43 @@ static bool
 image_write (bfd *abfd, unsigned char *ptr, unsigned int size)
 {
   asection *sec = PRIV (image_section);
-  size_t off = PRIV (image_offset);
 
-  /* Check bounds.  */
-  if (off > sec->size
-      || size > sec->size - off)
+  if ((sec->flags & SEC_IN_MEMORY) != 0
+      && sec->contents == NULL)
+    /* Not yet allocated.  Just increment size.  */
+    ;
+  else
     {
-      bfd_set_error (bfd_error_bad_value);
-      return false;
-    }
+      size_t off = PRIV (image_offset);
+      /* Check bounds.  */
+      if (off > sec->size
+         || size > sec->size - off)
+       {
+         bfd_set_error (bfd_error_bad_value);
+         return false;
+       }
 
 #if VMS_DEBUG
-  _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size,
-                 (long) off);
+      _bfd_vms_debug (8, "image_write from (%p, %d) to (%ld)\n", ptr, size,
+                     (long) off);
 #endif
 
-  if (PRIV (image_section)->contents != NULL)
-    memcpy (sec->contents + off, ptr, size);
-  else
-    {
-      unsigned int i;
-      for (i = 0; i < size; i++)
-       if (ptr[i] != 0)
-         {
-           bfd_set_error (bfd_error_bad_value);
-           return false;
-         }
-    }
-
+      if (sec->contents != NULL)
+       memcpy (sec->contents + off, ptr, size);
+      else
+       {
+         unsigned int i;
+         for (i = 0; i < size; i++)
+           if (ptr[i] != 0)
+             {
+               bfd_set_error (bfd_error_bad_value);
+               return false;
+             }
+       }
 #if VMS_DEBUG
-  _bfd_hexdump (9, ptr, size, 0);
+      _bfd_hexdump (9, ptr, size, 0);
 #endif
+    }
 
   PRIV (image_offset) += size;
   return true;
@@ -7493,6 +7499,8 @@ evax_bfd_print_dst (struct bfd *abfd, unsigned int dst_size, FILE *file)
       /* xgettext:c-format */
       fprintf (file, _(" type: %3u, len: %3u (at 0x%08x): "),
               type, len, off);
+      /* !!! The length is short by one!  */
+      len++;
       if (len > dst_size)
        len = dst_size;
       if (len < sizeof (dsth))