# DF-1106 — VERDICT

**Verdict: NOT REPRODUCED at runtime (latent — no XHCI controller on the
audit guest, and the trigger is fundamentally a malicious-controller
scenario).  Bug confirmed by source trace.**

## Mechanism (source-confirmed)

`xhci_pci_take_controller()` at `sys/bus/u4b/controller/xhci_pci.c:398-413`:

```c
for (eecp = XHCI_HCS0_XECP(cparams) << 2;             /* :398 */
     eecp != 0 && XHCI_XECP_NEXT(eec);                 /* :399 */
     eecp += XHCI_XECP_NEXT(eec) << 2) {               /* :400 */
    eec = XREAD4(sc, capa, eecp);                       /* :401 — OOB read */
    if (XHCI_XECP_ID(eec) != XHCI_ID_USB_LEGACY)
        continue;
    bios_sem = XREAD1(sc, capa, eecp + XHCI_XECP_BIOS_SEM);  /* :405 — OOB */
    if (bios_sem == 0)
        continue;
    ...
    XWRITE1(sc, capa, eecp + XHCI_XECP_OS_SEM, 1);            /* :410 — OOB write */
    to = 500;
    while (1) {
        bios_sem = XREAD1(sc, capa, eecp + XHCI_XECP_BIOS_SEM); /* :413 — OOB */
        ...
    }
}
```

- `XHCI_HCS0_XECP` is a 16-bit field
  (`sys/bus/u4b/controller/xhcireg.h:70`) → initial `eecp` can be up to
  `0xFFFF << 2 = 262140`, larger than typical XHCI BARs (8-64 KB).
- `XHCI_XECP_NEXT` is an 8-bit field (xhcireg.h:192) → grows `eecp` by up
  to `0xFF << 2 = 1020` per iteration.
- `XREAD4/XREAD1/XWRITE1` (xhcireg.h:205-222) expand to plain
  `bus_space_read/write_*` with **no bounds check**.
- `sc->sc_io_size` IS recorded at xhci_pci.c:206 but is **never consulted
  in this loop**.

A malicious XHCI controller can:
- Supply an `eecp` past its BAR → kernel page-fault panic on platforms
  with precise `pmap_mapdev` bounds.
- Return `NEXT=0xFF` from an OOB read (i.e. `0xFFFFFFFF`) →
  `XHCI_XECP_NEXT(0xFFFFFFFF) = 0xFF` (never 0) → loops unboundedly with
  growing `eecp` until fault (DoS).
- Force the kernel to perform an OOB MMIO **write** at line 410.

Same class as DF-1092 (EHCI).

## Why it can't be triggered on this guest

```
$ dmesg | grep -iE 'xhci|usb'
(empty)
$ pciconf -lv | grep -iE 'xhci|class: 0x0c03'
(empty)
```

The QEMU guest has no XHCI controller.  Even if one were added via
`-device qemu-xhci`, the QEMU emulated XHCI reports honest
extended-capability registers, so `eecp` would always be a valid in-BAR
offset and the OOB walk wouldn't trigger.  The bug is fundamentally a
malicious-controller scenario (Thunderbolt / ExpressCard / PCIe hot-plug
of a device that lies about its capability registers) — not reproducible
on the audit guest.

## Exploit chain

**Primitive class:** OOB MMIO read/write driven by attacker-controlled
PCI capability registers.  In principle an OOB MMIO write could be
weaponised into code execution if the write targeted sensitive platform
MMIO (e.g. SPI flash mapping, MSIX tables).  BUT:

- The primitive requires a malicious PCI device on the bus — not
  reproducible from any userspace action on the audit guest.
- QEMU's emulated XHCI is well-behaved and won't trigger the bug.

**Valid hard blocker** ("vulnerable code path is dead code at runtime on
this guest AND no harness can exercise it without hardware the guest
lacks").  Documented as latent.  No `uid=0` achievable on this guest.

## Fix

`fix.diff` adds `eecp + 4 <= sc->sc_io_size` to the loop condition so any
pointer past the mapped BAR terminates the walk.  Validated as applies +
compiles in a clean GENERIC kernel build (rebuilt fresh, no
warnings/errors).

## Fix validation

`not_testable` — path not runtime-reachable on this guest.  Validated
`fix.diff` applies cleanly and compiles with `-Werror` in a full
`make nativekernel KERNCONF=X86_64_GENERIC` (xhci_pci.o rebuilt fresh,
no warnings/errors — see `../DF-1096/all_fixes_build.log`).

## PoC changes

- Wrote `df1106.c` (documentation-only stub explaining the source trace).
- Wrote `fix.diff`, `build.sh`, `run.sh`.
