* [PATCH wireless v2 1/2] wifi: mt76: mt7915: validate WCID index before WTBL lookup
2026-04-07 5:39 [PATCH wireless v2 0/2] wifi: mt76: validate WCID index before WTBL lookup Joshua Klinesmith
@ 2026-04-07 5:39 ` Joshua Klinesmith
2026-04-07 5:39 ` [PATCH wireless v2 2/2] wifi: mt76: mt7996: " Joshua Klinesmith
1 sibling, 0 replies; 3+ messages in thread
From: Joshua Klinesmith @ 2026-04-07 5:39 UTC (permalink / raw)
To: linux-wireless
Cc: nbd, lorenzo, ryder.lee, shayne.chen, sean.wang,
Joshua Klinesmith, stable
The mt7915 driver does not validate WCID indices extracted from
hardware TX free events and TX status reports before using them
for WTBL MMIO register accesses. The hardware WCID field is 10
bits wide (max 1023) but actual WTBL capacity is only 288
(MT7915) or 544 (MT7916). An out-of-range index causes
mt7915_mac_wtbl_lmac_addr() to compute an invalid MMIO address,
leading to a kernel data abort:
Unable to handle kernel paging request at virtual address
ffffff88d5ab0010
The mt7615, mt7921, and mt7925 drivers already validate WCID
indices against their WTBL size before use. Add the same bounds
checks in mt7915_mac_tx_free() and mt7915_mac_add_txs().
Additionally, when a WCID pair lookup in the TX free path
resolves to a valid WCID that is not a station (wcid_to_sta()
returns NULL), or the WCID index is out of range, clear both
wcid and sta so that subsequent non-pair MSDU entries do not
attribute TX statistics or pass a stale station pointer to
mt76_connac2_txwi_free().
Fixes: c17780e7b21e ("mt76: mt7915: add txfree event v3")
Cc: stable@vger.kernel.org
Signed-off-by: Joshua Klinesmith <joshuaklinesmith@gmail.com>
---
drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 2f307c4caff1..19435f3c6fa5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -913,10 +913,19 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
u16 idx;
idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info);
+ if (idx >= mt7915_wtbl_size(dev)) {
+ wcid = NULL;
+ sta = NULL;
+ continue;
+ }
+
wcid = mt76_wcid_ptr(dev, idx);
sta = wcid_to_sta(wcid);
- if (!sta)
+ if (!sta) {
+ wcid = NULL;
+ sta = NULL;
continue;
+ }
msta = container_of(wcid, struct mt7915_sta, wcid);
mt76_wcid_add_poll(&dev->mt76, &msta->wcid);
@@ -1004,6 +1013,9 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
u8 pid;
wcidx = le32_get_bits(txs_data[2], MT_TXS2_WCID);
+ if (wcidx >= mt7915_wtbl_size(dev))
+ return;
+
pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
if (pid < MT_PACKET_ID_WED)
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH wireless v2 2/2] wifi: mt76: mt7996: validate WCID index before WTBL lookup
2026-04-07 5:39 [PATCH wireless v2 0/2] wifi: mt76: validate WCID index before WTBL lookup Joshua Klinesmith
2026-04-07 5:39 ` [PATCH wireless v2 1/2] wifi: mt76: mt7915: " Joshua Klinesmith
@ 2026-04-07 5:39 ` Joshua Klinesmith
1 sibling, 0 replies; 3+ messages in thread
From: Joshua Klinesmith @ 2026-04-07 5:39 UTC (permalink / raw)
To: linux-wireless
Cc: nbd, lorenzo, ryder.lee, shayne.chen, sean.wang,
Joshua Klinesmith, stable
Same class of bug as mt7915: the mt7996 driver does not validate
WCID indices from TX free events or TX status reports before
WTBL lookups. An out-of-range WCID causes invalid MMIO accesses
leading to a kernel data abort.
Add bounds checks in mt7996_mac_tx_free() and
mt7996_mac_add_txs() to match the pattern used by mt7615,
mt7921, and mt7925 drivers.
Additionally, clear the carried wcid and link_sta state when
a WCID pair lookup fails (either out of range or not a station),
so that subsequent header and MSDU entries in the same TX free
event do not attribute statistics or free tokens against a stale
WCID from a previous pair.
Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Cc: stable@vger.kernel.org
Signed-off-by: Joshua Klinesmith <joshuaklinesmith@gmail.com>
---
drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 3d9648fb6773..f962ad398e04 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -1248,9 +1248,16 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
u16 idx;
idx = FIELD_GET(MT_TXFREE_INFO_WLAN_ID, info);
+ if (idx >= mt7996_wtbl_size(dev)) {
+ wcid = NULL;
+ link_sta = NULL;
+ goto next;
+ }
+
wcid = mt76_wcid_ptr(dev, idx);
sta = wcid_to_sta(wcid);
if (!sta) {
+ wcid = NULL;
link_sta = NULL;
goto next;
}
@@ -1482,6 +1489,9 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)
u8 pid;
wcidx = le32_get_bits(txs_data[2], MT_TXS2_WCID);
+ if (wcidx >= mt7996_wtbl_size(dev))
+ return;
+
pid = le32_get_bits(txs_data[3], MT_TXS3_PID);
if (pid < MT_PACKET_ID_NO_SKB)
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread