⬢ DragonFlyBSD Kernel Audit
DF-5259 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5259",
  "status": "inconclusive",
  "reproduced": false,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Same lock-domain hole as the run/urtwn twins (DF-5246/DF-5254), but here the lock was outright DROPPED in the port: mtw_update_beacon() (if_mtw.c:3829-3868) touches rvp->beacon_mbuf (NULL-check, ieee80211_beacon_alloc, ieee80211_beacon_update which WRITES seq/capinfo/TIM into the mbuf) under only the net80211 ic lock, while mtw_newstate() at 1802-1803 (after releasing the ic lock at 1771) and mtw_vap_delete() at 891 m_freem() the same mbuf under only MTW_LOCK - the two lock sets are disjoint, so beacon_update can write into a freed 2KB mbuf cluster. FreeBSDs run_update_beacon() wraps exactly this region in RUN_LOCK. Simulated on the guest with a harness mirroring the exact code regions and lock domains: 127131-127406 write-after-free interleavings per 10s run (~91% of frees land inside the beacon_update window) across 3 runs. In-kernel reproduction is hardware-gated (no MT7601U can attach to the QEMU guest).",
  "exploit_chain": "hostap/ibss vap + power-save client TIM churn (remote-peer triggerable) racing ifconfig down/destroy or a RUN transition -> ieee80211_beacon_update writes into freed 2KB cluster -> heap corruption -> panic to privesc with post-free reallocation control",
  "evidence": "run.log: UAF writes: 127355/127131/127406 over 3 x 10s runs; beacon_race.c; VERDICT.md lock-intersection table",
  "kernel_refs": [
    "sys/bus/u4b/wlan/if_mtw.c:3855",
    "sys/bus/u4b/wlan/if_mtw.c:3860",
    "sys/bus/u4b/wlan/if_mtw.c:1802",
    "sys/bus/u4b/wlan/if_mtw.c:891",
    "sys/bus/u4b/wlan/if_mtw.c:1771"
  ],
  "poc_changes": "Harness written from scratch (no seed); pthread mutexes model IEEE80211_LOCK(ic) and MTW_LOCK(sc); atomic poison flag so the process survives while counting kernel-equivalent UAF writes",
  "attempts": 3,
  "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 -O2 -pthread -o /tmp/beacon_race /tmp/beacon_race.c",
  "run_cmd": "/tmp/beacon_race 10   (3 runs, see run.log)",
  "code_hash": "794fc172c2a897a6eda12beca23cf9cca8c2d42498a78553f8cb5c1ab9f27a14",
  "notes": "All mtw(4) paths are hardware-gated on the QEMU guest (no USB controller is passed through and no MT7601U device model exists); evidence is in-kernel structural (DF-5258: kld probe against the real if_mtwvar.h) or userland interleaving simulation mirroring the exact code regions/lock domains, per the wlan-trio pass-2 methodology (cf. DF-5246..DF-5257).",
  "recommended_fix": "Take MTW_LOCK around the beacon_mbuf check/alloc/use in mtw_update_beacon() (what FreeBSD run_update_beacon does)",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored and verified with git apply --check against the pristine sys/ tree, but cannot be kernel-tested: the guest has no USB controller and no MT7601U device model, so neither baseline nor patched kernel behavior is exercisable. Hardware-gated: not_testable.",
  "fix_evidence": "fix.diff (git-apply clean); VERDICT.md"
}