diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-05-13 17:04:41 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-07-02 16:50:10 -0700 |
commit | 0b4dbf904310eb56ef54b7a033f17651a0d0849f (patch) | |
tree | b9268b57d1eb8676be2c79824674cd5d05b62259 | |
parent | a08b8fc14b865bc751c6b83b1fab5f0ad3225c11 (diff) |
cfg80211: fix in nl80211_set_reg()
commit 61405e97788b1bc4e7c5be5b4ec04a73fc11bac2 upstream.
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().
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | net/wireless/nl80211.c | 5 | ||||
-rw-r--r-- | net/wireless/reg.c | 2 |
2 files changed, 6 insertions, 1 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 641e3e26c09..b759106522f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2388,6 +2388,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; @@ -2425,13 +2427,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; } diff --git a/net/wireless/reg.c b/net/wireless/reg.c index d3ac70551ce..9765bc892f0 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -389,6 +389,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; |