⬢ DragonFlyBSD Kernel Audit
DF-2261 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/cam/cam_xpt.c	2026-10-21 04:27:46.575051812 +0000
+++ b/sys/bus/cam/cam_xpt.c	2026-10-21 04:27:46.575051812 +0000
@@ -1,13 +1,26 @@
 		} else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP
 			&& (serial_buf->length > 0)) {
+			u_int8_t serial_len;
+
+			/*
+			 * DF-2261: serial_buf->length is device-controlled
+			 * (up to 255) but serial_num[] holds 251 bytes of
+			 * the 255-byte allocation; unclamped it read past
+			 * the allocation, and serial_num_len > 252 then
+			 * overflowed ccb_getdev.serial_num via
+			 * XPT_GDEV_TYPE.
+			 */
+			serial_len = serial_buf->length;
+			if (serial_len > SVPD_SERIAL_NUM_SIZE)
+				serial_len = SVPD_SERIAL_NUM_SIZE;
 
 			have_serialnum = 1;
 			path->device->serial_num =
-				kmalloc((serial_buf->length + 1),
+				kmalloc((serial_len + 1),
 				       M_CAMXPT, M_INTWAIT);
 			bcopy(serial_buf->serial_num,
 			      path->device->serial_num,
-			      serial_buf->length);
-			path->device->serial_num_len = serial_buf->length;
-			path->device->serial_num[serial_buf->length] = '\0';
+			      serial_len);
+			path->device->serial_num_len = serial_len;
+			path->device->serial_num[serial_len] = '\0';
 		} else if (cam_periph_error(done_ccb, 0,
\ No newline at end of file
--- a/sys/bus/cam/cam_xpt.c	2026-10-21 04:27:46.575051812 +0000
+++ b/sys/bus/cam/cam_xpt.c	2026-10-21 04:27:46.575051812 +0000
@@ -1,5 +1,12 @@
 			cgd->serial_num_len = dev->serial_num_len;
 			if ((dev->serial_num_len > 0)
-			 && (dev->serial_num != NULL))
+			 && (dev->serial_num != NULL)) {
+				u_int8_t copy_len = dev->serial_num_len;
+
+				/* DF-2261: never write past
+				 * ccb_getdev.serial_num[252] */
+				if (copy_len > sizeof(cgd->serial_num))
+					copy_len = sizeof(cgd->serial_num);
 				bcopy(dev->serial_num, cgd->serial_num,
-				      dev->serial_num_len);
\ No newline at end of file
+				      copy_len);
+			}
\ No newline at end of file