Download raw body.
trm: add bounds check on MsgBuf in trm_MsgInPhase0()
Hi all,
trm_MsgInPhase0() in sys/dev/ic/trm.c accumulates incoming SCSI message
bytes into MsgBuf[6] (trm.h line 207) via `sc->MsgBuf[sc->MsgCnt++] =
message_in_code` with no check that MsgCnt is within bounds. The only exits
from the accumulation state (TRM_EXTEND_MSGIN) are when specific message
types are recognized (WDTR at MsgCnt==4, SDTR at MsgCnt==5). If an
unrecognized extended message type is received, neither condition fires and
accumulation continues past the 6-byte buffer, resulting in a heap buffer
overflow that corrupts the freeSRB, goingSRB, waitingSRB, and sc_srb_mtx
members that follow MsgBuf in trm_softc. A malicious SCSI target could use
this to corrupt kernel heap state.
The patch adds a bounds check before the store. On overflow it rejects the
message via trm_EnableMsgOut() and resets SRBState, which mirrors the
existing reject_offer pattern used for invalid WDTR/SDTR lengths.
Best regards,
Stanislav Fort
Aisle Research
---
Draft patch:
diff --git a/sys/dev/ic/trm.c b/sys/dev/ic/trm.c
--- a/sys/dev/ic/trm.c
+++ b/sys/dev/ic/trm.c
@@ -1460,10 +1460,15 @@
} else {
/*
* We are collecting an extended message. Save the latest byte and then
* check to see if the message is complete. If so, process it.
*/
- sc->MsgBuf[sc->MsgCnt++] = message_in_code;
+ if (sc->MsgCnt >= sizeof(sc->MsgBuf)) {
+ pSRB->SRBState = TRM_FREE;
+ trm_EnableMsgOut(sc, MSG_MESSAGE_REJECT);
+ } else {
+ sc->MsgBuf[sc->MsgCnt++] = message_in_code;
+ }
#ifdef TRM_DEBUG0
printf("%s: sc->MsgBuf = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
sc->sc_device.dv_xname,
trm: add bounds check on MsgBuf in trm_MsgInPhase0()