aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
authorSimon Wunderlich <sw@simonwunderlich.de>2013-11-21 12:19:50 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-12-02 05:51:53 -0500
commit7ca133bc7f9dd5cee2b469eb917bd352be80a690 (patch)
tree9527f4cacef336ead7ad622d0ffa9dc237ecdc5a /net/mac80211/cfg.c
parentc56589ed1d25ae110a5b000bc1edea8f6861348f (diff)
mac80211: modify beacon using sdata/wdev-lock, not rtnl lock
The csa finalize worker needs to change the beacon information (for different modes). These are normally protected under rtnl lock, but the csa finalize worker is called by drivers and should not acquire the RTNL lock. Therefore change access protection for beacons to sdata/wdev lock. Reported-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> [fix sdata_dereference] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 267d3aca9947..4a5c21ed64d1 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -857,7 +857,7 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
857 if (!resp || !resp_len) 857 if (!resp || !resp_len)
858 return 1; 858 return 1;
859 859
860 old = rtnl_dereference(sdata->u.ap.probe_resp); 860 old = sdata_dereference(sdata->u.ap.probe_resp, sdata);
861 861
862 new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL); 862 new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL);
863 if (!new) 863 if (!new)
@@ -881,7 +881,8 @@ int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
881 int size, err; 881 int size, err;
882 u32 changed = BSS_CHANGED_BEACON; 882 u32 changed = BSS_CHANGED_BEACON;
883 883
884 old = rtnl_dereference(sdata->u.ap.beacon); 884 old = sdata_dereference(sdata->u.ap.beacon, sdata);
885
885 886
886 /* Need to have a beacon head if we don't have one yet */ 887 /* Need to have a beacon head if we don't have one yet */
887 if (!params->head && !old) 888 if (!params->head && !old)
@@ -958,7 +959,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
958 BSS_CHANGED_P2P_PS; 959 BSS_CHANGED_P2P_PS;
959 int err; 960 int err;
960 961
961 old = rtnl_dereference(sdata->u.ap.beacon); 962 old = sdata_dereference(sdata->u.ap.beacon, sdata);
962 if (old) 963 if (old)
963 return -EALREADY; 964 return -EALREADY;
964 965
@@ -1020,7 +1021,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
1020 1021
1021 err = drv_start_ap(sdata->local, sdata); 1022 err = drv_start_ap(sdata->local, sdata);
1022 if (err) { 1023 if (err) {
1023 old = rtnl_dereference(sdata->u.ap.beacon); 1024 old = sdata_dereference(sdata->u.ap.beacon, sdata);
1025
1024 if (old) 1026 if (old)
1025 kfree_rcu(old, rcu_head); 1027 kfree_rcu(old, rcu_head);
1026 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); 1028 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
@@ -1051,7 +1053,7 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
1051 if (sdata->vif.csa_active) 1053 if (sdata->vif.csa_active)
1052 return -EBUSY; 1054 return -EBUSY;
1053 1055
1054 old = rtnl_dereference(sdata->u.ap.beacon); 1056 old = sdata_dereference(sdata->u.ap.beacon, sdata);
1055 if (!old) 1057 if (!old)
1056 return -ENOENT; 1058 return -ENOENT;
1057 1059
@@ -1071,10 +1073,10 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1071 struct probe_resp *old_probe_resp; 1073 struct probe_resp *old_probe_resp;
1072 struct cfg80211_chan_def chandef; 1074 struct cfg80211_chan_def chandef;
1073 1075
1074 old_beacon = rtnl_dereference(sdata->u.ap.beacon); 1076 old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata);
1075 if (!old_beacon) 1077 if (!old_beacon)
1076 return -ENOENT; 1078 return -ENOENT;
1077 old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp); 1079 old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata);
1078 1080
1079 /* abort any running channel switch */ 1081 /* abort any running channel switch */
1080 sdata->vif.csa_active = false; 1082 sdata->vif.csa_active = false;
@@ -1975,7 +1977,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1975 enum ieee80211_band band; 1977 enum ieee80211_band band;
1976 u32 changed = 0; 1978 u32 changed = 0;
1977 1979
1978 if (!rtnl_dereference(sdata->u.ap.beacon)) 1980 if (!sdata_dereference(sdata->u.ap.beacon, sdata))
1979 return -ENOENT; 1981 return -ENOENT;
1980 1982
1981 band = ieee80211_get_sdata_band(sdata); 1983 band = ieee80211_get_sdata_band(sdata);
@@ -3045,6 +3047,8 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3045 struct ieee80211_if_mesh __maybe_unused *ifmsh; 3047 struct ieee80211_if_mesh __maybe_unused *ifmsh;
3046 int err, num_chanctx; 3048 int err, num_chanctx;
3047 3049
3050 lockdep_assert_held(&sdata->wdev.mtx);
3051
3048 if (!list_empty(&local->roc_list) || local->scanning) 3052 if (!list_empty(&local->roc_list) || local->scanning)
3049 return -EBUSY; 3053 return -EBUSY;
3050 3054