# VERDICT — DF-4266 (inverted RX OWN test in wb_rxeof)

**Status: reproduced** — at the strongest fidelity possible without the NIC:
the **production handler itself** (the running kernel's static `wb_rxeof()`,
resolved from `/boot/kernel/kernel` via `nm(1)` and dispatched from a KLD rig)
exhibited every claimed defective behavior on the guest, and a kernel rebuilt
with `fix.diff` exhibited none of them. Same rig binary (`.ko`) on both
kernels; the only variable was the one-line fix.

## Method — production-handler KLD dispatch (DF-4106 vge evidence class)

The guest has no W89C840F/Compex NIC, but `device wb` is built into
X86_64_GENERIC (sys/config/X86_64_GENERIC:246), so the driver's real static
functions live in the running kernel image. The rig
(`findings/poc/DF-4266/df4266_wb_poc.c`, built clean with `-Werror`,
`kld_build.log`):

* resolves **`wb_rxeof` / `wb_init` / `wb_stop`** from `/boot/kernel/kernel`
  (sysctl-injected hex addresses — `wb_newbuf` exists only as an IPA-SRA
  clone `wb_newbuf.isra.5` with a compiler-mangled ABI and is deliberately
  never called; the ring is armed by dispatching the kernel's own
  `wb_init()`, whose inlined `wb_list_rx_init`/`wb_newbuf` build the exact
  production post-init state);
* fabricates a post-attach softc in module `.bss`: real `wb_list_data`
  (contiguous rxbufs + descriptor rings, armed by the REAL `wb_init` — 64
  MGETHDR mbufs, descriptors `WB_RXSTAT=0x80000300`
  FIRSTFRAG|LASTFRAG|OWN), a fake miibus `device_t` whose softc is a zeroed
  `mii_data` (empty phys list: `mii_mediachg`/`mii_pollstat`/`mii_tick`
  degenerate to no-ops so `wb_init`/`wb_reset`/`wb_fixmedia` run their full
  real bodies safely), a real lwkt serializer held across dispatches exactly
  as `wb_intr` would, per-CPU ifdata, a real `ifaltq_subque` (rig v1
  panicked in `wb_stop+0x156` on a NULL `if_snd.altq_subq` — rig bug, fixed
  by replicating `if_attach`'s subqueue setup, net/if.c:592-640; see
  `panic_rig_v1.txt`), and a scratch page as the MMIO BAR;
* simulates the NIC the only way the driver can observe it: descriptor
  status write-backs + frame bytes into the armed buffer — bit-exact with
  the W89C840F protocol (`wb_newbuf` arms OWN=1; chip clears OWN and sets
  RXCMP|FIRSTFRAG|LASTFRAG|len on completion, if_wbreg.h:227-243);
* struct-layout agreement between the module compile and the running kernel
  is verified: `sizeof(wb_softc)=0x1e80 if_timer=0x6a wb_bhandle=0x3c0
  wb_btag=0x3c8 wb_ldata=0x400 rx_chain[0]=0x448 wb_stat_timer=0x1e68
  if_snd.altq_subq=0x210` — every constant matches the kernel's own
  disassembly of `wb_stop`/`wb_init` (kld_run_baseline.log line 2).
* The one transcription (`df_wb_rxeof_fixed`) is NOT the code under test —
  it is the verbatim counterfactual with exactly the fix.diff line applied,
  used for the module-level A/B (S1fix) and as an independent sanity check.

## Baseline run — stock kernel #0 (Jul 2 2026), REAL `wb_rxeof` (kld_run_baseline.log)

* **S1 — chip-completed frame DROPPED (THE bug).** Slot 0 write-back
  `0x40400300` (OWN=0, RXCMP|FIRSTFRAG|LASTFRAG, len 64) + 60-byte frame
  with marker payload in the armed buffer. Real `wb_rxeof` **broke
  immediately** at if_wb.c:974-975: `delivered=0 ipackets=0 ierrors=0`,
  descriptor NOT re-armed (`0x40400300` unchanged), head NOT advanced.
  On silicon this is permanent: 100% RX loss, `ipackets` stays 0 forever,
  and since completed descriptors are never recycled the chip starves →
  `WB_ISR_RX_NOBUF` → `wb_intr` (if_wb.c:1137-1144) runs
  `wb_reset`+`wb_init` (full 64-mbuf ring teardown/re-init) for every
  arriving frame. Any adjacent L2 frame (untargeted broadcast suffices)
  triggers it: unauthenticated adjacent-network DoS.
* **S1fix — identical state, one-line-fixed comparator:** delivered=1,
  `if_input: m_len=60 dst=ff:ff:ff:ff:ff:ff src=00:df:42:66:00:01
  type=df42 pay=0e 0f 10 11` (exact crafted bytes), ipackets=1, slot
  re-armed to `0x80000300`. The state was processable; only the inverted
  test blocks the production handler.
* **S2 — chip-OWNED descriptors PROCESSED + per-interrupt reset storm.**
  Armed idle ring (exactly what `wb_init` leaves). Each of 3 dispatches of
  the REAL handler: popped the chip-owned head, `ierrors++`, kernel printed
  `receiver babbling: possible chip bug, forcing reset` (if_wb.c:989-990),
  ran `wb_fixmedia`+`wb_reset`+`wb_init` — full ring re-init observable via
  the replaced `wb_rx_chain[0].wb_mbuf` pointer each dispatch — at
  **~60.9/69.8/65.3 ms per dispatch** (mostly the MMIO-stand-in reset poll;
  the 64-mbuf teardown/reinit work is the same on real HW). On the fixed
  kernel the same dispatches took **9-13 µs and did nothing** (below).
* **S3 — frame ACCEPTED from a descriptor the chip STILL OWNS.** Slot 0 =
  `0xc0400300` (OWN=1 — the mid-write-back transient the inverted loop
  wrongly accepts, i.e. what the driver sees when the interrupt fires while
  DMA is in flight). Real `wb_rxeof` **processed it as a good frame**
  (delivered=1, ipackets=1 — with the correct payload), then
  **re-armed the descriptor under the chip** (status rewritten to
  `0x80000300`, `wb_data` re-pointed): driver and hardware now disagree
  about who owns descriptor 0 and its buffer. This is the on-ramp to the
  DMA/race memory-safety tail tracked separately as DF-4268 (not re-verified
  here). After the S3 delivery the loop re-entered the just-re-armed slot
  (OWN=1 → continue, per the inversion) and babbled into yet another
  full reset — the storm feeds itself.
* Guest stayed up (SURVIVED) — this finding is availability-breaking, not
  corruption-demonstrating (corruption family is DF-4268).

## Fix validation — kernel #1 (Oct 14 2026), same tree + fix.diff (kld_run_fixed.log)

`fix.diff` applied to the guest's `/usr/src` (patch output in VERDICT
history; `fix_build_tail.log`: `make -j6 nativekernel` + `installkernel`,
if_wb.c recompiled at build log line 18787), rebooted into kernel #1, and
the **identical rig** re-run — `wb_rxeof` resolved again from the new
kernel (same address `0xffffffff808dae30`; the one-line change did not move
the symbol):

| scenario | baseline (buggy) | fixed kernel |
|---|---|---|
| S1 completed frame (OWN=0) | dropped, ipackets=0, not re-armed | **DELIVERED by the REAL patched handler** (m_len=60, exact payload), ipackets=1, re-armed |
| S2 armed ring ×3 | ierrors +1/dispatch, babble print, full ring re-init, 61-70 ms | **ierrors=0, no babble, no re-init (mbuf unchanged), 9-13 µs** |
| S3 OWN=1 looking complete | accepted + re-armed under chip | **untouched**: delivered=0, ipackets=0, status still the crafted `0xc0400300` |

(The fixed-run "S2 BUG CONFIRMED" banner and "S1/S1fix/S3: UNEXPECTED
outcome" strings in the log are the rig's *bug-expectation* assertions
failing — i.e. exactly the fixed behavior; the data lines are decisive.
The run also crossed a warm reboot — DragonFly's msgbuf preserved the
baseline section in `dmesg`, so both runs appear in order; attribution is
by boot context and mbuf addresses, see env.txt.)

fix_status: **fixed** (baseline_reproduced=1, patched_reproduced=0 — every
defective marker gone; the previously-impossible behavior — receiving a
frame — now works).

## Impact

Unauthenticated adjacent-network DoS on W89C840F/Compex RL100-ATX equipped
hosts: 100% RX loss from the first frame + a per-interrupt full-chip
reset/re-init storm (which also destroys TX progress each time), plus the
S3 ownership-protocol break that races the DMA engine (DF-4268 tracks the
memory-safety tail). Trigger is any Ethernet frame — untargeted
broadcast/multicast suffices; no privileges needed. High severity stands.

## Why this is "reproduced" and not "hardware-gated untested"

Everything the driver decides is a function of descriptor words and MMIO.
The rig supplied both bit-exactly per the W89C840F protocol (triangulated:
`wb_newbuf` arming semantics if_wbreg.h:243, FreeBSD 4.11 original loop,
Linux winbond-840.c `DescOwn` convention — see prior pack revision), and
the *code that was executed* was the kernel's own `wb_rxeof`, not a
transcription. The remaining hardware dependency (the chip actually
clearing OWN on write-back) is a property of the NIC the driver cannot
influence — and S1/S3 demonstrate the driver's response to both sides of
exactly that protocol event. The defective behavior is therefore
demonstrated on production code, on the audit guest, deterministically,
twice (plus once on the patched kernel to prove the delta).

## Rig iteration notes (attempts)

1. v1: NULL `if_snd.altq_subq` → panic in `wb_stop+0x156` (rig bug,
   `panic_rig_v1.txt`) — also yielded the struct-offset cross-check.
2. v2: full baseline reproduced (all scenarios, guest survived).
3. v3: fixed-kernel A/B — all defective behaviors gone; frame delivery
   restored by the REAL patched handler.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
