# DF-3658 VERDICT — unchecked target_id in XPT_GET/SET_TRAN_SETTINGS

## Status: not_reproduced (hardening-class; both userland and HW routes absent on guest)

## Analysis

Sinks (all in `sys/dev/disk/isp/isp_freebsd.c`, all indexed by
`tgt = cts->ccb_h.target_id` with no bounds check):

| Line | Sink | Array | Bound |
|------|------|-------|-------|
| 4585 | `sdp->isp_devparam[tgt].goal_flags` (RMW write) | `sdparam.isp_devparam[16]` (ispvar.h:195) | 16 (SCSI) |
| 4616-4617 | `.goal_period`, `.goal_offset` (16-bit writes) | same | 16 |
| 4623 | `.dev_update` (write) | same | 16 |
| 4649 | `fcp->isp_dev_map[tgt]` (read, 32-bit index) | `uint16_t[512]` (ispvar.h:485) | 512 (FC) |
| 4664-4673 | `.actv_*` / `.nvrm_*` (reads) | same sdparam | 16 |

A crafted CCB with `target_id` ≥ 16 (SCSI branch) yields OOB 16-bit writes at
a controlled offset from the `sdparam` heap allocation (which is `isp_param`,
sized `sizeof(sdparam)*nchan`, allocated in `isp_pci.c:830+`); ≥ 512 on FC
yields a wild read at `fcparam + 2*tgt` — `tgt` is 32-bit so the read address
is fully controlled → panic-capable.

`hdlidx < MAX_FC_TARG` at 4650 guards only `portdb[hdlidx]`, not the
`isp_dev_map[tgt]` read itself.

## Reachability

1. Kernel-internal CAM clients get `target_id` from `xpt_setup_ccb()` =
   path target, discovery-bounded → in-bounds. Not exploitable in normal use.
2. Userland `/dev/xpt0` (root:operator 0600) — DragonFly `xptioctl()`
   CAMIOCOMMAND whitelist (`cam_xpt.c:1028+`) excludes
   XPT_GET/SET_TRAN_SETTINGS; demonstrated live (run.log, errno 45).
3. Guest has no QLogic HBA → `isp_action` unreachable regardless.

Conclusion: defensive-depth finding, same class as DF-3574 (sym) and
DF-3609 (ncr). Severity Info, confidence certain (the missing check is
unambiguous; the exploit route requires a kernel-internal CCB forger).

## Fix

`fix.diff`: validate `tgt >= ISP_MAX_TARGETS(isp)` in both XPT_SET_TRAN_SETTINGS
and XPT_GET_TRAN_SETTINGS and complete the CCB with `CAM_TID_INVALID`.
`ISP_MAX_TARGETS(isp)` returns 512 for FC / 16 for SCSI, covering both the
sdparam and isp_dev_map sinks.

## Fix validation

not_testable — no isp hardware on the guest; no userland injection route
(whitelist). The diff is a two-hunk guard matching the existing DIAGNOSTIC
check at isp_freebsd.c:4325.

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