PR 33385 DST handling

Message ID aL7O7Xum5eh2zA6b@squeak.grove.modra.org
State New
Headers
Series PR 33385 DST handling |

Commit Message

Alan Modra Sept. 8, 2025, 12:41 p.m. UTC
  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.
  

Patch

diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
index d963ff7bb48..1924a761141 100644
--- a/bfd/vms-alpha.c
+++ b/bfd/vms-alpha.c
@@ -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))