Reorder buffer rxa_m[] mutated without dedicated lock: RX races timer flush and ADDBA re-init (double-free/UAF)
Summary
ieee80211_rx_ampdu rxa_m[64] accessed by 3 contexts with no per-rap lock: RX ieee80211_ampdu_reorder(:780/:908), node-age callout ampdu_rx_flush(:1125/:1151 frees mbufs), ADDBA ampdu_rx_start(:540/:553 purge+memset). Code littered with XXX locking(:1819,:1842). Remote peer interleaves A-MPDU + ADDBA -> double-free/UAF mbuf corruption.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0320 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | source-trace confirmed race, no WiFi HW | 2.5 KB | β raw |
| README.md | readme | status explanation | 692 B | β raw |
| fix.diff | suggested-fix | add rxa_lock spinlock to ieee80211_rx_ampdu; compiles on GENERIC | 2.1 KB | view raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-0320 PoC β WiFi A-MSDU reorder buffer race
Status: REAL (source-trace confirmed), not testable on this guest
The race is confirmed by tracing three concurrent mutators of
rxa_m[] with no dedicated lock:
- RX reorder write at ieee80211_ht.c:911
- Node-age flush at :1151
- ADDBA memset at :553
Not testable because:
- No WiFi hardware on this guest
- wlan module not loaded at runtime
- Requires a remote WiFi peer interleaving A-MPDU + ADDBA frames
The code IS compiled into GENERIC (device wlan).
Fix
See fix.diff β adds struct spinlock rxa_lock to
struct ieee80211_rx_ampdu and wraps the critical sections.
Verified to compile cleanly on GENERIC.
DF-0320 β Reorder buffer rxa_m[] mutated without dedicated lock
Verdict: REAL (source-trace confirmed) β not testable on this guest (no WiFi HW)
Mechanism
struct ieee80211_rx_ampdu (sys/netproto/802_11/ieee80211_ht.h:151-163)
contains struct mbuf *rxa_m[IEEE80211_AGGR_BAWMAX] (64-slot reorder
buffer) which is mutated by three concurrent execution contexts with
no dedicated lock:
-
RX reorder path β
ieee80211_ampdu_reorder()atieee80211_ht.c:780writesrxa_m[off]at:911and callsampdu_rx_flush()at:897which frees mbufs fromrxa_m[]. -
Node-age callout β
ieee80211_ht_node_age()at:1125iterates TIDs and callsampdu_rx_flush()at:1151which frees mbufs fromrxa_m[]. Runs from a callout/softclock context. -
ADDBA re-init β
ampdu_rx_start()at:540callsampdu_rx_purge()thenmemset(rap, 0, sizeof(*rap))at:553, wiping allrxa_m[]entries without freeing them first (or racing with a concurrent flush that's freeing them).
The code is littered with XXX locking comments (:570, :885,
:1144). Without serialization:
- Context 3 (memset) can zero rxa_m[i] while Context 1/2 is freeing
the mbuf β double-free (both the memset-wiped slot and the
caller's mbuf reference become dangling)
- Context 2 (flush) can free rxa_m[i] while Context 1 is writing
to it β use-after-free / type confusion
Privilege / testability
- Remote-triggerable: a WiFi peer interleaving A-MPDU data frames with ADDBA request frames can race the RX reorder path against the ADDBA re-init.
- The wlan code IS compiled into GENERIC (
device wlan). - But requires WiFi hardware β none on this guest.
- The
wlanmodule is not loaded at runtime.
This is a valid hard blocker: the code path is unreachable at runtime on this guest (no WiFi hardware).
Fix
fix.diff β adds a struct spinlock rxa_lock to
struct ieee80211_rx_ampdu (using available rxa_pad space),
initializes it in ampdu_rx_start(), and wraps the critical
ampdu_rx_purge()/ampdu_rx_flush() calls in all three contexts.
Also adds #include <sys/spinlock2.h> to ieee80211_ht.c.
Verified to compile cleanly on GENERIC.
Impact
Remote double-free / UAF of kernel mbufs from an unauthenticated WiFi peer. On a default kernel with INVARIANTS, this would likely manifest as a panic (slab poisoning detected). Without INVARIANTS, it's a heap corruption primitive exploitable for code execution. Realistic only in a WiFi deployment with HT (802.11n) A-MPDU aggregation.
Fix verification
not_testablecompile validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. rxa_m[64] reorder buffer mutated by 3 contexts no dedicated lock -> double-free/UAF. No WiFi HW. Fix compiles.
No comments yet.