DF-1125 / fix.diff
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; |