# DF-3801 — `mprsas_resetdev_complete` dereferences a NULL reply → kernel panic during Diag Reset

- File: `sys/dev/raid/mpr/mpr_sas.c`
- Class: kernel NULL-deref panic (missing NULL check)
- Severity: Medium / Confidence: certain (statically provable)
- Status on guest: not_reproduced — no SAS3 HBA (see `env.txt`)

## Defect

Every task-management completion handler in this file guards against
`cm_reply == NULL`:

- `mprsas_abort_complete`      — `mpr_sas.c:1545`
- `mprsas_logical_unit_reset_complete` — `mpr_sas.c:1300`
- `mprsas_target_reset_complete` — `mpr_sas.c:1395`
- `mprsas_remove_volume`       — `mpr_sas.c:383`
- `mprsas_remove_device`       — `mpr_sas.c:582`
- `mprsas_remove_complete`     — `mpr_sas.c:657`

`mprsas_resetdev_complete` (`mpr_sas.c:3384-3427`) does **not**:

```c
	resp = (MPI2_SCSI_TASK_MANAGE_REPLY *)tm->cm_reply;   /* :3392 */
	...
	if ((tm->cm_flags & MPR_CM_FLAGS_ERROR_MASK) != 0) { /* :3400 — only bail */
		...
	}
	mpr_dprint(sc, MPR_XINFO, "%s: IOCStatus = 0x%x ResponseCode = 0x%x\n",
	    __func__, le16toh(resp->IOCStatus), le32toh(resp->ResponseCode)); /* :3412-13 DEREF */
```

## Reachability

`mprsas_complete_all_commands()` — run from `mprsas_handle_reinit()` during
**every** Diag Reset (`mpr_reinit`, e.g. from `mprsas_tm_timeout`
`mpr_sas.c:1255-1270`) — deliberately completes all outstanding commands with
`cm->cm_reply = NULL` and then invokes `cm->cm_complete(sc, cm)`
(`mpr_sas.c:1173-1207`).

If CAM error recovery has an `XPT_RESET_DEV` in flight (`mprsas_action_resetdev`
→ `tm->cm_complete = mprsas_resetdev_complete`, `mpr_sas.c:3372`) at the moment
the controller is diag-reset, `mprsas_resetdev_complete` runs with
`resp == NULL` and faults on `resp->IOCStatus` → kernel panic.

Device error storms classically produce both events together: CAM escalates to
XPT_RESET_DEV while the HBA simultaneously needs a controller reset. Note
`xpt_done(ccb)` at `mpr_sas.c:3426` is never reached, and the TM is never freed.

## Fix

Add the same `resp == NULL` guard the sibling handlers have (see `fix.diff`);
on NULL, complete the ccb with `CAM_REQ_CMP_ERR`/`CAM_SCSI_BUS_RESET` and free
the TM.

## Guest verification attempt

No SAS3 controller in the QEMU guest (`pciconf -l`: no LSI/Avago device;
`camcontrol devlist`: only ata0/ata1/xpt0 buses). `mpr` is compiled in
(`pci/mpr` registered) but `mpr_attach` never matches, so no XPT_RESET_DEV can
ever reach `mprsas_action_resetdev`. Not reproducible on this hardware; the
missing guard is provable from source with certainty. FreeBSD's mpr(4) carries
the identical defect in `mprsas_resetdev_complete`.

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