# DF-5041 — acpi_pcib.c: _PRT `Source` device used as PCI link device without NULL/driver validation → boot-time kernel panic (type confusion / NULL deref)

**File:** `sys/dev/acpica/acpi_pcib.c`
**Severity:** Low (firmware/AML-controlled trigger at boot) · **Verified:** reproduced (fatal trap 12 at boot) · **Fix:** validated on a patched kernel

## What it is

A 191-byte SSDT (`ssdt_prtbad.aml`) that declares a second ACPI PCI host
bridge (`\_SB.PCIX`, PNP0A03, bus 1) whose `_PRT` names, as interrupt link
`Source`, ACPI devices that are **not** PCI interrupt link devices:

* `\_SB.PCI0`     — the real host bridge (`acpi_hpcib_softc`)
* `\_SB.HPET`     — HPET (probe fails → benign path)
* `\_SB.PCI0.S08` — ISA-bridge namespace node (attached by an unrelated
  driver on this guest)

At boot `acpi_pcib_attach()` walks the `_PRT` and hands those devices to
`acpi_pci_link_add_reference()`; `acpi_pci_link_lookup()` then reads their
softc as `struct acpi_pci_link_softc` (`pl_num_links` ← low 32 bits of a
`device_t` at offset 0, `pl_links` ← `ACPI_HANDLE` at offset 8) and walks
`pl_links[i].l_res_index` — an OOB read from a wild pointer, plus a
`link->l_references++` write through any forged match.

## Build (on the host, uses the guest's iasl)

```sh
scp -F dfbsd-qemu/config findings/poc/DF-5041/ssdt_prtbad.asl dfbsd:/tmp/
dfbsd-qemu/vm.sh run_root 'cd /tmp && iasl ssdt_prtbad.asl'
scp -F dfbsd-qemu/config dfbsd:/tmp/ssdt_prtbad.aml dfbsd-qemu/ssdt_prtbad.aml
```

## Run (baseline, stock kernel)

```sh
dfbsd-qemu/vm.sh down
cd dfbsd-qemu && QEMU_EXTRA="-acpitable file=ssdt_prtbad.aml" ./vm.sh up 300 || true
tail -25 boot.log
```

## Expected

Stock kernel — boot dies with:

```
pcib1: <ACPI Host-PCI bridge> on acpi0
pcib0: apparently invalid index 0
pcib1: failed to force attach of \_SB_.HPET
Fatal trap 12: page fault while in kernel mode
fault virtual address = 0xfffffffffffffff8
Stopped at acpi_pci_link_lookup+0x32: movl (%rax),%ecx
```

ssh never comes up (boot bricked). Full log: `run.log`, extract: `panic.txt`.

Patched kernel (`fix.diff` applied, single-fix build) — same SSDT boots fine:

```
pcib1: <ACPI Host-PCI bridge> on acpi0
pcib1: PRT source \_SB_.PCI0 is not a PCI interrupt link
pcib1: failed to force attach of \_SB_.HPET
pcib1: PRT source \_SB_.PCI0.S08_ is not a PCI interrupt link
pci1: <ACPI PCI bus> on pcib1
```

ssh comes up; see `fix_run.log` / `fix_evidence.txt`.

## Files

| file | what |
|---|---|
| `ssdt_prtbad.asl` / `.aml` | the malicious SSDT (ASL source + compiled) |
| `build.sh` / `run.sh` | exact commands |
| `build.log` | iasl compile output |
| `run.log` | FULL baseline boot log (panic) |
| `panic.txt` | decisive lines |
| `fix.diff` | the verified fix (never applied to the repo `sys/`) |
| `fix_build.log` | patched-kernel build/install evidence |
| `fix_run.log` / `fix_evidence.txt` | patched-kernel boot with same SSDT |
| `env.txt` | guest uname / iasl version |
| `VERDICT.md` | full narrative |
| `manifest.json` / `verdict.json` | machine-readable |

sha256: asl `579e1f3f…3a6d0`, aml `643f5913…d4b10145`, fix.diff `6ca71c41…5c18b08`.
