Search Linux Wireless

[PATCH v4 04/15] nl80211: disallow user requests prior to regulatory_init()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If cfg80211 is built into the kernel there is perhaps a small
time window betwen nl80211_init() and regulatory_init() where
cfg80211_regdomain hasn't yet been initialized to let the
wireless core do its work. During that rare case and time
frame (if its even possible) we don't allow user regulatory
changes as cfg80211 is working on enabling its first regulatory
domain.

To check for cfg80211_regdomain we now contend the entire operation
using the cfg80211_mutex.

Signed-off-by: Luis R. Rodriguez <lrodriguez@xxxxxxxxxxx>
---
 net/wireless/nl80211.c |   34 ++++++++++++++++++++++++++--------
 1 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f353e39..5d3e968 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1882,24 +1882,42 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
 	int r;
 	char *data = NULL;
 
-	if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
-		return -EINVAL;
+	/*
+	 * You should only get this when cfg80211 hasn't yet initialized
+	 * completely when built-in to the kernel right between the time
+	 * window between nl80211_init() and regulatory_init(), if that is
+	 * even possible.
+	 */
+	mutex_lock(&cfg80211_mutex);
+	if (unlikely(!cfg80211_regdomain)) {
+		r = -EINPROGRESS;
+		goto out;
+	}
+
+	if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) {
+		r = -EINVAL;
+		goto out;
+	}
 
 	data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
 
 #ifdef CONFIG_WIRELESS_OLD_REGULATORY
 	/* We ignore world regdom requests with the old regdom setup */
-	if (is_world_regdom(data))
-		return -EINVAL;
+	if (is_world_regdom(data)) {
+		r = -EINVAL;
+		goto out;
+	}
 #endif
-	mutex_lock(&cfg80211_mutex);
 	r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, 0, ENVIRON_ANY);
-	mutex_unlock(&cfg80211_mutex);
-	/* This means the regulatory domain was already set, however
+	/*
+	 * This means the regulatory domain was already set, however
 	 * we don't want to confuse userspace with a "successful error"
-	 * message so lets just treat it as a success */
+	 * message so lets just treat it as a success
+	 */
 	if (r == -EALREADY)
 		r = 0;
+out:
+	mutex_unlock(&cfg80211_mutex);
 	return r;
 }
 
-- 
1.6.0.3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux