Commit e8da2bb4 authored by Johannes Berg's avatar Johannes Berg

regulatory: clarify locking rules and assertions

Many places that currently check that cfg80211_mutex
is held don't actually use any data protected by it.
The functions that need to hold the cfg80211_mutex
are the ones using the cfg80211_regdomain variable,
so add the lock assertion to those and clarify this
in the comments.

The reason for this is that nl80211 uses the regdom
without being able to hold reg_mutex.
Acked-by: default avatarLuis R. Rodriguez <mcgrof@do-not-panic.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 5d885b99
...@@ -94,14 +94,14 @@ static struct device_type reg_device_type = { ...@@ -94,14 +94,14 @@ static struct device_type reg_device_type = {
/* /*
* Central wireless core regulatory domains, we only need two, * Central wireless core regulatory domains, we only need two,
* the current one and a world regulatory domain in case we have no * the current one and a world regulatory domain in case we have no
* information to give us an alpha2 * information to give us an alpha2.
* Protected by the cfg80211_mutex.
*/ */
const struct ieee80211_regdomain *cfg80211_regdomain; const struct ieee80211_regdomain *cfg80211_regdomain;
/* /*
* Protects static reg.c components: * Protects static reg.c components:
* - cfg80211_world_regdom * - cfg80211_world_regdom
* - cfg80211_regdom
* - last_request * - last_request
* - reg_num_devs_support_basehint * - reg_num_devs_support_basehint
*/ */
...@@ -185,6 +185,9 @@ MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); ...@@ -185,6 +185,9 @@ MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
static void reset_regdomains(bool full_reset) static void reset_regdomains(bool full_reset)
{ {
assert_cfg80211_lock();
assert_reg_lock();
/* avoid freeing static information or freeing something twice */ /* avoid freeing static information or freeing something twice */
if (cfg80211_regdomain == cfg80211_world_regdom) if (cfg80211_regdomain == cfg80211_world_regdom)
cfg80211_regdomain = NULL; cfg80211_regdomain = NULL;
...@@ -215,6 +218,9 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd) ...@@ -215,6 +218,9 @@ static void update_world_regdomain(const struct ieee80211_regdomain *rd)
{ {
WARN_ON(!last_request); WARN_ON(!last_request);
assert_cfg80211_lock();
assert_reg_lock();
reset_regdomains(false); reset_regdomains(false);
cfg80211_world_regdom = rd; cfg80211_world_regdom = rd;
...@@ -422,8 +428,6 @@ static int call_crda(const char *alpha2) ...@@ -422,8 +428,6 @@ static int call_crda(const char *alpha2)
/* Used by nl80211 before kmalloc'ing our regulatory domain */ /* Used by nl80211 before kmalloc'ing our regulatory domain */
bool reg_is_valid_request(const char *alpha2) bool reg_is_valid_request(const char *alpha2)
{ {
assert_cfg80211_lock();
if (!last_request) if (!last_request)
return false; return false;
...@@ -915,8 +919,6 @@ bool reg_last_request_cell_base(void) ...@@ -915,8 +919,6 @@ bool reg_last_request_cell_base(void)
{ {
bool val; bool val;
assert_cfg80211_lock();
mutex_lock(&reg_mutex); mutex_lock(&reg_mutex);
val = reg_request_cell_base(last_request); val = reg_request_cell_base(last_request);
mutex_unlock(&reg_mutex); mutex_unlock(&reg_mutex);
...@@ -999,8 +1001,6 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx, ...@@ -999,8 +1001,6 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx,
bool channel_changed = false; bool channel_changed = false;
struct ieee80211_channel chan_before; struct ieee80211_channel chan_before;
assert_cfg80211_lock();
sband = wiphy->bands[reg_beacon->chan.band]; sband = wiphy->bands[reg_beacon->chan.band];
chan = &sband->channels[chan_idx]; chan = &sband->channels[chan_idx];
...@@ -1042,8 +1042,6 @@ static void wiphy_update_new_beacon(struct wiphy *wiphy, ...@@ -1042,8 +1042,6 @@ static void wiphy_update_new_beacon(struct wiphy *wiphy,
unsigned int i; unsigned int i;
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
assert_cfg80211_lock();
if (!wiphy->bands[reg_beacon->chan.band]) if (!wiphy->bands[reg_beacon->chan.band])
return; return;
...@@ -1062,8 +1060,6 @@ static void wiphy_update_beacon_reg(struct wiphy *wiphy) ...@@ -1062,8 +1060,6 @@ static void wiphy_update_beacon_reg(struct wiphy *wiphy)
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct reg_beacon *reg_beacon; struct reg_beacon *reg_beacon;
assert_cfg80211_lock();
list_for_each_entry(reg_beacon, &reg_beacon_list, list) { list_for_each_entry(reg_beacon, &reg_beacon_list, list) {
if (!wiphy->bands[reg_beacon->chan.band]) if (!wiphy->bands[reg_beacon->chan.band])
continue; continue;
...@@ -1075,6 +1071,8 @@ static void wiphy_update_beacon_reg(struct wiphy *wiphy) ...@@ -1075,6 +1071,8 @@ static void wiphy_update_beacon_reg(struct wiphy *wiphy)
static bool reg_is_world_roaming(struct wiphy *wiphy) static bool reg_is_world_roaming(struct wiphy *wiphy)
{ {
assert_cfg80211_lock();
if (is_world_regdom(cfg80211_regdomain->alpha2) || if (is_world_regdom(cfg80211_regdomain->alpha2) ||
(wiphy->regd && is_world_regdom(wiphy->regd->alpha2))) (wiphy->regd && is_world_regdom(wiphy->regd->alpha2)))
return true; return true;
...@@ -1116,8 +1114,6 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy, ...@@ -1116,8 +1114,6 @@ static void reg_process_ht_flags_channel(struct wiphy *wiphy,
struct ieee80211_channel *channel_before = NULL, *channel_after = NULL; struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
unsigned int i; unsigned int i;
assert_cfg80211_lock();
if (!is_ht40_allowed(channel)) { if (!is_ht40_allowed(channel)) {
channel->flags |= IEEE80211_CHAN_NO_HT40; channel->flags |= IEEE80211_CHAN_NO_HT40;
return; return;
...@@ -1180,6 +1176,7 @@ static void wiphy_update_regulatory(struct wiphy *wiphy, ...@@ -1180,6 +1176,7 @@ static void wiphy_update_regulatory(struct wiphy *wiphy,
{ {
enum ieee80211_band band; enum ieee80211_band band;
assert_cfg80211_lock();
assert_reg_lock(); assert_reg_lock();
if (ignore_reg_update(wiphy, initiator)) if (ignore_reg_update(wiphy, initiator))
...@@ -1299,8 +1296,6 @@ get_reg_request_treatment(struct wiphy *wiphy, ...@@ -1299,8 +1296,6 @@ get_reg_request_treatment(struct wiphy *wiphy,
{ {
struct wiphy *last_wiphy = NULL; struct wiphy *last_wiphy = NULL;
assert_cfg80211_lock();
/* All initial requests are respected */ /* All initial requests are respected */
if (!last_request) if (!last_request)
return REG_REQ_OK; return REG_REQ_OK;
...@@ -2246,8 +2241,6 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -2246,8 +2241,6 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env)
void wiphy_regulatory_register(struct wiphy *wiphy) void wiphy_regulatory_register(struct wiphy *wiphy)
{ {
assert_cfg80211_lock();
mutex_lock(&reg_mutex); mutex_lock(&reg_mutex);
if (!reg_dev_ignore_cell_hint(wiphy)) if (!reg_dev_ignore_cell_hint(wiphy))
...@@ -2263,8 +2256,6 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy) ...@@ -2263,8 +2256,6 @@ void wiphy_regulatory_deregister(struct wiphy *wiphy)
{ {
struct wiphy *request_wiphy = NULL; struct wiphy *request_wiphy = NULL;
assert_cfg80211_lock();
mutex_lock(&reg_mutex); mutex_lock(&reg_mutex);
if (!reg_dev_ignore_cell_hint(wiphy)) if (!reg_dev_ignore_cell_hint(wiphy))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment