⬢ DragonFlyBSD Kernel Audit
DF-3805 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/mpr/mpr_sas.c b/sys/dev/raid/mpr/mpr_sas.c
index 1111111..2222222 100644
--- a/sys/dev/raid/mpr/mpr_sas.c
+++ b/sys/dev/raid/mpr/mpr_sas.c
@@ -2101,9 +2101,22 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
 		mprsas_set_ccbstatus(ccb, CAM_LUN_INVALID);
 		xpt_done(ccb);
 		return;
 	}
 
-	if (csio->ccb_h.flags & CAM_CDB_POINTER)
+	/*
+	 * DF-3805: cdb_len is caller-controlled (u8, up to 255) and nothing
+	 * in CAM bounds it.  The MPI2 CDB field is 32 bytes; copying more
+	 * overflows the request frame into the SGL and adjacent frames.
+	 */
+	if (csio->cdb_len < 6 || csio->cdb_len > 32) {
+		mpr_dprint(sc, MPR_ERROR, "%s cdb_len %d out of range\n",
+		    __func__, csio->cdb_len);
+		mprsas_set_ccbstatus(ccb, CAM_CCB_LEN_ERR);
+		xpt_done(ccb);
+		return;
+	}
+
+	if (csio->ccb_h.flags & CAM_CDB_POINTER)
 		bcopy(csio->cdb_io.cdb_ptr, &req->CDB.CDB32[0], csio->cdb_len);
 	else {
 		KASSERT(csio->cdb_len <= IOCDBLEN,