{
  "finding_id": "DF-3761",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-level certain, runtime honestly inconclusive (hardware-gated). alc_rxintr (sys/dev/netif/alc/if_alc.c:3222-3289) walks the Rx return ring with no work bound (:3236): the loop exits only on a non-VALID entry or IFF_RUNNING clearing. The drivers process_limit knob (if_alc.c:1696-1713, ALC_PROC_DEFAULT 64, if_alcvar.h:71-73) - exactly the bound this loop should use - is never read anywhere in the driver (guest-side grep: references only at :1697-1711); FreeBSD bounds the identical loop (alc_rxintr(sc, int count), if (count-- <= 0) break;) and DragonFlys msk(4) bounds its own walk (if_msk.c:3225), proving the bound was intended and lost. Attack: a remote, unauthenticated, default-config attacker floods alc0 at line rate (1.488 Mpps small frames at 1GbE); the per-frame m_getcl + bus_dmamap_load_mbuf_segment + if_input cost (alc_newbuf :3187-3199 via alc_rxeof :3332) exceeds arrival rate, so the return ring stays perpetually non-empty and the loop never terminates. alc_intr has the NIC interrupt disabled for the whole walk (:3082, re-enabled only at :3110) and the walk runs holding the interface serializer (:3075): the interrupt thread pins one CPU at 100% indefinitely, every other driver entry point (ifconfig, ioctls, alc_tick) blocks forever, and callout delivery starves on that CPU - a remote-triggerable NIC + single-CPU livelock (DoS). The audit guest has no Atheros device (env.txt/run.log: NO_ATHEROS_PCI, ifconfig=vtnet0 lo0, NO_ALC_KLD, no hw.alc sysctl; if_alc.ko present only as a module file; guest src md5 == audited tree), so the instance itself cannot be fired; per family convention recorded as inconclusive. Not a memory-safety bug: availability only.",
  "exploit_chain": "Remote unauthenticated attacker on a network segment of an alc(4) interface sends a sustained line-rate small-packet flood; the interfaces interrupt thread enters alc_rxintr and never exits, pinning one CPU and holding the serializer so the interface (and all its ioctls/timers) wedges until the flood stops. No memory corruption, no privilege escalation.",
  "evidence": "run.log (presence probe NO_ATHEROS_PCI / unknown oid hw.alc + guest-side grep proving the knob has no reader + msk comparison), env.txt (fresh instance state, md5 of if_alc.c == audited tree), VERDICT.md (path:line trace incl. FreeBSD head comparison), trigger.c (annotated remote-flood precondition), fix.diff (count bound, git-apply clean)",
  "kernel_refs": [
    "sys/dev/netif/alc/if_alc.c:3236",
    "sys/dev/netif/alc/if_alc.c:3239",
    "sys/dev/netif/alc/if_alc.c:3248",
    "sys/dev/netif/alc/if_alc.c:3332",
    "sys/dev/netif/alc/if_alc.c:3187",
    "sys/dev/netif/alc/if_alc.c:1696",
    "sys/dev/netif/alc/if_alc.c:3082",
    "sys/dev/netif/alc/if_alc.c:3110",
    "sys/dev/netif/alc/if_alc.c:3075",
    "sys/dev/netif/alc/if_alcvar.h:71",
    "sys/dev/netif/msk/if_msk.c:3225"
  ],
  "poc_changes": "No seed PoC. Authored trigger.c as an annotated remote-flood precondition document (nothing meaningful to execute without AR81xx hardware) plus a guest-side source-proof run.sh; honest hardware-absent verification per family convention.",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "runtime_sec": 60,
  "guest_dirty": 0,
  "build_cmd": "(none - documented remote-flood trigger)",
  "run_cmd": "vm.sh run_root ifconfig -l; pciconf -l | grep -i -E \"atheros|1969\"; sysctl hw.alc; grep -n alc_process_limit /usr/src/sys/dev/netif/alc/if_alc.c",
  "code_hash": "",
  "notes": "Pass-2 result for sys/dev/netif/alc/if_alc.c (GLM 5.3). FreeBSD head if_alc.c fetched and diffed mentally against the DFly copy for this specific loop; the DFly copy retains the sysctl but lost/never had the loop bound. msk(4) shows the intended DFly idiom.",
  "recommended_fix": "Bound the alc_rxintr loop with the existing alc_process_limit knob: n = sc->alc_process_limit; if (n-- <= 0) break; at the loop head (see fix.diff).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff (git-apply clean) ports FreeBSDs count idiom using the existing knob; alc_intrs post-loop interrupt re-enable (:3110) makes the device immediately re-raise RX if work remains, so the bound costs no packets. Cannot be runtime-validated without AR81xx hardware.",
  "fix_evidence": "fix.diff"
}