lkml.org 
[lkml]   [2022]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.17 373/772] mt76: fix tx status related use-after-free race on station removal
    Date
    From: Felix Fietkau <nbd@nbd.name>

    [ Upstream commit fcfe1b5e162bf473c1d47760962cec8523c00466 ]

    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 <greearb@candelatech.com>
    Signed-off-by: Felix Fietkau <nbd@nbd.name>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/net/wireless/mediatek/mt76/mac80211.c | 2 ++
    drivers/net/wireless/mediatek/mt76/tx.c | 2 +-
    2 files changed, 3 insertions(+), 1 deletion(-)

    diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
    index 6023ff6dc059..cbda0f57ff9a 100644
    --- a/drivers/net/wireless/mediatek/mt76/mac80211.c
    +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
    @@ -1344,7 +1344,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/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
    index 6b8c9dc80542..ccaf9a31fbc4 100644
    --- a/drivers/net/wireless/mediatek/mt76/tx.c
    +++ b/drivers/net/wireless/mediatek/mt76/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)
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-07 23:08    [W:6.886 / U:0.052 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site