aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2009-02-21 00:04:25 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-27 14:52:56 -0500
commit761cf7ecffc4bc079679e65c3b1ab107c1c1fb56 (patch)
treebd9ff2715f6f191c31368c9efc534fdc68187705
parentbcf4f99b7b1e0971b79e8df40331e77fc1744049 (diff)
cfg80211: add assert_cfg80211_lock() to ensure proper protection
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/wireless/core.c5
-rw-r--r--net/wireless/core.h6
-rw-r--r--net/wireless/nl80211.c3
-rw-r--r--net/wireless/reg.c15
4 files changed, 27 insertions, 2 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 39d40d1e06db..e347093ccc73 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -7,7 +7,6 @@
7#include <linux/if.h> 7#include <linux/if.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/err.h> 9#include <linux/err.h>
10#include <linux/mutex.h>
11#include <linux/list.h> 10#include <linux/list.h>
12#include <linux/nl80211.h> 11#include <linux/nl80211.h>
13#include <linux/debugfs.h> 12#include <linux/debugfs.h>
@@ -50,6 +49,8 @@ cfg80211_drv_by_wiphy_idx(int wiphy_idx)
50 if (!wiphy_idx_valid(wiphy_idx)) 49 if (!wiphy_idx_valid(wiphy_idx))
51 return NULL; 50 return NULL;
52 51
52 assert_cfg80211_lock();
53
53 list_for_each_entry(drv, &cfg80211_drv_list, list) { 54 list_for_each_entry(drv, &cfg80211_drv_list, list) {
54 if (drv->wiphy_idx == wiphy_idx) { 55 if (drv->wiphy_idx == wiphy_idx) {
55 result = drv; 56 result = drv;
@@ -69,6 +70,8 @@ __cfg80211_drv_from_info(struct genl_info *info)
69 struct net_device *dev; 70 struct net_device *dev;
70 int err = -EINVAL; 71 int err = -EINVAL;
71 72
73 assert_cfg80211_lock();
74
72 if (info->attrs[NL80211_ATTR_WIPHY]) { 75 if (info->attrs[NL80211_ATTR_WIPHY]) {
73 bywiphyidx = cfg80211_drv_by_wiphy_idx( 76 bywiphyidx = cfg80211_drv_by_wiphy_idx(
74 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY])); 77 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY]));
diff --git a/net/wireless/core.h b/net/wireless/core.h
index f3ab00cbf766..982cc6be3484 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -10,6 +10,7 @@
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/kref.h> 11#include <linux/kref.h>
12#include <linux/rbtree.h> 12#include <linux/rbtree.h>
13#include <linux/mutex.h>
13#include <net/genetlink.h> 14#include <net/genetlink.h>
14#include <net/wireless.h> 15#include <net/wireless.h>
15#include <net/cfg80211.h> 16#include <net/cfg80211.h>
@@ -73,6 +74,11 @@ bool wiphy_idx_valid(int wiphy_idx)
73extern struct mutex cfg80211_mutex; 74extern struct mutex cfg80211_mutex;
74extern struct list_head cfg80211_drv_list; 75extern struct list_head cfg80211_drv_list;
75 76
77static inline void assert_cfg80211_lock(void)
78{
79 BUG_ON(!mutex_is_locked(&cfg80211_mutex));
80}
81
76struct cfg80211_internal_bss { 82struct cfg80211_internal_bss {
77 struct list_head list; 83 struct list_head list;
78 struct rb_node rbn; 84 struct rb_node rbn;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 130fc2561bac..e0d3879b8852 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7,7 +7,6 @@
7#include <linux/if.h> 7#include <linux/if.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/err.h> 9#include <linux/err.h>
10#include <linux/mutex.h>
11#include <linux/list.h> 10#include <linux/list.h>
12#include <linux/if_ether.h> 11#include <linux/if_ether.h>
13#include <linux/ieee80211.h> 12#include <linux/ieee80211.h>
@@ -138,6 +137,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
138 int i; 137 int i;
139 u16 ifmodes = dev->wiphy.interface_modes; 138 u16 ifmodes = dev->wiphy.interface_modes;
140 139
140 assert_cfg80211_lock();
141
141 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); 142 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
142 if (!hdr) 143 if (!hdr)
143 return -1; 144 return -1;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 47d505616a4b..e49ac9b2adac 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -276,6 +276,8 @@ static bool alpha2_equal(const char *alpha2_x, const char *alpha2_y)
276 276
277static bool regdom_changed(const char *alpha2) 277static bool regdom_changed(const char *alpha2)
278{ 278{
279 assert_cfg80211_lock();
280
279 if (!cfg80211_regdomain) 281 if (!cfg80211_regdomain)
280 return true; 282 return true;
281 if (alpha2_equal(cfg80211_regdomain->alpha2, alpha2)) 283 if (alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
@@ -830,6 +832,8 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
830 struct ieee80211_supported_band *sband; 832 struct ieee80211_supported_band *sband;
831 struct ieee80211_channel *chan; 833 struct ieee80211_channel *chan;
832 834
835 assert_cfg80211_lock();
836
833 sband = wiphy->bands[band]; 837 sband = wiphy->bands[band];
834 BUG_ON(chan_idx >= sband->n_channels); 838 BUG_ON(chan_idx >= sband->n_channels);
835 chan = &sband->channels[chan_idx]; 839 chan = &sband->channels[chan_idx];
@@ -1042,6 +1046,9 @@ static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
1042static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by, 1046static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
1043 const char *alpha2) 1047 const char *alpha2)
1044{ 1048{
1049
1050 assert_cfg80211_lock();
1051
1045 /* All initial requests are respected */ 1052 /* All initial requests are respected */
1046 if (!last_request) 1053 if (!last_request)
1047 return 0; 1054 return 0;
@@ -1122,6 +1129,8 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
1122 bool intersect = false; 1129 bool intersect = false;
1123 int r = 0; 1130 int r = 0;
1124 1131
1132 assert_cfg80211_lock();
1133
1125 r = ignore_request(wiphy, set_by, alpha2); 1134 r = ignore_request(wiphy, set_by, alpha2);
1126 1135
1127 if (r == REG_INTERSECT) { 1136 if (r == REG_INTERSECT) {
@@ -1217,6 +1226,8 @@ EXPORT_SYMBOL(regulatory_hint);
1217static bool reg_same_country_ie_hint(struct wiphy *wiphy, 1226static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1218 u32 country_ie_checksum) 1227 u32 country_ie_checksum)
1219{ 1228{
1229 assert_cfg80211_lock();
1230
1220 if (!last_request->wiphy) 1231 if (!last_request->wiphy)
1221 return false; 1232 return false;
1222 if (likely(last_request->wiphy != wiphy)) 1233 if (likely(last_request->wiphy != wiphy))
@@ -1583,6 +1594,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)
1583{ 1594{
1584 int r; 1595 int r;
1585 1596
1597 assert_cfg80211_lock();
1598
1586 /* Note that this doesn't update the wiphys, this is done below */ 1599 /* Note that this doesn't update the wiphys, this is done below */
1587 r = __set_regdom(rd); 1600 r = __set_regdom(rd);
1588 if (r) { 1601 if (r) {
@@ -1605,6 +1618,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)
1605/* Caller must hold cfg80211_mutex */ 1618/* Caller must hold cfg80211_mutex */
1606void reg_device_remove(struct wiphy *wiphy) 1619void reg_device_remove(struct wiphy *wiphy)
1607{ 1620{
1621 assert_cfg80211_lock();
1622
1608 kfree(wiphy->regd); 1623 kfree(wiphy->regd);
1609 if (!last_request || !last_request->wiphy) 1624 if (!last_request || !last_request->wiphy)
1610 return; 1625 return;