]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mt76: mt7996: Fix possible token leak in mt7996_tx_prepare_skb()
authorLorenzo Bianconi <lorenzo@kernel.org>
Sun, 31 May 2026 09:10:59 +0000 (11:10 +0200)
committerFelix Fietkau <nbd@nbd.name>
Tue, 9 Jun 2026 10:15:22 +0000 (10:15 +0000)
If link_conf or link_sta lookup fails in mt7996_tx_prepare_skb routine,
mt7996 driver leaks an already allocated tx token. Fix the issue
releasing the token in case of error.

Fixes: 7ef0c7ad735b0 ("wifi: mt76: mt7996: Implement MLD address translation for EAPOL")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260531-mt7996_tx_prepare_skb-token-leack-v1-1-2b9c9f59ceb1@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7996/mac.c
drivers/net/wireless/mediatek/mt76/tx.c

index c98446057282ae7251914685aa625cf5147c4870..ade8706623b07dbd3623645d038b6b15eddb3100 100644 (file)
@@ -1067,11 +1067,11 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 
                link_conf = rcu_dereference(vif->link_conf[wcid->link_id]);
                if (!link_conf)
-                       return -EINVAL;
+                       goto error_release_token;
 
                link_sta = rcu_dereference(sta->link[wcid->link_id]);
                if (!link_sta)
-                       return -EINVAL;
+                       goto error_release_token;
 
                dma_sync_single_for_cpu(mdev->dma_dev, tx_info->buf[1].addr,
                                        tx_info->buf[1].len, DMA_TO_DEVICE);
@@ -1176,6 +1176,10 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
        tx_info->nbuf = MT_CT_DMA_BUF_NUM;
 
        return 0;
+
+error_release_token:
+       mt76_token_release(mdev, id, NULL);
+       return -EINVAL;
 }
 
 u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
index 22f9690634c942cbbc7712a403dc3c57e01284ff..f96d9c471853549a74309704da6cb9b525f9ddea 100644 (file)
@@ -933,7 +933,7 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
 #endif
        }
 
-       if (dev->token_count < dev->token_size - MT76_TOKEN_FREE_THR &&
+       if (wake && dev->token_count < dev->token_size - MT76_TOKEN_FREE_THR &&
            dev->phy.q_tx[0]->blocked)
                *wake = true;