# DF-4306 VERDICT — unbounded HW-semaphore spin in the 80003ES2LAN SWFW release path

## Bottom line

Source-certain unbounded-wait defect (DF-4217 family shape: a hardware
wait whose timeout branch can never be reached because the loop condition
never terminates). Runtime not reproducible on this guest — no 80003ES2LAN
device exists (`hw.igb` unknown oid, virtio-only guest; QEMU's Intel NIC
models are e1000-family MMIO-incompatible with the 80003 KMRN/SWFW
register set and no such device is attached anyway) — **not_reproduced**
per family convention (DF-3827). Impact ceiling on real hardware: CPU
livelock + interface wedge (availability only). Low severity: trigger is a
hardware/firmware fault state (stuck SWSM.SMBI bit), not attacker-set
state.

## Trace

1. `e1000_release_swfw_sync_80003es2lan` (e1000_80003es2lan.c:449-463):
   `while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS) ;` at
   :455-456 — no bound, no yield, MMIO read loop.
2. `e1000_get_hw_semaphore_generic` (e1000_mac.c:1721-1745): bounded
   per-call (SMBI poll timeout = `hw->nvm.word_size + 1` × 50 µs;
   word_size capped to 1<<14 by e1000_80003es2lan.c:176-178), returns
   `-E1000_ERR_NVM` on timeout ⇒ the outer `while` retries the entire
   bounded poll **forever**.
3. Reachability: every PHY register access (`e1000_read/write_phy_reg_
   gg82563_80003es2lan` :482/:499/:514/:531, :553/:570/:585/:602), every
   KMRN access (:1388/:1402, :1425/:1436), NVM acquire/release wrapper
   (:368-391), and `e1000_reset_hw_80003es2lan` (:845-851) funnel through
   acquire/release — i.e. link maintenance (1 Hz igb tick), ifmedia
   changes, resets. All execute under the igb serializer.
4. Why SMBI sticks: the 80003 pairs with manageability firmware
   (`mac->asf_firmware_present = TRUE` :223; FWSM-checked
   `arc_subsystem_valid` :227-228) and dual-function parts share the
   semaphore — a fw hold or a wedged sibling function leaves SMBI set
   indefinitely (this is why the acquire side has a timeout at all; the
   release side just forgot the bound).

## Checklist coverage (whole-file negative results)

- (a) init_function_pointers NULL-op coverage: `set_lan_id` called at :269
  is pre-assigned by `e1000_init_mac_ops_generic` (e1000_mac.c:58) which
  `e1000_setup_init_funcs` (e1000_api.c:447) runs BEFORE the family init
  (:486) — safe. Serdes (non-copper) early-return leaves phy read/write
  NULL, but both local call sites guard (`if (!(hw->phy.ops.read_reg))`
  :670/:765) and `cfg_on_link_up` is only invoked on the copper branch of
  `e1000_get_link_up_info_80003es2lan` (:800-803). Clean.
- (b) rar/LAA: no direct RAR mutation in this file (delegates to
  `e1000_init_rx_addrs_generic`/`e1000_check_alt_mac_addr_generic`);
  `rar_entry_count = E1000_RAR_ENTRIES` (:221). Clean.
- (c) PHY modes: KMRN retry do/while loops bounded by
  GG82563_MAX_KMRN_RETRY=5 (e1000_80003es2lan.h:92) at :1312/:1363;
  smart-speed not implemented here; cable-length table indexing guarded
  (`index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5` :774-775 with mask
  0x0007, table[11] ⇒ max touch table[10]). Clean.
- (d) NVM ops: word_size derived from EECD with the `size > 14 → 14` cap
  (:176-178, 16 K words max); write delegates to `e1000_write_nvm_spi`.
  The mdic_wa verify-read at :511 ignores its ret_val before comparing
  `temp` (:513) — `temp` is pre-initialized (:496), worst case a wrong
  page read is returned; verbatim upstream Intel HAL, no kernel memory
  effect (not filed; hardening note only).
- (e) semaphore paths: acquire bounded (:412-431); **release unbounded
  (:455) — this finding**; `e1000_get_cfg_done` bounded
  (PHY_CFG_TIMEOUT × 1 ms, :641-646).
- (f) div0: the only division is the constant `/2` at :780. Clean.
- (g) FreeBSD divergence: file is byte-carried from FreeBSD's ig_hal
  (Intel-shared source, `$FreeBSD$` tag :33); no DragonFly-local
  modifications of substance in this snapshot (single bulk-import commit
  in history).

## Fix validation

fix.diff bounds the retry (50 attempts, matching the acquire-side budget)
with a DEBUGOUT on give-up; `patch -p1 --dry-run` clean. Same-shape
instances exist at e1000_82575.c:1110 and e1000_i210.c:146 — the fix
should be replicated there (noted; those files are separate audit rows).
Cannot be runtime-validated without 80003 hardware → fix_status
not_testable.

## 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.
