tx_intr STA_CSR4 completion desync: qid 5-15 garbage mapped to the mgt ring, results matched to the driver's stat cursor rather than a device index, unguarded txq->queued-- underflow defeating the ring-full gate, and m leaked on the ni==NULL path
Summary
tx_intr attributes each device-posted TX result to txq->data[txq->stat] - the driver's sequential cursor - and maps any qid>=4 to the mgt ring. Reordered/duplicated STA_CSR4 entries complete the wrong slot, freeing an in-flight mbuf while the device may still DMA it (UAF window); the unguarded queued-- underflows on spurious entries so the ring-full gate never trips and the post path reuses device-owned slots; the ni==NULL continue drops m without m_freem. Device-fed desync, different mechanism from rt2860's DF-3749. qid-check+floor+free fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3967 Β· 11 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.1 KB | β raw | |
| VERDICT.md | β | 1.7 KB | β raw | |
| trigger.c | β | 2.0 KB | view raw | |
| build.sh | β | 67 B | view raw | |
| run.sh | β | 91 B | view raw | |
| run.log | β | 12 B | view raw | |
| env.txt | β | 1021 B | view raw | |
| fix.diff | β | 1.0 KB | view raw | |
| build.log | β | 37.9 KB | view raw | |
| manifest.json | β | 370 B | view raw | |
| verdict.json | β | 3.2 KB | view raw |
DF-3967 β rt2661_tx_intr: device-fed TX-status desync (qid garbage β mgtq, unguarded queued--, stat-cursor assumption) β mbuf UAF window / m leak
File: sys/dev/netif/ral/rt2661.c (pass 2, checklist item (b) TX ring indices)
What
rt2661_tx_intr (896β960) attributes each device-posted TX result to
txq->data[txq->stat] β the driver's cursor β and trusts the device's qid
field ((val>>8)&0xf; qid 5..15 silently mapped to the mgt ring at 906).
txq->queued-- (955) has no floor, so spurious results underflow queued
and defeat the ring-full gate at 1687 β the post path (1561β1562, 1643β1644)
overwrites slots the device still owns. A result landing on an in-flight slot
frees its mbuf via ieee80211_tx_complete (959) while the device may still
DMA it. The ni == NULL continue (916β917) drops m without freeing (leak).
Device-gated (malicious/buggy NIC firmware), same trust class as rt2860's DF-3749 but a different mechanism (cursor desync vs. stale node map).
Build / Run
Hardware-gated; see trigger.c (fw-patched NIC or PCIe emulation posting spurious TX_STAT_VALID entries).
DF-3967 verdict β likely device-fed desync, Low
Reproduced?
No Ralink NIC on the guest (env.txt).
Analysis
- rt2661reg.h:191
RT2661_TX_QID(v) ((v>>8)&0xf)β 0..15; rt2661.c:906txq = (qid <= 3) ? &sc->txq[qid] : &sc->mgtq;β qid 4 is the intended mgt id, 5..15 are garbage yet indistinguishable from mgt. - rt2661.c:909
data = &txq->data[txq->stat]β completion is matched to the driver's sequential cursor, not to any device-provided index; any device reordering/duplication desyncs stat from the true completion order. - rt2661.c:955
txq->queued--unguarded; gate at 1687 comparesqueued >= RT2661_TX_RING_COUNT - 1β negative queued never trips it, so cur laps next and slots owned by the device are reused (1561-1562/1643-1644 overwrite data->m/desc while DMA pending). - rt2661.c:916-917:
if (ni == NULL) continue;afterm = data->m; data->m = NULL;β m is dropped, never freed (leak per spurious entry). - Driver-fed cursors themselves are in-bounds (cur/next/stat wrapped at count), so the memory-safety exposure is strictly device-fed desync.
Severity rationale
Low: requires a misbehaving device (same bar as DF-3749/DF-1312-class findings); consequence is an mbuf UAF write window (device DMA into a freed cluster) or resource exhaustion β real but hardware-gated.
Fix
fix.diff: reject qid>4, free m on the ni==NULL path, floor the queued--.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testablefix.diff closes the three gap (qid mapping, m leak, queued underflow); git apply --check clean. Runtime validation needs the NIC fix.diff applied to the guest /usr/src copy and the if_ral.ko module rebuilt clean with -Werror (build.log; combined with the other two rt2661 fix.diffs of this batch); runtime validation still impossible without the NIC.
fix.diff; fix.diff applied to the guest /usr/src copy and the if_ral.ko module rebuilt clean with -Werror (build.log; combined with the other two rt2661 fix.diffs of this batch); runtime validation still impossible without the NIC.
Confirmed kernel references
Detail
Exploit chain
device posts duplicated/reordered TX_STAT_VALID entries -> stat cursor desync -> ieee80211_tx_complete frees an mbuf whose cluster the device still DMAs into -> freed-cluster reuse corruption window; independently queued<0 reopens a full ring -> slot overwrite while pending.
Evidence (decisive lines)
VERDICT.md (cursor/gate analysis path:line), trigger.c, env.txt, fix.diff (qid guard + m free + queued floor)
PoC changes
Informational trigger only (needs device firmware control / PCIe emulation).
Verified recommended fix
Validate qid<=4, free m on the ni==NULL path, and floor txq->queued at zero (fix.diff).
Verdict
Device-fed TX-completion desync in rt2661_tx_intr (rt2661.c:896-960): qid (val>>8)&0xf values 5..15 are silently attributed to the mgt ring (:906); results are matched to the driver's sequential stat cursor (:909) rather than a device index, so reordered/duplicated STA_CSR4 entries complete the wrong slot β freeing an in-flight mbuf via ieee80211_tx_complete (:959) while the device may still DMA it β and the unguarded txq->queued-- (:955) underflows on spurious entries, defeating the ring-full gate (:1687) so the post path reuses device-owned slots; the ni==NULL continue (:916-917) also leaks m. Requires a misbehaving/compromised NIC (same trust bar as sibling rt2860 DF-3749, different mechanism). Not reproduced: no Ralink hardware on the guest.
No comments yet.