DF-3576 / verdict.json
{ "finding_id": "DF-3576", "status": "inconclusive", "reproduced": 0, "impact": "panic", "confidence": "certain", "verdict": "Remote-triggerable kernel divide-by-zero: iwn_set_timing() (if_iwn.c:5596-5597) computes val = ni_intval * 1024 then tstamp % val with no zero check; ni_intval==0 reaches it because net80211 parses beacon bintval (ieee80211_input.c:545), flags BPARSE_BINTVAL_INVALID (ieee80211_input.c:700-707) but the STA scan consumer stores it anyway (ieee80211_scan_sta.c:314) and ieee80211_sta_join copies it into the node (ieee80211_node.c:818); association then drives iwn_run->iwn_set_timing. The verbatim arithmetic faulted with SIGFPE (exit 136) deterministically 4/4 runs on the DragonFly guest (a runtime hardware divide, not a compiler fold), and the control value survived. Full in-kernel repro was impossible: the audit guest is virtio-only and has no Intel WiFi device (if_iwn.ko exists, no 8086 wifi PCI device), so classification is inconclusive-at-runtime / certain-at-source.", "exploit_chain": "evil-twin AP beacons bintval=0 -> victim scan cache se_intval=0 (BINTVAL_INVALID never checked) -> ieee80211_sta_join: ni_intval=0 -> victim associates -> iwn_newstate RUN -> iwn_run (if_iwn.c:7237) -> iwn_set_timing: tstamp % 0 -> #DE -> kernel panic (remote DoS).", "evidence": "run.log (control survives; malicious call prints ni_intval=0 -> val=0 ; taking modulo then exit=136 SIGFPE), run.2.log (3/3 stress), iwn_timing_div0.c (verbatim arithmetic copy), VERDICT.md (full hop-by-hop source trace), fix.diff.", "kernel_refs": [ "sys/dev/netif/iwn/if_iwn.c:5596", "sys/dev/netif/iwn/if_iwn.c:5597", "sys/dev/netif/iwn/if_iwn.c:7237", "sys/netproto/802_11/wlan/ieee80211_input.c:545", "sys/netproto/802_11/wlan/ieee80211_input.c:700", "sys/netproto/802_11/wlan/ieee80211_scan_sta.c:314", "sys/netproto/802_11/wlan/ieee80211_node.c:818" ], "poc_changes": "No seed existed; harness authored in this run. Verbatim copy of the iwn_set_timing arithmetic (if_iwn.c:5590-5598) plus a control run with ni_intval=100.", "attempts": 4, "guest_uname": "DragonFly dfbsd 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": 12, "guest_dirty": 0, "build_cmd": "cc -O2 -Wall -o iwn_timing_div0 iwn_timing_div0.c", "run_cmd": "./iwn_timing_div0 # expect exit=136 (SIGFPE) after control succeeds", "code_hash": "07bb064f0db767ce26f405620e471d4b21c743a78226b77c8ac0956799d3c285", "notes": "Guest has if_iwn.ko and driver registered (kldstat -v: pci/iwn) but no Intel WiFi PCI device, so the kernel path cannot be driven. Complementary net80211 hardening (honor IEEE80211_BPARSE_BINTVAL_INVALID in sta_add_scan) would protect all drivers; ieee80211_init_neighbor (node.c:1525) copies sp->bintval unvalidated too.", "recommended_fix": "Reject ni_intval==0 (return EINVAL) in iwn_set_timing before the modulo; also honor IEEE80211_BPARSE_BINTVAL_INVALID in ieee80211_scan_sta.c sta_add_scan.", "fix_status": "not_testable", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff authored against the read-only sys/ tree; not kernel-validated because the guest cannot execute the iwn driver path (no hardware). Baseline fault primitive reproduced (SIGFPE, exit 136); the guard makes the function return EINVAL instead of dividing.", "fix_evidence": "findings/poc/DF-3576/fix.diff" } |