DF-1238 / fix.diff
diff --git a/sys/dev/disk/trm/trm.c b/sys/dev/disk/trm/trm.c index 73425d7c..9870a7de 100644 --- a/sys/dev/disk/trm/trm.c +++ b/sys/dev/disk/trm/trm.c @@ -2425,9 +2425,29 @@ trm_Reselect(PACB pACB) /* Read Reselected Target Id and LUN */ RselTarLunId = trm_reg_read16(TRMREG_SCSI_TARGETID) & 0x1FFF; pDCB = pACB->pLinkDCB; - while (RselTarLunId != *((u_int16_t *) &pDCB->TargetID)) { - /* get pDCB of the reselect id */ - pDCB = pDCB->pNextDCB; + { + u_int16_t dcb_i; + for (dcb_i = 0; dcb_i < pACB->DeviceCnt; dcb_i++) { + if (RselTarLunId == *((u_int16_t *) &pDCB->TargetID)) + break; + /* get pDCB of the reselect id */ + pDCB = pDCB->pNextDCB; + } + if (dcb_i >= pACB->DeviceCnt) { + /* + * No DCB matched the reselected target/LUN. A + * malicious or misbehaving target could reselect with + * an unknown ID/LUN and loop the old unbounded walk + * forever in interrupt context. Treat as an + * unexpected reselection and abort via TmpSRB. + */ + pSRB = &pACB->TmpSRB; + pSRB->SRBState = SRB_UNEXPECT_RESEL; + pACB->pActiveDCB = NULL; + pDCB->pActiveSRB = pSRB; + trm_EnableMsgOutAbort1(pACB, pSRB); + return; + } } pACB->pActiveDCB = pDCB; |