mt76_tx_status_skb_add() checks rcu_access_pointer(dev->wcid[wcid->idx]) before taking dev->status_lock, then allocates a pktid afterwards. A concurrent mt76_wcid_cleanup() can run between the check and the lock, letting a stale wcid be re-added to dev->wcid_list after teardown. Worse, the check only tests for a non-NULL slot, so it also passes if a different wcid has since been published at the same idx. Move the check under status_lock, alongside idr_alloc(), and compare identity (rcu_access_pointer(dev->wcid[wcid->idx]) != wcid) instead of just testing for non-NULL, so that a reused index is correctly rejected. Fixes: fcfe1b5e162b ("mt76: fix tx status related use-after-free race on station removal") Signed-off-by: Ryan Leung --- Changes in v2: - check that dev->wcid[wcid->idx] still points at this wcid, not just that it is non-NULL, since the slot can be reused by a different station between the unlocked check and the lock being taken. - Link to v1: https://patch.msgid.link/20260821-mt76-stale-wcid-race-v1-1-d6de3f842506@protonmail.com --- drivers/net/wireless/mediatek/mt76/tx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index 3707ee19e4ae..0f74d808d328 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -129,7 +129,7 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, memset(cb, 0, sizeof(*cb)); - if (!wcid || !rcu_access_pointer(dev->wcid[wcid->idx])) + if (!wcid) return MT_PACKET_ID_NO_ACK; if (info->flags & IEEE80211_TX_CTL_NO_ACK) @@ -147,6 +147,11 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, spin_lock_bh(&dev->status_lock); + if (rcu_access_pointer(dev->wcid[wcid->idx]) != wcid) { + pid = MT_PACKET_ID_NO_ACK; + goto out; + } + pid = idr_alloc(&wcid->pktid, skb, MT_PACKET_ID_FIRST, MT_PACKET_ID_MASK, GFP_ATOMIC); if (pid < 0) { --- base-commit: ca800a9302764c445de0da0e84d2252400a770ee change-id: 20260821-mt76-stale-wcid-race-4d92f898437b Best regards, -- Ryan Leung