]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mt76: use kfree_rcu for offchannel link in mt76_put_vif_phy_link
authorRajat Gupta <rajat.gupta@oss.qualcomm.com>
Thu, 7 May 2026 04:35:31 +0000 (21:35 -0700)
committerFelix Fietkau <nbd@nbd.name>
Tue, 9 Jun 2026 10:15:20 +0000 (10:15 +0000)
mt76_put_vif_phy_link() frees the offchannel mlink with plain kfree()
after rcu_assign_pointer(NULL). However, rcu_assign_pointer only prevents
future RCU readers from obtaining the pointer -- it does not wait for
existing readers that already hold it via rcu_dereference.

The TX datapath (e.g. mt7996_mac_write_txwi) dereferences mlink->wcid
and mlink->idx under rcu_read_lock. If a TX softirq obtained the pointer
via rcu_dereference just before the NULL assignment, it will dereference
freed memory after the kfree.

struct mt76_vif_link already contains an rcu_head field that is unused at
this free site -- a developer oversight, since the adjacent
kfree_rcu_mightsleep call for rx_sc in the same function shows the
pattern was understood.

Replace kfree(mlink) with kfree_rcu(mlink, rcu_head).

Fixes: a8f424c1287c ("wifi: mt76: add multi-radio remain_on_channel functions")
Signed-off-by: Rajat Gupta <rajat.gupta@oss.qualcomm.com>
Link: https://patch.msgid.link/20260507043531.492-1-rajat.gupta@oss.qualcomm.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/channel.c

index 05eee64706ea87f9f19acc103354939c66b767cb..6edcb3b8f2798ef3479aeff681da15bb2b660733 100644 (file)
@@ -307,7 +307,7 @@ void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif,
 
        rcu_assign_pointer(mvif->offchannel_link, NULL);
        dev->drv->vif_link_remove(phy, vif, &vif->bss_conf, mlink);
-       kfree(mlink);
+       kfree_rcu(mlink, rcu_head);
 }
 
 void mt76_roc_complete(struct mt76_phy *phy)