# DF-3894 — VERDICT

**Status: not_reproduced (hardware-gated) — defect certain from source.**
**Impact class (on real hardware): persistent driver-state corruption →
adapter-wide I/O failure / firmware-contract violation (DoS).**

## Proof chain

1. `sys/dev/raid/mps/mps_sas.c:2765` — `tm = mps_alloc_command(sc);`
   `mps_alloc_command` pops from `sc->req_list`
   (`sys/dev/raid/mps/mpsvar.h:543-555`).
2. `sys/dev/raid/mps/mps_sas.c:2830-2833` — every exit path of
   `mpssas_resetdev_complete` calls `mpssas_free_tm(sc, tm)`.
3. `sys/dev/raid/mps/mps_sas.c:252-270` — `mpssas_free_tm` executes
   `--sc->sassc->tm_count` (line 262) and
   `mps_free_high_priority_command(sc, tm)` (line 269), which inserts onto
   `sc->high_priority_req_list` (mpsvar.h:576).
4. Nothing on the XPT_RESET_DEV path ever incremented `tm_count` (only
   `mpssas_alloc_tm` does, mps_sas.c:242) nor removed the command from
   `req_list`'s counterpart. So per occurrence:
   - `req_list` shrinks by one, permanently (normal-pool SMID leak);
   - `high_priority_req_list` grows by one, containing an SMID seeded to
     the *normal* list at init (`sys/dev/raid/mps/mps.c:864-867` puts only
     SMIDs `<= facts->HighPriorityCredit` on the hp list);
   - `tm_count` (u_int, `sys/dev/raid/mps/mps_sas.h:100`) underflows
     0 → 0xFFFFFFFF.
5. Poisoned-refcount consequence: the next `mpssas_alloc_tm` evaluates
   `sc->sassc->tm_count++ == 0` against UINT_MAX (false) → **no
   `xpt_freeze_simq` while a TM is in flight**, breaking the invariant
   documented at mps_sas.c:231-234 ("LSI's firmware requires us to stop
   sending commands when we're doing task management"); the matching
   `mpssas_free_tm` then decrements 0 → UINT_MAX again. From the first
   XPT_RESET_DEV onward, TM/scsi-io mutual exclusion never holds again.
6. Reachability: `mpssas_action` case XPT_RESET_DEV (mps_sas.c:981-984) —
   CAM error recovery (periph timeouts escalating to device reset) or
   `camcontrol reset`. Same defect shape as DF-1223 (mpr_sas.c:3351-3425),
   which was accepted with the alloc/free pool mismatch as root cause.

## Why not reproduced on this guest

No SAS2 HBA (env.txt, run.log); the SIM never attaches so XPT_RESET_DEV
cannot be routed to `mpssas_action`. On hardware, the divergence is
observable in `sysctl kern.ipc`-style driver counters after one
`camcontrol reset`: normal command pool count drops, hp pool count rises,
`tm_count` (viewable with MPS_TRACE logging, mps_sas.c:246-247/266-267)
prints 4294967295.

## Exploitability

No direct memory-safety primitive (the lists themselves stay consistent —
the corruption is *accounting*), but the end state is adapter-wide I/O
denial (pool exhaustion → CAM_RESRC_UNAVAIL for every subsequent command)
plus firmware-contract violation during task management. DoS class.

## Fix validation

Not testable on this guest. fix.diff swaps the allocation to
`mpssas_alloc_tm` (making alloc/free symmetric and the tm_count/freeze
discipline correct) and zeroes the request frame. This mirrors the mpr
DF-1223 fix direction.

## 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.
