mac80211: further RCU fixes
authorJohannes Berg <johannes@sipsolutions.net>
Thu, 10 Apr 2008 13:36:09 +0000 (15:36 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 16 Apr 2008 18:53:22 +0000 (14:53 -0400)
There were a few more instances of sta_info_get calls not being
protected by RCU, fix them.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/mac80211/cfg.c
net/mac80211/wext.c

index 8af576c1d2f135f07d2db86c9edca749a9549e94..0c1095aa94dda2ac60ae02667e1ab1124bf8eb29 100644 (file)
@@ -718,12 +718,18 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
        struct sta_info *sta;
 
        if (mac) {
+               rcu_read_lock();
+
                /* XXX: get sta belonging to dev */
                sta = sta_info_get(local, mac);
-               if (!sta)
+               if (!sta) {
+                       rcu_read_unlock();
                        return -ENOENT;
+               }
 
                sta_info_unlink(&sta);
+               rcu_read_unlock();
+
                sta_info_destroy(sta);
        } else
                sta_info_flush(local, sdata);
@@ -740,17 +746,23 @@ static int ieee80211_change_station(struct wiphy *wiphy,
        struct sta_info *sta;
        struct ieee80211_sub_if_data *vlansdata;
 
+       rcu_read_lock();
+
        /* XXX: get sta belonging to dev */
        sta = sta_info_get(local, mac);
-       if (!sta)
+       if (!sta) {
+               rcu_read_unlock();
                return -ENOENT;
+       }
 
        if (params->vlan && params->vlan != sta->sdata->dev) {
                vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
 
                if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
-                   vlansdata->vif.type != IEEE80211_IF_TYPE_AP)
+                   vlansdata->vif.type != IEEE80211_IF_TYPE_AP) {
+                       rcu_read_unlock();
                        return -EINVAL;
+               }
 
                sta->sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
                ieee80211_send_layer2_update(sta);
@@ -758,6 +770,8 @@ static int ieee80211_change_station(struct wiphy *wiphy,
 
        sta_apply_parameters(local, sta, params);
 
+       rcu_read_unlock();
+
        return 0;
 }
 
index 69aed16faff311482a4767d928f0e3a168945045..5a452575719d4e4e2bd3f22b81989b7f7dc387b2 100644 (file)
@@ -980,6 +980,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct sta_info *sta = NULL;
 
+       rcu_read_lock();
+
        if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
            sdata->vif.type == IEEE80211_IF_TYPE_IBSS)
                sta = sta_info_get(local, sdata->u.sta.bssid);
@@ -996,6 +998,9 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
                wstats->qual.noise = sta->last_noise;
                wstats->qual.updated = local->wstats_flags;
        }
+
+       rcu_read_unlock();
+
        return wstats;
 }