# DF-3045 — unvalidated sdl_alen overflows the BOOTP query and smashes a 64-byte stack buffer

Verified in VERIFY mode on the QEMU guest with the verbatim-interposition
kernel-compiled harness (`dfrig12_bootp.c`): a fake `IFT_ETHER` link address
with `sdl_alen` > 16 is fed through the **verbatim**
`bootpc_fakeup_interface` (:1046-1053 selection), `bootpc_compose_query`
(:1192 hlen, :1197 bcopy), and the `bootpc_call` matcher (:846-848 bcmp),
plus the verbatim `hexncpy` call form (:718-720) with canaries.

## What was reproduced (baseline kernel)

* **Selection accepts any sdl_alen** (:1046-1053 filters only
  `sdl_type == IFT_ETHER`): `ACCEPTED IFT_ETHER sdl_alen=17 (>16, never
  checked)`.
* **In-struct overrun of chaddr[16]** via `bcopy(LLADDR(sdl),
  &call.chaddr, sdl_alen)` (:1197): with alen=17 the 17th MAC byte (0x50)
  lands in `call.sname[0]`; with alen=255, 239 bytes spill into
  sname/file/vend of the outgoing query (console hexdumps in `run50.log`).
* **hlen = sdl_alen** (:1192) drives the reply matcher
  `bcmp(reply.chaddr, call.chaddr, call.hlen)` (:846-848) **past the
  16-byte chaddr member on both sides** (len=17 → 1 byte; len=255 → 239
  bytes), and the exchange still completes (`bootpc_call error=0`).
* **Stack buffer smash via hexncpy** (:718-720, `HEX_NCPYLEN(alen) =
  alen*3` into `char hexstr[64]` at :590):
  * contained canary measurement: alen=22 → 2 bytes past the 64-byte
    buffer; alen=106 → 254 bytes past (linear; alen=255 → 701 bytes past);
  * **in-situ, alen=255**: 765-byte write from `hexstr[64]` inside
    `bootpc_call`'s own frame → `Fatal trap 9` GPF at `bootpc_call+0x83d:
    ret` with **frame pointer 0x3a37363a36363a35** — the saved RBP is
    filled with 0x3a (':' the hexncpy separator) — `panic.txt`.

## Honest reachability (matches the finding's Low/speculative rating)

* All in-tree Ethernet drivers get `sdl_alen = 6` from `ether_ifattach`
  (if_ethersubr.c:620,647); no in-tree driver claims IFT_ETHER with a
  longer address. Triggering requires a broken/virtual/future driver that
  does — hardware/driver-gated, boot-stage only. Not reachable by an
  unprivileged local user, not by crafted network input alone.
* The verification proves the *code path performs no defense-in-depth
  bound* and the primitive is a full kernel-stack smash once such a driver
  exists; on this intentionally unhardened guest that smash is a fatal GPF
  with attacker-influenced frame content (0x3a pattern), i.e. a control-
  flow-corruption class defect, not a benign overprint.

## Files

* `run.log` — baseline tests 3 and 5 (console traces).
* `run50.log` — baseline test 50: full console incl. the 255-byte MAC
  hexdump line and the fatal trap.
* `panic.txt` — GPF header with the 0x3a-laden frame pointer + backtrace.
* `run.fixed.log` / `panic_fix_rejection_console.txt` — fixed-kernel test 3:
  selection rejects alen=17, verbatim fail-loud panic
  `bootpc: Unable to find HW address for fak0`.
* `fix_validation.log` — A/B table **including the documented first-fix
  bug** (appending predicates to the `(sdl = ...)` condition leaves sdl
  non-NULL; caught by the A/B run and corrected).
* `fix.diff` — the corrected, validated fix.
