# DF-5374 — NULL-periph deref panic in targread()/targwrite() before LUN enable

## What
`sys/bus/cam/scsi/scsi_target.c`

- `targwrite()` (scsi_target.c:566-602) fetches `softc` and immediately
  uses `softc->periph` in `cam_periph_lock()` at :588/:602.
- `targread()` (scsi_target.c:874, :880) does the same, plus dereferences
  `softc->periph->sim->lock` directly.
- Neither path checks `softc->periph != NULL` or
  `softc->state & TARG_STATE_LUN_ENABLED` — between open(2) and a
  successful TARGIOCENABLE the periph pointer is NULL
  (set only in `targctor()`, scsi_target.c:522).
- `cam_periph_lock(periph)` is `CAM_SIM_LOCK(periph->sim)` (cam_periph.h:186-190)
  → NULL->sim read → "Fatal trap 12" panic.

## Threat
Any process that can open the targ clone node (created 0600 root:wheel by
`targinit()`, scsi_target.c:1057-1063; open additionally gated by
`caps_priv_check_self(SYSCAP_RESTRICTEDROOT)`, :177). On the stock guest
that means root/operator-with-devfs-rule; the canonical caller is the
userland SCSI target daemon. One write(2) of 8 bytes before any setup
panics the kernel — a trivially reliable local DoS with zero setup and no
race.

## Reproduce (guest, root)
```
cd /root/targpwn
cc -O0 -g -o poc5374 poc5374.c
./poc5374 w        # panic in targwrite/cam_periph_lock
# (after reset) ./poc5374 r   # panic in targread/cam_periph_lock
```

## Expected
Kernel panic "Fatal trap 12: page fault while in kernel mode", faulting
address = offsetof(struct cam_periph, sim), backtrace
`cam_periph_lock <- targwrite <- devfs_dwrite <- ...`. Serial console
(vm.sh log) carries the panic; guest stops answering ssh (DDB).

## Files
- poc5374.c — trigger (write- and read-mode)
- build.sh / run.sh
- build.log / run.log / panic.txt — captured evidence
- fix.diff — state-check both entry points, return ENXIO
