# DF-3044 — BOOTP/DHCP reply acceptance: zero origin validation + deterministic XID

Verified in VERIFY mode (audit skipped) on the single-tenant QEMU guest, with
the verbatim-interposition kernel-compiled harness (`dfrig12_bootp.c`, this
directory) that `#include`s the unmodified production
`sys/vfs/nfs/bootp_subr.c` (sha256-gated: `build.sh` refuses to build unless
the guest source is byte-identical to the audited tree).

## What was reproduced (baseline kernel)

* **Blind predicted-XID spoof, arbitrary origin, full client compromise of
  the netboot identity**: a reply whose XID is computed *purely from source
  constants* — seed `0xFFFF0000` (bootp_subr.c:1538 `gctx->xid = ~0xFFFF`),
  `+0x100` per interface (:435), `+1` on the first compose of an unresolved
  ifctx (:1194-1195) — sent from `6.6.6.6:9999` (a port no DHCP server uses)
  is **accepted** by the verbatim `bootpc_call` matcher (:838-848) and the
  verbatim `bootpc_decode_reply` adopts the attacker's entire config:
  hostname, root NFS server+path, swap NFS server+path, default route.
  `soreceive(so, NULL, ...)` at :807 means the origin is never even
  requested (harness counter: 0 times).
* **DoS manifestation**: the same predicted-XID ACK carrying
  `TAG_SUBNETMASK` with len 3 reaches `bootpc_decode_reply` and trips the
  verbatim `panic("bootpc: subnet mask len is 3")` (:1390) → `panic.txt`.

## Files

* `dfrig12_bootp.c` — the harness (interposition seams: sockets, ifioctl,
  rtrequest, tsleep, setfs/nfs_mountopts/md_mount/md_lookup_swap, bcmp).
* `build.sh` — verbatim sha256 gate + `make nativekernel` + installkernel.
* `run.sh` — test selector (2 = blind spoof, 20 = wrong-xid control,
  21/22 = fixed-kernel sniff variants, 4 = panic path, dedicated boot).
* `run.log` — baseline test-2 console trace (verbatim `Received DHCP
  Offer/Ack ... (accepted)` lines + adopted-config decode line) + test-20
  control status.
* `run.fixed.log` — fixed-kernel runs (2/21/22 + test 4 without panic).
* `panic.txt` — baseline test-4 panic + backtrace.
* `fix_validation.log` — A/B table.
* `fix.diff` — the validated fix (random XID seed + require source port 67).
* `build.log` / `build_fixed.log` — full untrimmed kernel build logs.
* `env.txt` — guest, compiler, rig, gate hashes.

## Reproduce (on the DragonFly guest)

```
sh build.sh                      # gate + build + install (reboot after)
sysctl -w kern.dfrig12=2         # blind spoof   -> full adoption (baseline)
sysctl -w kern.dfrig12=20        # wrong-xid     -> ignored
sysctl -n kern.dfrig12_status    # verdict markers
# dedicated boot:
sysctl -w kern.dfrig12=4         # -> panic: bootpc: subnet mask len is 3
```

## Expected (baseline)

```
dfrig12: client broadcasts query #1 xid_raw=0100ffff ...
dfrig12: ATTACKER injects OFFER xid_raw=0100ffff origin=6.6.6.6:9999 ...
Received DHCP Offer packet on vtnet0 from 6.6.6.6 (accepted) (no root path)
...
Received DHCP Ack packet on vtnet0 from 6.6.6.6 (accepted) (got root path)
vtnet0 at 66.6.6.6 server 6.6.6.6
subnet mask 255.255.0.0 router 1.6.6.6 rootfs 6.6.6.6:/pwn3d swapfs 6.6.6.6:/swpwn swapsize 65536 KB hostname pwn3d
dfrig12: DF3044: hostname ADOPTED 'pwn3d' ...
dfrig12: DF3044: root NFS mount ADOPTED from attacker 6.6.6.6 path=6.6.6.6:/pwn3d
dfrig12: DF3044: default route ADOPTED via attacker 6.6.6.1 flags=0x803
```
(with attacker constants stored big-endian; on-wire they appear as
66.6.6.6 / 6.6.6.6 / 1.6.6.6 — all attacker-chosen either way.)
