# DF-1041 PoC — CISTPL_CFTABLE_ENTRY power/misc unbounded read loops

## Verdict

**REPRODUCED** (harness-level — runtime unreachable on guest without PCMCIA HW).
**Fix VALIDATED** on a built-and-booted single-fix kernel.

See `VERDICT.md` for the full narrative. See `manifest.json` for the artifact
catalog. The decisive log is `run.log`; `fix_build.log` is the full 35553-line
single-fix kernel build.

## Why a harness (not a runtime panic)

The QEMU/KVM audit guest has **no PCMCIA/CardBus bridge** — `devinfo` shows
no pccard/cbb device, `/dev/pccard*` and `/dev/cardbus*` do not exist, and
there is no syscall/ioctl/devfs path that feeds attacker bytes into
`pccard_parse_cis_tuple`. The bug is latent, triggerable only by physical
PCMCIA card insertion (the threat model in the finding markdown).

`harness.c` is a verbatim, line-cited replication of the CFTABLE_ENTRY
parser (`pccard_cis.c:871-1253`) that demonstrates the unbounded `idx`
growth on the supplied CIS image without needing real PCMCIA hardware.
This follows the precedent set by sibling finding DF-1040 (same parser).

## Trigger

CIS attribute-memory image containing a malformed `CISTPL_CFTABLE_ENTRY`:

| Offset | Value | Meaning                                                |
|--------|-------|--------------------------------------------------------|
| 0x00   | 0x1B  | CISTPL_CFTABLE_ENTRY code                              |
| 0x02   | 0x08  | declared length (8 bytes, intentionally short)         |
| 0x04   | 0x80  | INDX: interface present                                |
| 0x06   | 0x41  | interface byte                                         |
| 0x08   | 0x01  | feature byte: power=Vcc only                           |
| 0x0A   | 0x7F  | param selection: all 7 bits set                        |
| 0x0C.. | 0xFF  | long run of 0xFF (each keeps `reg2 & 0x80` true)       |

(`cis_image.bin` is the 64 KiB version of this — every even byte after 0x0C
is `0xFF`. The kernel's `PCCARD_CIS_SIZE` is 4096, so on real HW the panic
would occur much earlier, at `byte_off >= 4096`, i.e. `idx >= 2046`.)

## Build & run

```
./build.sh       # cc -O2 -Wall -o harness harness.c
./run.sh         # ./harness cis_image.bin
```

Expected:

```
=== UNPATCHED (master pccard_cis.c) ===
final idx reached        = 50001 bytes        (cap; first OOB at idx=32766)
=== PATCHED (fix.diff: idx>=length -> abort_cfe) ===
final idx reached        = 8 bytes            (capped at length=8)
SUMMARY: unpatched idx=50001 (>49993 past length) vs patched idx=8 (==length).
```

`harness_valid` (run separately) confirms the fix doesn't break legitimate
input — both branches reach the same idx on a well-formed tuple.

## On real hardware

A malicious PC Card / CardBus card flashed with this CIS, when inserted
into a DragonFlyBSD system with the default kernel, drives the parser's
`idx` past the 4096-byte bus-space CIS window. The expected kernel panic:

```
Fatal trap 12: page fault while in kernel mode
fault virtual address   = 0x<offset past bridge window>
pccard_parse_cis_tuple(...) at pccard_cis.c:996   (or :1244)
pccard_scan_cis(...) at pccard_cis.c:349
```

## Kernel references

- `sys/bus/pccard/pccard_cis.c:984-1007`  — power parameter loop (no length guard)
- `sys/bus/pccard/pccard_cis.c:995-1003`  — do-while continuing on card byte's bit 7
- `sys/bus/pccard/pccard_cis.c:1243-1246` — misc-extension while loop (no length guard)
- `sys/bus/pccard/pccard_cis.c:1024, 1102, 1134, 1225` — existing length checks
- `sys/bus/pccard/pccard_cis.c:62`        — `PCCARD_CIS_SIZE 4096`
- `sys/bus/pccard/pccardvar.h:255-259`    — `pccard_tuple_read_1` (no length check)
