cfg80211: fix regulatory restore upon user hints
When we restore regulatory settings its possible CRDA will not reply because of a bogus user entry. In this case the bogus entry will prevent any further processing on cfg80211 for regulatory domains even if we restore regulatory settings. To prevent this we suck out all pending requests when restoring regulatory settings and add them back into the queue after we have queued up the reset work. The impact of not having this applied is that a user with privileges can issue a userspace regulatory hint while we are disasocciating and this would prevent any further processing of regulatory domains. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
02a7fa00a6
commit
146095557b
|
@ -1744,6 +1744,8 @@ static void restore_regulatory_settings(bool reset_user)
|
|||
{
|
||||
char alpha2[2];
|
||||
struct reg_beacon *reg_beacon, *btmp;
|
||||
struct regulatory_request *reg_request, *tmp;
|
||||
LIST_HEAD(tmp_reg_req_list);
|
||||
|
||||
mutex_lock(&cfg80211_mutex);
|
||||
mutex_lock(®_mutex);
|
||||
|
@ -1751,6 +1753,25 @@ static void restore_regulatory_settings(bool reset_user)
|
|||
reset_regdomains();
|
||||
restore_alpha2(alpha2, reset_user);
|
||||
|
||||
/*
|
||||
* If there's any pending requests we simply
|
||||
* stash them to a temporary pending queue and
|
||||
* add then after we've restored regulatory
|
||||
* settings.
|
||||
*/
|
||||
spin_lock(®_requests_lock);
|
||||
if (!list_empty(®_requests_list)) {
|
||||
list_for_each_entry_safe(reg_request, tmp,
|
||||
®_requests_list, list) {
|
||||
if (reg_request->initiator !=
|
||||
NL80211_REGDOM_SET_BY_USER)
|
||||
continue;
|
||||
list_del(®_request->list);
|
||||
list_add_tail(®_request->list, &tmp_reg_req_list);
|
||||
}
|
||||
}
|
||||
spin_unlock(®_requests_lock);
|
||||
|
||||
/* Clear beacon hints */
|
||||
spin_lock_bh(®_pending_beacons_lock);
|
||||
if (!list_empty(®_pending_beacons)) {
|
||||
|
@ -1785,8 +1806,31 @@ static void restore_regulatory_settings(bool reset_user)
|
|||
*/
|
||||
if (is_an_alpha2(alpha2))
|
||||
regulatory_hint_user(user_alpha2);
|
||||
}
|
||||
|
||||
if (list_empty(&tmp_reg_req_list))
|
||||
return;
|
||||
|
||||
mutex_lock(&cfg80211_mutex);
|
||||
mutex_lock(®_mutex);
|
||||
|
||||
spin_lock(®_requests_lock);
|
||||
list_for_each_entry_safe(reg_request, tmp, &tmp_reg_req_list, list) {
|
||||
REG_DBG_PRINT("Adding request for country %c%c back "
|
||||
"into the queue\n",
|
||||
reg_request->alpha2[0],
|
||||
reg_request->alpha2[1]);
|
||||
list_del(®_request->list);
|
||||
list_add_tail(®_request->list, ®_requests_list);
|
||||
}
|
||||
spin_unlock(®_requests_lock);
|
||||
|
||||
mutex_unlock(®_mutex);
|
||||
mutex_unlock(&cfg80211_mutex);
|
||||
|
||||
REG_DBG_PRINT("Kicking the queue\n");
|
||||
|
||||
schedule_work(®_work);
|
||||
}
|
||||
|
||||
void regulatory_hint_disconnect(void)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue