⬢ DragonFlyBSD Kernel Audit
DF-3641 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3641",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-level certain: bnx_sysctl_std_refill (sys/dev/netif/bnx/if_bnx.c:5684-5685) iterates sc->bnx_tx_ringcnt while indexing sc->bnx_rx_ret_ring[i] — a copy-paste of the loop bound from a TX loop; it must iterate sc->bnx_rx_retcnt. On BCM5719/5720 with rx_retcnt>1 and tx_ringcnt==1 (common non-bundled RSS setup), writing dev.bnx.N.std_refill updates only ring 0; rings 1..rx_retcnt-1 silently keep the default bnx_rx_cntmax from bnx_dma_alloc (if_bnx.c:4259-4260), so the operator-visible value disagrees with the per-ring refill thresholds in force at if_bnx.c:2825. Not memory-unsafe: tx_ringcnt <= rx_retcnt is structurally guaranteed (if_bnx.c:5784-5799 clamps TX ring_max to min(BNX_TX_RING_MAX, rx_retcnt); if_ringcnt_fixup clamps the count, sys/net/if.c:3944-3953; if_ringmap_align only equalizes grids, sys/net/if.c:4029-4036). Also fixed: validation at 5679 admits negative cntmax, which truncates into uint16_t bnx_rx_cntmax (-5 -> 65531, effectively disabling that refill trigger; RX still refills via the bnx_rx_std_used>=256 check at 2890). Runtime verification honestly inconclusive: sysctl dev.bnx.0.std_refill is unknown oid on the audit guest (no Broadcom device, NO_BROADCOM_DEVICE), so the handler cannot execute there; guest /usr/src if_bnx.c md5 49a18c4b7642b9b2ebd1d02ad11542e4 matches the audited tree and the guest-side dump of lines 5679-5686 shows the mismatch verbatim.",
  "exploit_chain": "",
  "evidence": "run.log (guest: sysctl dev.bnx.0.std_refill unknown oid, NO_BROADCOM_DEVICE, md5 match, verbatim sed dump of the wrong loop bound), VERDICT.md (path:line trace + the structural tx<=rx proof), trigger.c (sysctlbyname probe, builds clean -O -Wall), fix.diff (iterate bnx_rx_retcnt + reject cntmax<1, git-apply verified)",
  "kernel_refs": [
    "sys/dev/netif/bnx/if_bnx.c:5669",
    "sys/dev/netif/bnx/if_bnx.c:5679",
    "sys/dev/netif/bnx/if_bnx.c:5684",
    "sys/dev/netif/bnx/if_bnx.c:5685",
    "sys/dev/netif/bnx/if_bnx.c:4259",
    "sys/dev/netif/bnx/if_bnx.c:2825",
    "sys/dev/netif/bnx/if_bnx.c:5784",
    "sys/dev/netif/bnx/if_bnxvar.h:204",
    "sys/net/if.c:3944"
  ],
  "poc_changes": "No seed existed (new pass-2 finding); trigger written as a sysctl probe that self-reports the absent OID on the audit guest.",
  "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": 40,
  "guest_dirty": 0,
  "build_cmd": "cc -O -Wall -o trigger trigger.c (guest)",
  "run_cmd": "./run.sh via dfbsd-qemu/vm.sh run_root (sysctl probe + source dump of the wrong loop bound)",
  "code_hash": "2962ddf0ed418237a377fb9511cc25bceccd5565ce84f9ed51fdf675175bebc4",
  "notes": "Found during the pass-2 interrupt-topology/ring-count sweep (DF-3606 analogue hunt): the MSI-X fallback itself is clean in bnx (failure fails attach rather than blackholing), but this sysctl handler revealed the tx/rx count copy-paste. Filed Info: correctness only, root-only sysctl, no memory-safety impact (structural tx<=rx).",
  "recommended_fix": "In bnx_sysctl_std_refill, iterate sc->bnx_rx_retcnt (not bnx_tx_ringcnt) and reject cntmax < 1 (see fix.diff).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff corrects the loop bound to sc->bnx_rx_retcnt and adds the cntmax<1 rejection; git apply --check passes against the audited tree. Cannot be runtime-validated: the sysctl handler never executes on the audit guest (no Broadcom device), so neither baseline nor patched behavior is observable there.",
  "fix_evidence": "fix.diff; run.log (dev.bnx.0.std_refill unknown oid => handler unreachable on guest)"
}