⬢ DragonFlyBSD Kernel Audit
DF-2362 / fix.diff
← back to finding ↓ download raw
--- a/sys/cpu/x86_64/misc/x86_64-gdbstub.c
+++ b/sys/cpu/x86_64/misc/x86_64-gdbstub.c
@@ -564,9 +564,14 @@
 
 	    ptr = &remcomInBuffer[1];
 
+	    /* DF-2361 fix: regno must index the 8-byte slots of `registers`
+	     * (19 slots, sizeof 152).  NUM_REGS (22) never matched the
+	     * struct, and the missing lower bound let hexToInt's signed
+	     * result (e.g. -1 from "ffffffff") write below the object. */
 	    if (hexToInt (&ptr, &regno)
 		&& *ptr++ == '='
-		&& regno < NUM_REGS)
+		&& regno >= 0
+		&& regno < (int)(sizeof(registers) / 8))
 	      {
 		/* JG */
 		hex2mem (ptr, (vm_offset_t)&registers + regno * 8, 8);
@@ -585,6 +590,13 @@
 	      && *(ptr++) == ','
 	      && hexToInt (&ptr, &length))
 	    {
+	      /* DF-2362 fix: mem2hex emits 2 hex chars + NUL per byte
+	       * into the BUFMAX-byte remcomOutBuffer; length was
+	       * unbounded. */
+	      if (length > (BUFMAX - 1) / 2)
+		length = (BUFMAX - 1) / 2;
+	      if (length < 0)
+		length = 0;
 	      if (mem2hex((vm_offset_t) addr, remcomOutBuffer, length) == NULL)
 		strcpy (remcomOutBuffer, "E03");
 	      break;
@@ -604,6 +616,19 @@
 	      && hexToInt(&ptr, &length)
 	      && *(ptr++) == ':')
 	    {
+	      /* DF-2362 fix: hex2mem consumes 2 chars per byte from
+	       * remcomInBuffer, past the packet NUL and past the array
+	       * end when the declared length exceeds the supplied data. */
+	      {
+		int avail = gdb_strlen (ptr) / 2;
+
+		if (length > avail)
+		  length = avail;
+		if (length > (BUFMAX - 1) / 2)
+		  length = (BUFMAX - 1) / 2;
+		if (length < 0)
+		  length = 0;
+	      }
 	      if (hex2mem(ptr, (vm_offset_t) addr, length) == NULL)
 		strcpy (remcomOutBuffer, "E03");
 	      else