# DF-3751 — rt2860 reads `rt2860_node.wcid` from nodes allocated as plain `ieee80211_node` (OOB read)

`struct rt2860_node` (rt2860var.h:102-107) adds `wcid` (+ two dead rate-index arrays)
after the embedded `ieee80211_node`, and four sites cast a net80211 node to it and read
`->wcid`:

- `rt2860_ampdu_rx_start` rt2860.c:919 and `rt2860_ampdu_rx_stop` rt2860.c:934 —
  **live** (`#ifdef IEEE80211_HT` is satisfied in default builds), invoked by net80211
  whenever an 802.11n Block-Ack session starts/stops for a node;
- `rt2860_set_key` rt2860.c:3266 / `rt2860_delete_key` rt2860.c:3349 — dead
  (`HW_CRYPTO` is not defined anywhere in the tree).

But the driver never overrides `ic->ic_node_alloc` (attach hooks only
`ic_node_free`, rt2860.c:352-353), so net80211 allocates nodes with the generic
`node_alloc` = `kmalloc(sizeof(struct ieee80211_node), M_80211_NODE, M_INTWAIT|M_ZERO)`
(wlan/ieee80211_node.c:917-923). Every `((struct rt2860_node *)ni)->wcid` load reads
**one byte past the end of the heap allocation** (allocator size-class padding or the
next slab chunk). The garbage `wcid` (0-255) then indexes
`RT2860_WCID_ENTRY(wcid) + 4` = MMIO `0x1800 + 8*wcid + 4` (max 0x1ffc — inside the
register aperture): a read-modify-write of the wrong WCID attribute word on every BA
session event. No kernel-memory disclosure of the OOB byte; no kernel-RAM write.
Severity: Low (CWE-125, wrong-HW-config / robustness).

**Fix** (`fix.diff`): give the driver its own `rt2860_node_alloc`
(`kmalloc(sizeof(struct rt2860_node))`, matching `rt2860_node_free`'s existing hook)
and actually maintain `rn->wcid` in `rt2860_newassoc` (which was clearly the original
intent — the field is otherwise written nowhere).

**Status:** source-certain; not runnable — audit guest has no Ralink NIC (env.txt).
