# DF-4398 — tws_scsi_err_complete touches the ccb AFTER xpt_done (callout_stop on a surrendered ccb)

## What
`sys/dev/raid/tws/tws_cam.c:593-596` — `tws_scsi_err_complete()` calls `xpt_done(ccb)`
(surrendering the ccb to CAM: it is queued to `sim_doneq` and processed by the
 cambio SWI, `sys/bus/cam/cam_xpt.c:4891-4926`) and only THEN executes
`callout_stop(req->ccb_ptr->ccb_h.timeout_ch)` — reading `req->ccb_ptr->ccb_h.timeout_ch`
out of the ccb and stopping the callout it points at. Once `xpt_done` has queued the
ccb, the peripheral's done routine (`dadone` et al.) may complete the transaction and
recycle (`xpt_release_ccb` back to the periph pool) or free the ccb concurrently; the
correct order — used by this very driver in `tws_scsi_complete()` (`callout_stop` at
:365 BEFORE `xpt_done` at :371) and in `tws_drain_busy_queue()` (:627 before :634) —
is to stop the callout first.

## Impact
Race window between `xpt_done(ccb)` at :593 and `callout_stop(...)` at :596 on a
error-completion path (`tws_err_complete` → `tws_scsi_err_complete`, i.e. every
controller error response / CHECK CONDITION):
- `callout_stop` on freed ccb memory (use-after-free), or
- `callout_stop` on a *reused* ccb whose `timeout_ch` now belongs to a NEW in-flight
  transaction → the new I/O silently loses its timeout → hung CAM transaction with no
  recovery (no `tws_timeout` → no reset).

## Trigger (needs a 3ware 9700/9700X controller)
Heavy concurrent disk I/O on a unit that returns check conditions (or any FW error
completion), racing the cambio SWI. `trigger.sh` documents the workload.

## Reproduce
```
./build.sh    # nothing to compile; workload is dd(1) based
./run.sh      # on a host with a tws(4) adapter and a failing/busy unit
```
Expected on vulnerable kernel: rare panic in callout/cam code or unkillable hung
transaction after error completions under load.

## Status on the audit QEMU guest
Guest has no 3ware HBA (`pciconf` shows no vendor 0x13c1, no /dev/tws*) → cannot be
exercised there; code-level proof in VERDICT.md. verdict: inconclusive.
