β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-5264

mtw_stop never frees the endpoint queues; the next mtw_init_locked memsets them via mtw_setup_tx_list, orphaning every queued mbuf and its ieee80211_node reference - repeatable kernel leak per down/up cycle

Summary

mtw_stop drains sc_snd/rx_m but never the six sc_epq rings; next up's setup_tx_list memsets the rings, orphaning tx_data[].m mbufs + their .ni node refs (up to 6x32/cycle) - leaked refs pin ieee80211_node allocations forever. FreeBSD run_stop frees the TX pool. Twin of DF-5251/DF-5255. unsetup-in-stop fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-5264 Β· 3 files
FileTypeDescriptionSize
env.txt β€” 183 B view raw
fix.diff β€” 400 B view raw
verdict.json β€” 2.8 KB view raw

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

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.diff (git-apply clean); VERDICT.md
↓ fix.diffper-fix-DF-5264

Confirmed kernel references

Detail

Exploit chain

traffic fills tx rings -> ifconfig down (mtw_stop leaves rings) -> ifconfig up (setup_tx_list memsets) -> mbuf clusters + node refs leaked -> repeat -> kernel memory exhaustion over time

Evidence (decisive lines)

Code-cited analysis; VERDICT.md walks mtw_stop -> mtw_init_locked -> mtw_setup_tx_list memset. No guest run (hardware-gated): untested

Verified recommended fix

Call mtw_unsetup_tx_list() for all MTW_EP_QUEUES in mtw_stop() before the next init memsets them

Verdict

On stop, mtw_stop() (if_mtw.c:4626-4713) drains mbufq and rx_m but never touches the six sc_epq[] rings; FreeBSD's run_stop() frees the TX pool ('free TX pool (should be empty)' loop in if_run.c). On the next up, mtw_init_locked() (4463-4467) calls mtw_setup_tx_list() for every queue, whose first act is memset(pq, 0, sizeof(*pq)) (950-954) - silently orphaning any tx_data[].m mbufs and leaking their tx_data[].ni node references. After a down with frames queued (ring holds up to 6x32 entries), up to ~192 mbuf clusters plus node references are leaked per cycle; leaked node references keep ieee80211_node allocations pinned forever (the node-table purge decrements but never reaches zero), so each down/up cycle under load permanently loses kernel memory. Repeatable by any admin (ifconfig wlanX down/up) with traffic in flight; unprivileged users merely need to keep the ring non-empty while root cycles the interface. Twin of DF-5251/DF-5255.