# DF-4241 — VERDICT

**REPRODUCED** (kernel list corruption + double `xpt_done` → CAM completion panic; fix
validated on a rebuilt kernel).

## Chain, all production code

0. rig registers a real cam_sim over a fabricated post-attach softc (real bus_dma; free
   list built by production `dptallocccbs`); the sim's handlers are the shipped kernel's
   `dpt_action`/`dpt_poll`.
1. `./dfdpt_ctl queue` → `xpt_action` with a REAL `xpt_alloc_ccb`'d XPT_SCSI_IO →
   production `dpt_action` (0xffffffff80438010) → `dptexecuteccb` → dccb `X`
   (0xfffff801185b78e8) is `DCCB_ACTIVE`, on `pending_ccb_list`, callout armed,
   `ccb_h.status = CAM_SIM_QUEUED`, `ccb_dccb_ptr = X`.
2. `./dfdpt_ctl intr 0 1 0 0` (legit single status packet, hba_stat=0/scsi_stat=0/EOC=1,
   DMA'd into the sp by the "device"): production `dpt_intr` (0xffffffff80439670) maps the
   busaddr to X (only range-checked, dpt_scsi.c:1518-1527), completes it:
   `CAM_REQ_CMP`, `rig_done` fires (`comp=1`), `dptfreeccb` inserts X into the free list
   once. Everything clean.
3. `./dfdpt_ctl dupalias 0` — the device delivers a **duplicate** of the same packet.
   Production `dpt_intr` again maps X — still no `DCCB_ACTIVE` check — and:
   - `callout_stop` on the stale (already completed, CAM-owned) ccb's timeout;
   - `dptfreeccb(dpt, X)` with `state == DCCB_FREE`: no LIST_REMOVE, but
     `SLIST_INSERT_HEAD` runs again → **self-loop** (`head->next == head`, rig prints
     `SELFLOOP=1`, `dups=200/200` = unbounded walk, `free_dccbs` inflated to 1);
   - `xpt_done(ccb)` **a second time** → the completed ccb is re-enqueued on
     `sim_doneq`.
4. Still inside the same ioctl (rig lock held, so the CAM SWI cannot race the capture),
   two more real XPT_SCSI_IOs are queued: production `dptgetccb` pops the self-looped
   head twice → **both CCBs get the SAME dccb** (`SHARED=1`) — the shared-command-block
   UAF; the rig then releases the lock.
5. The CAM software-interrupt handler processes the corrupt `sim_doneq`:
   `panic: Bad link elm 0xfffff801185f0ec0 prev->next != elm` in `camisr_runqueue` —
   and 0xfffff801185f0ec0 is exactly the CCB from step 1 (`QUEUE id=0 ccb=...`).
   System down in DDB. (First observed serendipitously in an earlier boot —
   `run.2.log` — then reproduced cleanly with the capture-under-lock sequence —
   `run.log`.)

## Fix validation (fix.diff applied, kernel rebuilt + rebooted)

Same rig, same sequence (`fix_validation.log`):
- the duplicate packet now hits the added guard: `dpt9: status packet for inactive CCB
  ignored` (production `dpt_intr`, dpt_scsi.c:1551ff in the patched file), IRQ cleared,
  loop continues — no double free, no double `xpt_done`;
- free list healthy: `SELFLOOP=0 dups=1 walk=16 ctr=0`;
- no aliasing: the two subsequent queues got **different** dccbs
  (`0x...8e8` vs `0x...850`, `SHARED=0`);
- no panic: `dupalias` returned to userland (`DUPALIAS_RC=0`), guest stayed up;
- the legitimate completion path is unaffected (`comp=1`, `CAM_REQ_CMP` — captured in
  the same log).

## Threat model

`sp->ccb_busaddr` is DMA'd by the controller (dpt.h:523): a hostile device (or
passed-through/virtualized HBA) sends a duplicate/fabricated completion for any in-range
busaddr. The SMP variant in the finding (dpttimeout → dpt_intr racing the hardirq,
dpt_scsi.c:1696) is the same missing-in-flight-check root cause; the demonstrated
primitive (device-fed double completion) is the superset.

## Caveats

- The rig calls `dpt_intr` from an ioctl thread (not a hardirq) — irrelevant to the bug:
  the corruption happens inside `dpt_intr` proper, and the detonation happens in the
  CAM SWI thread exactly as it would from a real interrupt.
- The rig's duplicate is byte-identical to the legit packet, which is exactly the
  "duplicate completion" case; the fabricated-in-range-busaddr case (any other dccb) is
  the same code path with the same missing check.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
