summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZilin Guan <zilin@seu.edu.cn>2026-01-16 17:49:19 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-05-23 14:08:33 +0300
commiteb466406d2094deefadc2cd6ddb4f6eeb086d1b4 (patch)
treed854ffe9930f090a79e5ccdeac1483aab22348ec
parent2d8e0053bca29143ace51e08c980ff076844a4b0 (diff)
downloadlinux-eb466406d2094deefadc2cd6ddb4f6eeb086d1b4.tar.xz
wifi: mt76: Fix memory leak after mt76_connac_mcu_alloc_sta_req()
[ Upstream commit c41075ce8cf05ed8c0e7b7efef000dce548ffc42 ] mt76_connac_mcu_alloc_sta_req() allocates an skb which is expected to be freed eventually by mt76_mcu_skb_send_msg(). However, currently if an intermediate function fails before sending, the allocated skb is leaked. Specifically, mt76_connac_mcu_sta_wed_update() and mt76_connac_mcu_sta_key_tlv() may fail, leading to an immediate memory leak in the error path. Fix this by explicitly freeing the skb in these error paths. Commit 7c0f63fe37a5 ("wifi: mt76: mt7996: fix memory leak on mt7996_mcu_sta_key_tlv error") made a similar change. Compile tested only. Issue found using a prototype static analysis tool and code review. Fixes: d1369e515efe ("wifi: mt76: connac: introduce mt76_connac_mcu_sta_wed_update utility routine") Fixes: 6683d988089c ("mt76: connac: move mt76_connac_mcu_add_key in connac module") Fixes: 4f831d18d12d ("wifi: mt76: mt7915: enable WED RX support") Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips") Signed-off-by: Zilin Guan <zilin@seu.edu.cn> Link: https://patch.msgid.link/20260116144919.1482558-1-zilin@seu.edu.cn Signed-off-by: Felix Fietkau <nbd@nbd.name> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c16
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7915/mcu.c4
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/mcu.c4
3 files changed, 18 insertions, 6 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 0457712286d5..3f583e2a1dc1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1295,8 +1295,10 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif_link *mvif,
wtbl_hdr);
ret = mt76_connac_mcu_sta_wed_update(dev, skb);
- if (ret)
+ if (ret) {
+ dev_kfree_skb(skb);
return ret;
+ }
ret = mt76_mcu_skb_send_msg(dev, skb, cmd, true);
if (ret)
@@ -1309,8 +1311,10 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif_link *mvif,
mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
ret = mt76_connac_mcu_sta_wed_update(dev, skb);
- if (ret)
+ if (ret) {
+ dev_kfree_skb(skb);
return ret;
+ }
return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
}
@@ -2764,12 +2768,16 @@ int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
return PTR_ERR(skb);
ret = mt76_connac_mcu_sta_key_tlv(sta_key_conf, skb, key, cmd);
- if (ret)
+ if (ret) {
+ dev_kfree_skb(skb);
return ret;
+ }
ret = mt76_connac_mcu_sta_wed_update(dev, skb);
- if (ret)
+ if (ret) {
+ dev_kfree_skb(skb);
return ret;
+ }
return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index 95b8f34a7b1d..023c92dac064 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -1765,8 +1765,10 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
}
out:
ret = mt76_connac_mcu_sta_wed_update(&dev->mt76, skb);
- if (ret)
+ if (ret) {
+ dev_kfree_skb(skb);
return ret;
+ }
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index dec8e2de86b6..abcdd0e0b3b5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -1288,8 +1288,10 @@ int mt7925_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
return PTR_ERR(skb);
ret = mt7925_mcu_sta_key_tlv(wcid, sta_key_conf, skb, key, cmd, msta);
- if (ret)
+ if (ret) {
+ dev_kfree_skb(skb);
return ret;
+ }
return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
}