DF-2523 / fix.diff
--- a/sys/dev/disk/trm/trm.c +++ b/sys/dev/disk/trm/trm.c @@ -2425,9 +2425,27 @@ /* 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; + if (pDCB != NULL) { + int n = pACB->DeviceCnt; + + while (n-- > 0 && + RselTarLunId != *((u_int16_t *) &pDCB->TargetID)) { + /* get pDCB of the reselect id (list is circular) */ + pDCB = pDCB->pNextDCB; + } + if (n < 0) + pDCB = NULL; + } + if (pDCB == NULL) { + /* + * Reselection from a target/LUN with no DCB (malicious + * or glitching device). Never spin forever at interrupt + * context: drop the connection and let the bus recover. + */ + trm_reg_write8(STOPDMAXFER, TRMREG_DMA_CONTROL); + trm_reg_write16((DO_CLRFIFO | DO_HWRESELECT), + TRMREG_SCSI_CONTROL); + return; } pACB->pActiveDCB = pDCB; |