# DF-2524 — PoC evidence pack (verify run, 2026-10-14)

Finding: `sys/dev/disk/trm/trm.c` — `trm_Disconnect()` fetches
`pSRB = pDCB->pActiveSRB` and immediately dereferences `pSRB->pccb`
(trm.c:2354-2356). The author left a literal acknowledgment at :2355:
`/* bug pSRB=0 */`. A DISCONNECT / selection-timeout interrupt arriving
while `pACB->pActiveDCB != NULL` but that DCB has no active SRB
(`pActiveSRB == NULL` — e.g. racing bus-reset recovery
(`trm_RecoverSRB`) / abort paths clearing it, or a misbehaving device
asserting disconnect before selection completed) NULL-dereferences and
panics the kernel.

## How it was verified

Same production-handler rig (`df252x_trm_rig.c`, zero driver code):
fabricated ACB with `pActiveDCB` → a DCB whose `pActiveSRB` is NULL,
register-file emulation behind the kernel's own `bus_space` accessors,
and the **running kernel's own `trm_Interrupt()`** dispatched with
`INT_DISCONNECT` (the same branch a selection timeout takes,
trm.c:1323-1325).

## What the run showed (stock kernel)

```
df2524: offsetof(SRB,pccb)=88 -> faulting read at 0x58
df2524: dispatching production trm_Interrupt: DISCONNECT with
        pACB->pActiveDCB=0xfffff8008d9e4560, pDCB->pActiveSRB=NULL
Fatal user address access from kernel mode from sysctl at ffffffff82601ea6
Fatal trap 12: page fault while in kernel mode
fault virtual address	= 0x58
instruction pointer	= 0x8:0xffffffff82601ea6     <- trm.ko base + 0x1ea6
Stopped at      trm_Interrupt+0x166:    movq    0x58(%r12),%rax
db>
```

`0x58 = 88 = offsetof(struct _SRB, pccb)` — the exact
`pSRB->pccb->ccb_h.target_id` read at trm.c:2356 with `pSRB == NULL`.
Kernel panicked into ddb; full serial capture in `panic.txt`.

## Build / run (in guest, as root)

```
sh build.sh
kldload trm
sh run.sh                # kernel panics; capture with: vm.sh log 40
```

## Fix validation

`fix.diff` adds the missing NULL guard: a disconnect with no active SRB
now recovers the bus (`DO_CLRFIFO | DO_HWRESELECT`, same recovery the
`pDCB == NULL` exception branch uses) and returns. Validated on the
rebuilt kernel: `go=3` prints `df2524: trm_Interrupt RETURNED - no NULL
deref (guard present)` and the guest stays up.
