]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/wireless/sme.c
cfg80211: validate channel settings across interfaces
[net-next-2.6.git] / net / wireless / sme.c
index 340934f714b2df619bddda570c013476ea760e8d..219c3bc2c37d3c1a3bf88a0b5aae1b11751d2602 100644 (file)
@@ -256,9 +256,11 @@ void cfg80211_sme_scan_done(struct net_device *dev)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
 
+       mutex_lock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
        wdev_lock(wdev);
        __cfg80211_sme_scan_done(dev);
        wdev_unlock(wdev);
+       mutex_unlock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
 }
 
 void cfg80211_sme_rx_auth(struct net_device *dev,
@@ -644,6 +646,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
                       struct cfg80211_cached_keys *connkeys)
 {
        struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct ieee80211_channel *chan;
        int err;
 
        ASSERT_WDEV_LOCK(wdev);
@@ -651,6 +654,10 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
        if (wdev->sme_state != CFG80211_SME_IDLE)
                return -EALREADY;
 
+       chan = rdev_fixed_channel(rdev, wdev);
+       if (chan && chan != connect->channel)
+               return -EBUSY;
+
        if (WARN_ON(wdev->connect_keys)) {
                kfree(wdev->connect_keys);
                wdev->connect_keys = NULL;
@@ -785,9 +792,11 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
 {
        int err;
 
+       mutex_lock(&rdev->devlist_mtx);
        wdev_lock(dev->ieee80211_ptr);
        err = __cfg80211_connect(rdev, dev, connect, connkeys);
        wdev_unlock(dev->ieee80211_ptr);
+       mutex_unlock(&rdev->devlist_mtx);
 
        return err;
 }