From a666d5637bc3afd3e310be09fac048906560097b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 23 Apr 2022 07:01:18 +0200 Subject: [PATCH] mt76: fix tx status related use-after-free race on station removal There is a small race window where ongoing tx activity can lead to a skb getting added to the status tracking idr after that idr has already been cleaned up, which will keep the wcid linked in the status poll list. Fix this by only adding status skbs if the wcid pointer is still assigned in dev->wcid, which gets cleared early by mt76_sta_pre_rcu_remove Fixes: bd1e3e7b693c ("mt76: introduce packet_id idr") Tested-by: Ben Greear Signed-off-by: Felix Fietkau --- mac80211.c | 2 ++ tx.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mac80211.c b/mac80211.c index 79c84f4e..18b5de55 100644 --- a/mac80211.c +++ b/mac80211.c @@ -1383,7 +1383,9 @@ void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv; mutex_lock(&dev->mutex); + spin_lock_bh(&dev->status_lock); rcu_assign_pointer(dev->wcid[wcid->idx], NULL); + spin_unlock_bh(&dev->status_lock); mutex_unlock(&dev->mutex); } EXPORT_SYMBOL_GPL(mt76_sta_pre_rcu_remove); diff --git a/tx.c b/tx.c index 870c0fff..02067edc 100644 --- a/tx.c +++ b/tx.c @@ -120,7 +120,7 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, memset(cb, 0, sizeof(*cb)); - if (!wcid) + if (!wcid || !rcu_access_pointer(dev->wcid[wcid->idx])) return MT_PACKET_ID_NO_ACK; if (info->flags & IEEE80211_TX_CTL_NO_ACK)