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,