diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-02-21 00:04:25 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-02-27 14:52:56 -0500 |
commit | 761cf7ecffc4bc079679e65c3b1ab107c1c1fb56 (patch) | |
tree | bd9ff2715f6f191c31368c9efc534fdc68187705 | |
parent | bcf4f99b7b1e0971b79e8df40331e77fc1744049 (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.c | 5 | ||||
-rw-r--r-- | net/wireless/core.h | 6 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 3 | ||||
-rw-r--r-- | net/wireless/reg.c | 15 |
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) | |||
73 | extern struct mutex cfg80211_mutex; | 74 | extern struct mutex cfg80211_mutex; |
74 | extern struct list_head cfg80211_drv_list; | 75 | extern struct list_head cfg80211_drv_list; |
75 | 76 | ||
77 | static inline void assert_cfg80211_lock(void) | ||
78 | { | ||
79 | BUG_ON(!mutex_is_locked(&cfg80211_mutex)); | ||
80 | } | ||
81 | |||
76 | struct cfg80211_internal_bss { | 82 | struct 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 | ||
277 | static bool regdom_changed(const char *alpha2) | 277 | static 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, | |||
1042 | static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by, | 1046 | static 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); | |||
1217 | static bool reg_same_country_ie_hint(struct wiphy *wiphy, | 1226 | static 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 */ |
1606 | void reg_device_remove(struct wiphy *wiphy) | 1619 | void 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; |