DragonFlyBSD Kernel Audit
DF-1563 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c b/sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c
--- a/sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c
+++ b/sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c
@@ -721,6 +721,22 @@
 			if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS)
 				pCmd->flags.physical_sg = 1;
 
+			/*
+			 * DF-1563: pCmd->psg aliases ext->psg which has
+			 * exactly os_max_sg_descriptors entries.  Reject
+			 * any sglist_cnt that would overflow that fixed
+			 * array (otherwise the loop below writes
+			 * (sglist_cnt-N)*sizeof(SG) bytes into the adjacent
+			 * M_DEVBUF slab).
+			 */
+			if (ccb->csio.sglist_cnt > os_max_sg_descriptors) {
+				cmdext_put(ext);
+				ldm_free_cmds(pCmd);
+				ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+				xpt_done(ccb);
+				return;
+			}
+
 			for (idx = 0; idx < ccb->csio.sglist_cnt; idx++) {
 				pCmd->psg[idx].addr.bus = sgList[idx].ds_addr;
 				pCmd->psg[idx].size = sgList[idx].ds_len;