mac80211: move roc cookie assignment earlier
authorEliad Peller <eliad@wizery.com>
Sun, 12 Jan 2014 09:06:37 +0000 (11:06 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 6 Feb 2014 08:55:17 +0000 (09:55 +0100)
ieee80211_start_roc_work() might add a new roc
to existing roc, and tell cfg80211 it has already
started.

However, this might happen before the roc cookie
was set, resulting in REMAIN_ON_CHANNEL (started)
event with null cookie. Consequently, it can make
wpa_supplicant go out of sync.

Fix it by setting the roc cookie earlier.

Cc: stable@vger.kernel.org
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c

index f9ae9b8..94b4acb 100644 (file)
@@ -2638,6 +2638,24 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
        INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work);
        INIT_LIST_HEAD(&roc->dependents);
 
+       /*
+        * cookie is either the roc cookie (for normal roc)
+        * or the SKB (for mgmt TX)
+        */
+       if (!txskb) {
+               /* local->mtx protects this */
+               local->roc_cookie_counter++;
+               roc->cookie = local->roc_cookie_counter;
+               /* wow, you wrapped 64 bits ... more likely a bug */
+               if (WARN_ON(roc->cookie == 0)) {
+                       roc->cookie = 1;
+                       local->roc_cookie_counter++;
+               }
+               *cookie = roc->cookie;
+       } else {
+               *cookie = (unsigned long)txskb;
+       }
+
        /* if there's one pending or we're scanning, queue this one */
        if (!list_empty(&local->roc_list) ||
            local->scanning || local->radar_detect_enabled)
@@ -2772,24 +2790,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
        if (!queued)
                list_add_tail(&roc->list, &local->roc_list);
 
-       /*
-        * cookie is either the roc cookie (for normal roc)
-        * or the SKB (for mgmt TX)
-        */
-       if (!txskb) {
-               /* local->mtx protects this */
-               local->roc_cookie_counter++;
-               roc->cookie = local->roc_cookie_counter;
-               /* wow, you wrapped 64 bits ... more likely a bug */
-               if (WARN_ON(roc->cookie == 0)) {
-                       roc->cookie = 1;
-                       local->roc_cookie_counter++;
-               }
-               *cookie = roc->cookie;
-       } else {
-               *cookie = (unsigned long)txskb;
-       }
-
        return 0;
 }