]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: mac80211: finish link init before RCU publish
authorJohannes Berg <johannes.berg@intel.com>
Tue, 24 Jun 2025 11:07:49 +0000 (13:07 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Jul 2025 14:03:13 +0000 (16:03 +0200)
[ Upstream commit d87c3ca0f8f1ca4c25f2ed819e954952f4d8d709 ]

Since the link/conf pointers can be accessed without any
protection other than RCU, make sure the data is actually
set up before publishing the structures.

Fixes: b2e8434f1829 ("wifi: mac80211: set up/tear down client vif links properly")
Link: https://patch.msgid.link/20250624130749.9a308b713c74.I4a80f5eead112a38730939ea591d2e275c721256@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/mac80211/link.c

index 16cbaea93fc32ddca6b6da85a7c4dbf0a87eda78..af4d2b2e9a26f82f6d3191f0903c935fde892053 100644 (file)
@@ -28,8 +28,16 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
        if (link_id < 0)
                link_id = 0;
 
-       rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf);
-       rcu_assign_pointer(sdata->link[link_id], link);
+       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+               struct ieee80211_sub_if_data *ap_bss;
+               struct ieee80211_bss_conf *ap_bss_conf;
+
+               ap_bss = container_of(sdata->bss,
+                                     struct ieee80211_sub_if_data, u.ap);
+               ap_bss_conf = sdata_dereference(ap_bss->vif.link_conf[link_id],
+                                               ap_bss);
+               memcpy(link_conf, ap_bss_conf, sizeof(*link_conf));
+       }
 
        link->sdata = sdata;
        link->link_id = link_id;
@@ -65,6 +73,9 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
 
                ieee80211_link_debugfs_add(link);
        }
+
+       rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf);
+       rcu_assign_pointer(sdata->link[link_id], link);
 }
 
 void ieee80211_link_stop(struct ieee80211_link_data *link)