# DF-3046 — TAG_OVERLOAD consumed without length validation (1-byte OOB read)

Verified in VERIFY mode on the QEMU guest with the verbatim-interposition
kernel-compiled harness: crafted option regions fed **directly to the
verbatim `bootpc_tag_helper` / `bootpc_tag`** with guard bytes planted
exactly where the walk would over-read.

## What was reproduced (baseline kernel)

* **T1a (core)** — a `TAG_OVERLOAD` whose length byte (0) is the FINAL
  byte of the parsed region passes the guard at :1283
  (`j + *j + 1 > ej` evaluates to `ej > ej`, false), `len = *j++` advances
  j to exactly ej, and `tctx->overload = *j` (:1300) **reads one byte past
  the region** — the planted guard 0xa5 was adopted (`overload=0xa5,
  badopt=0`).
* **T1b** — `TAG_OVERLOAD` with len=3: the first value byte is taken as
  the overload flag regardless (RFC 2131 requires len==1).
* **T1c** — in-packet, replylen = sizeof(struct bootp_packet) = 1460
  (the struct has 2 bytes of tail padding): the byte read is at
  `bp + sizeof` — **past the struct** (planted guard 0x03 adopted).
* **T1c2** — replylen = 1458: the read lands on the struct tail padding
  just past the `vend[1222]` member (planted 0xee adopted).
* **T1d/T1e** — sname-walk variant: a len=0 TAG_OVERLOAD as the final two
  bytes of `sname[64]` reads `bp->file[0]`, the adjacent in-struct field —
  attribution tracked across two planted values (0x5c, 0x77).
* **T1f** — file-walk variant shows **chained** propagation: the file walk
  reads `bp->vend[0]` (the cookie byte 99), whose SNAME bit then triggers
  a sname walk that adopts `bp->file[0]`.

## Impact (as the Info finding states)

The read value only steers which bounded areas (file[128]/sname[64]) get
re-walked. For both production contexts (`gctx->reply` /
`ifctx->reply`) the byte past the region lies **inside the same kmalloc
allocation** (struct tail padding or the adjacent `replylen` member /
cookie byte); no crash, no leak to userspace, no corruption — verified on
the INVARIANTS kernel. `impact: none`, defect mechanically confirmed.

## Files

* `run.log` — baseline test 1 console trace (all subtests).
* `run.fixed.log` — fixed-kernel test 1 status (every planted byte
  rejected, `badopt=1`; only legitimate len==1 values survive).
* `fix_validation.log` — subtest-by-subtest A/B.
* `fix.diff` — one hunk: require `len == 1` for TAG_OVERLOAD.
