mac80211: fix virtual monitor interface iteration
authorJohannes Berg <johannes.berg@intel.com>
Wed, 29 Jan 2014 12:28:02 +0000 (13:28 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 6 Feb 2014 08:55:22 +0000 (09:55 +0100)
During channel context assignment, the interface should
be found by interface iteration, so we need to assign the
pointer before the channel context.

Reported-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Tested-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/iface.c

index ae2eb14..d6d1f1d 100644 (file)
@@ -418,20 +418,24 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
                return ret;
        }
 
+       mutex_lock(&local->iflist_mtx);
+       rcu_assign_pointer(local->monitor_sdata, sdata);
+       mutex_unlock(&local->iflist_mtx);
+
        mutex_lock(&local->mtx);
        ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
                                        IEEE80211_CHANCTX_EXCLUSIVE);
        mutex_unlock(&local->mtx);
        if (ret) {
+               mutex_lock(&local->iflist_mtx);
+               rcu_assign_pointer(local->monitor_sdata, NULL);
+               mutex_unlock(&local->iflist_mtx);
+               synchronize_net();
                drv_remove_interface(local, sdata);
                kfree(sdata);
                return ret;
        }
 
-       mutex_lock(&local->iflist_mtx);
-       rcu_assign_pointer(local->monitor_sdata, sdata);
-       mutex_unlock(&local->iflist_mtx);
-
        return 0;
 }