⬢ DragonFlyBSD Kernel Audit
DF-3640 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3640",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-level certain: bnx_reset (sys/dev/netif/bnx/if_bnx.c:2585-2592) requests the on-chip NVRAM software arbitration (BGE_NVRAMSWARB_SET1, polls GNT1 up to 160ms, prints and CONTINUES on timeout) and never releases it \u2014 BGE_NVRAMSWARB_CLR1 appears zero times in if_bnx.c (grep executed on the guests byte-identical /usr/src copy, run.log). bnx_reset runs on every attach/init/stop/watchdog/error-recovery cycle, so the host holds the flash arbitration for the drivers lifetime, locking out the APE management firmware (NC-SI/DASH) and any other arbiter agent until power cycle. The bge code this driver derives from pairs acquire/release (if_bge.c:551-590) and upstream tg3/FreeBSD bge release after chip reset; bce had the same family filed as DF-3605. Runtime verification honestly inconclusive: no Broadcom PCI device on the audit guest (NO_BROADCOM_DEVICE, sysctl hw.bnx unknown oid), and the lock state is chip-internal, unobservable without hardware.",
  "exploit_chain": "",
  "evidence": "run.log (guest: driver in kernel, no Broadcom device, no attach, src md5 49a18c4b7642b9b2ebd1d02ad11542e4, grep CLR1-in-bnx=0 vs bge=1, NVRAMSWARB lines 2585/2587 only), VERDICT.md (full path:line trace + upstream comparison), trigger.c (annotated hardware-precondition trigger), fix.diff (CLR1 release after bnx_ape_unlock in bnx_reset)",
  "kernel_refs": [
    "sys/dev/netif/bnx/if_bnx.c:2585",
    "sys/dev/netif/bnx/if_bnx.c:2587",
    "sys/dev/netif/bnx/if_bnx.c:2591",
    "sys/dev/netif/bnx/if_bnx.c:2715",
    "sys/dev/netif/bnx/if_bnx.c:2092",
    "sys/dev/netif/bnx/if_bnx.c:3604",
    "sys/dev/netif/bnx/if_bnx.c:2983",
    "sys/dev/netif/bnx/if_bnx.c:4000",
    "sys/dev/netif/bnx/if_bnx.c:405",
    "sys/dev/netif/bge/if_bge.c:588"
  ],
  "poc_changes": "No seed existed (new pass-2 finding); trigger written as an annotated hardware-precondition skeleton, built clean (-O -Wall) and executed on the guest; the decisive evidence is the guest-side grep of the byte-identical source.",
  "attempts": 1,
  "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": 45,
  "guest_dirty": 0,
  "build_cmd": "cc -O -Wall -o trigger trigger.c (guest)",
  "run_cmd": "./run.sh via dfbsd-qemu/vm.sh run_root (kldstat/pciconf/sysctl/md5 + grep NVRAMSWARB_CLR1 proofs)",
  "code_hash": "1880d4b8a572d21830eab733783b6765d3a797be390e8ab0045e60055bf5dab0",
  "notes": "Direct DF-3605 (bce NVRAM lock) analogue for bnx. Also noted while auditing: the timeout path prints and continues without the grant (if_bnx.c:2591-2592) rather than aborting the reset. No kernel memory-safety impact; management-plane interop only, hence Low.",
  "recommended_fix": "In bnx_reset, write BGE_NVRAMSWARB_CLR1 (+ read-back) after bnx_ape_unlock(BGE_APE_LOCK_GRC) to release the NVRAM arbitration, matching bges paired idiom (see fix.diff).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff adds the paired CLR1 release at the point upstream drivers release (post-reset, before the firmware handshake poll). Cannot be runtime-validated: the guest has no Broadcom device, so the arbiter state cannot be observed before or after the patch (same reason the PoC is inconclusive). The patch touches only register writes on an existing path.",
  "fix_evidence": "fix.diff; run.log (NO_BROADCOM_DEVICE => neither baseline nor patched behavior observable)"
}