aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2011-04-05 13:49:04 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-07 15:52:29 -0400
commita90c7a313a1c5b4fc99f987a2ae8f92ab0ae35c7 (patch)
treeb5484abed3ef3f23e17375fbc44657b875b7f418 /net/wireless
parent146095557b01cf5ff5d66554d96cbb8133d94eb9 (diff)
cfg80211: add a timer for invalid user reg hints
We have no other option but to inform userspace that we have queued up their regulatory hint request when we are given one given that nl80211 operates atomically on user requests. The best we can do is accept the request, and add a delayed work item for processing failure and cancel it if we succeeed. Upon failure we restore the regulatory settings and ignore the user input. This fixes this reported bug: https://bugzilla.kernel.org/show_bug.cgi?id=28112 Reported-by: gregoryx.alagnou@intel.com Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/reg.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 7b1a89b20ebf..2714379ce2d6 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -106,6 +106,9 @@ struct reg_beacon {
106static void reg_todo(struct work_struct *work); 106static void reg_todo(struct work_struct *work);
107static DECLARE_WORK(reg_work, reg_todo); 107static DECLARE_WORK(reg_work, reg_todo);
108 108
109static void reg_timeout_work(struct work_struct *work);
110static DECLARE_DELAYED_WORK(reg_timeout, reg_timeout_work);
111
109/* We keep a static world regulatory domain in case of the absence of CRDA */ 112/* We keep a static world regulatory domain in case of the absence of CRDA */
110static const struct ieee80211_regdomain world_regdom = { 113static const struct ieee80211_regdomain world_regdom = {
111 .n_reg_rules = 5, 114 .n_reg_rules = 5,
@@ -1330,6 +1333,9 @@ static void reg_set_request_processed(void)
1330 need_more_processing = true; 1333 need_more_processing = true;
1331 spin_unlock(&reg_requests_lock); 1334 spin_unlock(&reg_requests_lock);
1332 1335
1336 if (last_request->initiator == NL80211_REGDOM_SET_BY_USER)
1337 cancel_delayed_work_sync(&reg_timeout);
1338
1333 if (need_more_processing) 1339 if (need_more_processing)
1334 schedule_work(&reg_work); 1340 schedule_work(&reg_work);
1335} 1341}
@@ -1440,8 +1446,17 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1440 r = __regulatory_hint(wiphy, reg_request); 1446 r = __regulatory_hint(wiphy, reg_request);
1441 /* This is required so that the orig_* parameters are saved */ 1447 /* This is required so that the orig_* parameters are saved */
1442 if (r == -EALREADY && wiphy && 1448 if (r == -EALREADY && wiphy &&
1443 wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) 1449 wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) {
1444 wiphy_update_regulatory(wiphy, initiator); 1450 wiphy_update_regulatory(wiphy, initiator);
1451 return;
1452 }
1453
1454 /*
1455 * We only time out user hints, given that they should be the only
1456 * source of bogus requests.
1457 */
1458 if (reg_request->initiator == NL80211_REGDOM_SET_BY_USER)
1459 schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142));
1445} 1460}
1446 1461
1447/* 1462/*
@@ -2169,6 +2184,13 @@ out:
2169 mutex_unlock(&reg_mutex); 2184 mutex_unlock(&reg_mutex);
2170} 2185}
2171 2186
2187static void reg_timeout_work(struct work_struct *work)
2188{
2189 REG_DBG_PRINT("Timeout while waiting for CRDA to reply, "
2190 "restoring regulatory settings");
2191 restore_regulatory_settings(true);
2192}
2193
2172int __init regulatory_init(void) 2194int __init regulatory_init(void)
2173{ 2195{
2174 int err = 0; 2196 int err = 0;
@@ -2222,6 +2244,7 @@ void /* __init_or_exit */ regulatory_exit(void)
2222 struct reg_beacon *reg_beacon, *btmp; 2244 struct reg_beacon *reg_beacon, *btmp;
2223 2245
2224 cancel_work_sync(&reg_work); 2246 cancel_work_sync(&reg_work);
2247 cancel_delayed_work_sync(&reg_timeout);
2225 2248
2226 mutex_lock(&cfg80211_mutex); 2249 mutex_lock(&cfg80211_mutex);
2227 mutex_lock(&reg_mutex); 2250 mutex_lock(&reg_mutex);