diff options
author | Sven Neumann <s.neumann@raumfeld.com> | 2011-08-30 17:38:53 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-14 13:26:39 -0400 |
commit | eac03e381957a05f3842ceb8de987a1025966ecf (patch) | |
tree | 5dfbfa366c63e481eb92b7f61dbabdd4f82b6ad3 /net/wireless | |
parent | 56e6786e59cba2c714091ed53deffa6001a32841 (diff) |
cfg80211: hold reg_mutex when updating regulatory
The function wiphy_update_regulatory() uses the static variable
last_request and thus needs to be called with reg_mutex held.
This is the case for all users in reg.c, but the function was
exported for use by wiphy_register(), from where it is called
without the lock being held.
Fix this by making wiphy_update_regulatory() private and introducing
regulatory_update() as a wrapper that acquires and holds the lock.
Signed-off-by: Sven Neumann <s.neumann@raumfeld.com>
Cc: John W. Linville <linville@tuxdriver.com>
Cc: Luis R. Rodriguez <mcgrof@gmail.com>
Cc: Daniel Mack <daniel@zonque.org>
Cc: linux-wireless@vger.kernel.org
Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.c | 2 | ||||
-rw-r--r-- | net/wireless/core.h | 2 | ||||
-rw-r--r-- | net/wireless/reg.c | 17 | ||||
-rw-r--r-- | net/wireless/reg.h | 2 |
4 files changed, 18 insertions, 5 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index 645437cfc464..44cbebac25e0 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -582,7 +582,7 @@ int wiphy_register(struct wiphy *wiphy) | |||
582 | } | 582 | } |
583 | 583 | ||
584 | /* set up regulatory info */ | 584 | /* set up regulatory info */ |
585 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | 585 | regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE); |
586 | 586 | ||
587 | list_add_rcu(&rdev->list, &cfg80211_rdev_list); | 587 | list_add_rcu(&rdev->list, &cfg80211_rdev_list); |
588 | cfg80211_rdev_list_generation++; | 588 | cfg80211_rdev_list_generation++; |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 8672e028022f..796a4bdf8b0d 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -279,8 +279,6 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, | |||
279 | char *newname); | 279 | char *newname); |
280 | 280 | ||
281 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy); | 281 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy); |
282 | void wiphy_update_regulatory(struct wiphy *wiphy, | ||
283 | enum nl80211_reg_initiator setby); | ||
284 | 282 | ||
285 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev); | 283 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev); |
286 | void cfg80211_bss_age(struct cfg80211_registered_device *dev, | 284 | void cfg80211_bss_age(struct cfg80211_registered_device *dev, |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index a2b09c2df1bf..a1f069da79a4 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -101,6 +101,9 @@ struct reg_beacon { | |||
101 | struct ieee80211_channel chan; | 101 | struct ieee80211_channel chan; |
102 | }; | 102 | }; |
103 | 103 | ||
104 | static void wiphy_update_regulatory(struct wiphy *wiphy, | ||
105 | enum nl80211_reg_initiator initiator); | ||
106 | |||
104 | static void reg_todo(struct work_struct *work); | 107 | static void reg_todo(struct work_struct *work); |
105 | static DECLARE_WORK(reg_work, reg_todo); | 108 | static DECLARE_WORK(reg_work, reg_todo); |
106 | 109 | ||
@@ -1118,11 +1121,13 @@ static void reg_process_ht_flags(struct wiphy *wiphy) | |||
1118 | 1121 | ||
1119 | } | 1122 | } |
1120 | 1123 | ||
1121 | void wiphy_update_regulatory(struct wiphy *wiphy, | 1124 | static void wiphy_update_regulatory(struct wiphy *wiphy, |
1122 | enum nl80211_reg_initiator initiator) | 1125 | enum nl80211_reg_initiator initiator) |
1123 | { | 1126 | { |
1124 | enum ieee80211_band band; | 1127 | enum ieee80211_band band; |
1125 | 1128 | ||
1129 | assert_reg_lock(); | ||
1130 | |||
1126 | if (ignore_reg_update(wiphy, initiator)) | 1131 | if (ignore_reg_update(wiphy, initiator)) |
1127 | return; | 1132 | return; |
1128 | 1133 | ||
@@ -1137,6 +1142,14 @@ void wiphy_update_regulatory(struct wiphy *wiphy, | |||
1137 | wiphy->reg_notifier(wiphy, last_request); | 1142 | wiphy->reg_notifier(wiphy, last_request); |
1138 | } | 1143 | } |
1139 | 1144 | ||
1145 | void regulatory_update(struct wiphy *wiphy, | ||
1146 | enum nl80211_reg_initiator setby) | ||
1147 | { | ||
1148 | mutex_lock(®_mutex); | ||
1149 | wiphy_update_regulatory(wiphy, setby); | ||
1150 | mutex_unlock(®_mutex); | ||
1151 | } | ||
1152 | |||
1140 | static void handle_channel_custom(struct wiphy *wiphy, | 1153 | static void handle_channel_custom(struct wiphy *wiphy, |
1141 | enum ieee80211_band band, | 1154 | enum ieee80211_band band, |
1142 | unsigned int chan_idx, | 1155 | unsigned int chan_idx, |
diff --git a/net/wireless/reg.h b/net/wireless/reg.h index b67d1c3a2fb9..4a56799d868d 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h | |||
@@ -16,6 +16,8 @@ void regulatory_exit(void); | |||
16 | 16 | ||
17 | int set_regdom(const struct ieee80211_regdomain *rd); | 17 | int set_regdom(const struct ieee80211_regdomain *rd); |
18 | 18 | ||
19 | void regulatory_update(struct wiphy *wiphy, enum nl80211_reg_initiator setby); | ||
20 | |||
19 | /** | 21 | /** |
20 | * regulatory_hint_found_beacon - hints a beacon was found on a channel | 22 | * regulatory_hint_found_beacon - hints a beacon was found on a channel |
21 | * @wiphy: the wireless device where the beacon was found on | 23 | * @wiphy: the wireless device where the beacon was found on |