# DF-4180 — Verification Verdict

**Status:** inconclusive (hardware-gated: no 3ware controller in the QEMU guest; trigger input comes from the controller response queue, not from userland)
**Impact:** none on this guest (wild pointer read+write via HW-controlled index on affected hardware)
**Confidence:** certain (bounds violation provable from source)

## Mechanism (source trace)

1. `struct twe_softc` layout (twevar.h:135-136):
   `struct twe_request *twe_lookup[TWE_Q_LENGTH];`
   `struct twe_drive twe_drive[TWE_MAX_UNITS];` — `twe_drive` begins
   exactly where `twe_lookup` ends (both pointer-aligned).
2. `TWE_Q_LENGTH == TWE_INIT_MESSAGE_CREDITS == 0xff == 255`
   (twereg.h:146,152).  `twe_setup()` fills `sc->twe_lookup[i]` for
   i = 0..254 only (`i < TWE_Q_LENGTH`, twe.c:140-157); legal request ids
   are 0..254.
3. `TWE_Response_Queue.u.response_id` is an **8-bit** field
   (twereg.h:331-340) — the controller can return 0..255.
4. `twe_done()` (twe.c:1196-1210):
   `rq.value = TWE_RESPONSE_QUEUE(sc);`
   `tr = sc->twe_lookup[rq.u.response_id];` — **no range check**.
   response_id == 255 reads `twe_lookup[255]`, i.e. the first 8 bytes of
   `twe_drive[0]` = `td_size` (controller-reported capacity, u32) and
   `td_cylinders` (derived, int) → a 64-bit, partially groomable bogus
   pointer.
5. `if (tr->tr_status != TWE_CMD_BUSY)` (twe.c:1203) — wild read;
   `tr->tr_status = TWE_CMD_COMPLETE` (twe.c:1205) — wild write of the
   constant 2 at offset offsetof(struct twe_request, tr_status); then
   `twe_remove_busy`/`twe_enqueue_complete` chase the bogus pointer
   further (twe.c:1209-1210).

Preconditions: a 3ware Escalade controller that emits a response id of 255
(firmware malfunction, malicious device, or hostile DMA — e.g.
Thunderbolt-attached FPGA).  Realistically a robustness/panic bug; the
groomed-pointer variant requires drive-size grooming of `twe_drive[0]`.

## Why it cannot be reproduced on this guest

No 3ware PCI device; `twe` never attaches; the response queue is only
readable from the controller itself.  There is no userland-reachable
trigger by construction.

## Fix validation

Bounds-check `rq.u.response_id >= TWE_Q_LENGTH` → consume + drop
(fix.diff); applies cleanly, batch-compiled into X86_64_GENERIC with the
rest of this batch (fix_build.log).

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