# DF-0607 — PoC: BPF write to ng_iface reads uninitialized sa_data -> KASSERT panic

Privileged local DoS PoC. `ng_iface_output` reads from `dst->sa_data` when
`dst->sa_family == AF_UNSPEC`, but for `DLT_NULL` BPF writes `bpf_movein`
never initializes `sa_data`. The `KASSERT(family != AF_UNSPEC)` at
`ng_iface_bpftap:481` fires and panics on INVARIANTS kernels (default).

## Files

- `df-bpf-panic.c` — minimal reproducer (tight `write()` loop on
  `/dev/bpfN` bound to an `ng_iface`).
- (added by per-PoC verifier) `build.sh`, `run.sh`, `run.log`,
  `VERDICT.md`, `manifest.json`, `fix.diff`, `panic.txt`.

## Build & run

```
cc -o df-bpf-panic df-bpf-panic.c
# one-time topology:
sudo ngctl mkpeer iface dummy inet    # creates ng0
sudo ./df-bpf-panic
```

## Expected first outcome

Kernel panic on the console and in `/var/crash`:

```
panic: assertion "family != AF_UNSPEC" failed in ng_iface_bpftap at sys/netgraph7/iface/ng_iface.c:481
```

The KASSERT fires when the stack garbage at `&dst.sa_data` has a zero low
byte — roughly 1/256 probability per write, so a tight loop panics within
seconds.

## Notes for the per-PoC verifier

- Requires `/dev/bpf*` write access (root on default installs; or any
  principal granted BPF via devfs rules).
- Requires an `ng_iface` interface attached (`ng0` from
  `ngctl mkpeer iface dummy inet`, or an existing `ng_pppoe` / `ng_l2tp`
  topology).
- Verify the fix with `git apply findings/poc/DF-0607/fix.diff` (read AF
  from leading 4 bytes of mbuf instead of `dst->sa_data`, strip 4 bytes);
  after the fix the panic should no longer occur and the peer hook
  receives the un-corrupted payload.
- On non-INVARIANTS kernels the KASSERT is a no-op; the bug instead
  manifests as silent payload corruption (4-byte AF prefix still attached
  to the mbuf when forwarded into netgraph).
