cfg80211: fix in nl80211_set_reg()
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Wed, 13 May 2009 21:04:41 +0000 (17:04 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 20 May 2009 18:46:32 +0000 (14:46 -0400)
There is a race on access to last_request and its alpha2
through reg_is_valid_request() and us possibly processing
first another regulatory request on another CPU. We avoid
this improbably race by locking with the cfg80211_mutex as
we should have done in the first place. While at it add
the assert on locking on reg_is_valid_request().

Cc: stable@kernel.org
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/wireless/nl80211.c
net/wireless/reg.c

index 66e0fb6a6420b7a446f661f67074b5e42674b956..632504060789dfc3d5913eeb7ae2d02d96a5c5f7 100644 (file)
@@ -2570,6 +2570,8 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
                        return -EINVAL;
        }
 
+       mutex_lock(&cfg80211_mutex);
+
        if (!reg_is_valid_request(alpha2)) {
                r = -EINVAL;
                goto bad_reg;
@@ -2607,13 +2609,14 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
 
        BUG_ON(rule_idx != num_rules);
 
-       mutex_lock(&cfg80211_mutex);
        r = set_regdom(rd);
+
        mutex_unlock(&cfg80211_mutex);
 
        return r;
 
  bad_reg:
+       mutex_unlock(&cfg80211_mutex);
        kfree(rd);
        return r;
 }
index 48db569d4c6b47c2e7d95ee37db0144f10ce7dc0..8d176a8010baebcef113478a2e845ec6c09f497a 100644 (file)
@@ -382,6 +382,8 @@ static int call_crda(const char *alpha2)
 /* Used by nl80211 before kmalloc'ing our regulatory domain */
 bool reg_is_valid_request(const char *alpha2)
 {
+       assert_cfg80211_lock();
+
        if (!last_request)
                return false;