Index | Thread | Search

From:
Stanislav Fort <stanislav.fort@aisle.com>
Subject:
trm: add bounds check on MsgBuf in trm_MsgInPhase0()
To:
tech@openbsd.org
Cc:
Disclosure <disclosure@aisle.com>
Date:
Mon, 13 Apr 2026 09:39:04 +0200

Download raw body.

Thread
  • Stanislav Fort:

    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,