DragonFlyBSD Kernel Audit
DF-0973 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/bus/cam/cam_xpt.c b/sys/bus/cam/cam_xpt.c
--- a/sys/bus/cam/cam_xpt.c
+++ b/sys/bus/cam/cam_xpt.c
@@ -6237,6 +6237,16 @@
 			struct scsi_control_page *page;
 			u_int8_t *offset;
 
+			/*
+			 * DF-0973: blk_desc_len is device-controlled; make sure
+			 * the control page (and its queue_flags field) lies within
+			 * the buffer we actually received.
+			 */
+			if ((u_int8_t *)&mode_hdr[1] - (u_int8_t *)mode_hdr +
+			    mode_hdr->blk_desc_len +
+			    offsetof(struct scsi_control_page, queue_flags) + 1 >
+			    csio->dxfer_len - csio->resid)
+				break;
 			offset = ((u_int8_t *)&mode_hdr[1])
 			    + mode_hdr->blk_desc_len;
 			page = (struct scsi_control_page *)offset;