mac80211: fix sdata->radar_required locking
authorMichal Kazior <michal.kazior@tieto.com>
Wed, 29 Jan 2014 06:56:20 +0000 (07:56 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 4 Feb 2014 20:58:10 +0000 (21:58 +0100)
radar_required setting wasn't protected by
local->mtx in some places. This should prevent
from scanning/radar detection/roc colliding.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/mac80211/chan.c
net/mac80211/ibss.c

index b98dc8ce8e25e9316ad52570e68738cf8d5ae2bb..27fa53bfed0d28397ecae4893e5f5e6fdbe53ffc 100644 (file)
@@ -970,9 +970,9 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
        /* TODO: make hostapd tell us what it wants */
        sdata->smps_mode = IEEE80211_SMPS_OFF;
        sdata->needed_rx_chains = sdata->local->rx_chains;
-       sdata->radar_required = params->radar_required;
 
        mutex_lock(&local->mtx);
+       sdata->radar_required = params->radar_required;
        err = ieee80211_vif_use_channel(sdata, &params->chandef,
                                        IEEE80211_CHANCTX_SHARED);
        mutex_unlock(&local->mtx);
@@ -3002,8 +3002,8 @@ static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
        struct ieee80211_local *local = sdata->local;
        int err, changed = 0;
 
-       sdata->radar_required = sdata->csa_radar_required;
        mutex_lock(&local->mtx);
+       sdata->radar_required = sdata->csa_radar_required;
        err = ieee80211_vif_change_channel(sdata, &changed);
        mutex_unlock(&local->mtx);
        if (WARN_ON(err < 0))
index f43613a97dd664e2daf1856b001d7bdee5708d4f..42c659229a090a7c86f6ad42a33df11afd40b6c8 100644 (file)
@@ -196,6 +196,8 @@ static bool ieee80211_is_radar_required(struct ieee80211_local *local)
 {
        struct ieee80211_sub_if_data *sdata;
 
+       lockdep_assert_held(&local->mtx);
+
        rcu_read_lock();
        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
                if (sdata->radar_required) {
index 82d3d14b03c56ea8e4dba5867ab0834646d33a89..f01d4683d473931675c6c058fd6de8814e1e0238 100644 (file)
@@ -303,6 +303,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                mutex_unlock(&local->mtx);
                return;
        }
+       sdata->radar_required = radar_required;
        mutex_unlock(&local->mtx);
 
        memcpy(ifibss->bssid, bssid, ETH_ALEN);
@@ -318,7 +319,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        rcu_assign_pointer(ifibss->presp, presp);
        mgmt = (void *)presp->head;
 
-       sdata->radar_required = radar_required;
        sdata->vif.bss_conf.enable_beacon = true;
        sdata->vif.bss_conf.beacon_int = beacon_int;
        sdata->vif.bss_conf.basic_rates = basic_rates;