DragonFlyBSD Kernel Audit
DF-1125 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/isp/isp.c b/sys/dev/disk/isp/isp.c
--- a/sys/dev/disk/isp/isp.c
+++ b/sys/dev/disk/isp/isp.c
@@ -5223,6 +5223,13 @@
 		if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
 			resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
 			rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
+			/* The FCP response length comes from firmware DMA and is
+			 * attacker-controllable via a remote FC target.  The inline
+			 * req_rsp_sense[] buffer is only 28 bytes and shares the
+			 * queue entry with the sense data; clamp rlen so the sense
+			 * pointer below cannot run past the 64-byte stack entry. */
+			if (rlen > sizeof(((isp24xx_statusreq_t *)sp)->req_rsp_sense))
+				rlen = sizeof(((isp24xx_statusreq_t *)sp)->req_rsp_sense);
 		} else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
 			resp = sp->req_response;
 			rlen = sp->req_response_len;
@@ -5238,6 +5245,11 @@
 				snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
 				snsp += rlen;
 				slen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
+				/* Sense data shares the 28-byte req_rsp_sense[] buffer
+				 * with the (already clamped) response; bound slen so the
+				 * XS_SAVE_SENSE memcpy cannot read past the entry. */
+				if (slen > sizeof(((isp24xx_statusreq_t *)sp)->req_rsp_sense) - rlen)
+					slen = sizeof(((isp24xx_statusreq_t *)sp)->req_rsp_sense) - rlen;
 			} else {
 				snsp = sp->req_sense_data;
 				slen = sp->req_sense_len;