aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorSimon Wunderlich <sw@simonwunderlich.de>2013-11-21 12:19:49 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-12-02 05:51:53 -0500
commitc56589ed1d25ae110a5b000bc1edea8f6861348f (patch)
tree32545cfb3e3e7fc512a37937a71f8445877fbc5d /net
parentce95320443c72ba43f8f9c6ceb276673cc30e2ce (diff)
cfg80211: protect beacon changing functions with wdev-lock
To avoid race conditions in functions which modify the beacon information, lock these using the wdev lock. This is especially required to avoid problems for csa handling functions which modify beacons but can not be called under rtnl lock. Reported-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/wireless/nl80211.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 703155b1aa7a..398756c226c3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3218,6 +3218,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3218 return PTR_ERR(params.acl); 3218 return PTR_ERR(params.acl);
3219 } 3219 }
3220 3220
3221 wdev_lock(wdev);
3221 err = rdev_start_ap(rdev, dev, &params); 3222 err = rdev_start_ap(rdev, dev, &params);
3222 if (!err) { 3223 if (!err) {
3223 wdev->preset_chandef = params.chandef; 3224 wdev->preset_chandef = params.chandef;
@@ -3226,6 +3227,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3226 wdev->ssid_len = params.ssid_len; 3227 wdev->ssid_len = params.ssid_len;
3227 memcpy(wdev->ssid, params.ssid, wdev->ssid_len); 3228 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
3228 } 3229 }
3230 wdev_unlock(wdev);
3229 3231
3230 kfree(params.acl); 3232 kfree(params.acl);
3231 3233
@@ -3254,7 +3256,11 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
3254 if (err) 3256 if (err)
3255 return err; 3257 return err;
3256 3258
3257 return rdev_change_beacon(rdev, dev, &params); 3259 wdev_lock(wdev);
3260 err = rdev_change_beacon(rdev, dev, &params);
3261 wdev_unlock(wdev);
3262
3263 return err;
3258} 3264}
3259 3265
3260static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) 3266static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
@@ -4460,7 +4466,9 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
4460{ 4466{
4461 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4467 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4462 struct net_device *dev = info->user_ptr[1]; 4468 struct net_device *dev = info->user_ptr[1];
4469 struct wireless_dev *wdev = dev->ieee80211_ptr;
4463 struct bss_parameters params; 4470 struct bss_parameters params;
4471 int err;
4464 4472
4465 memset(&params, 0, sizeof(params)); 4473 memset(&params, 0, sizeof(params));
4466 /* default to not changing parameters */ 4474 /* default to not changing parameters */
@@ -4526,7 +4534,11 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
4526 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4534 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4527 return -EOPNOTSUPP; 4535 return -EOPNOTSUPP;
4528 4536
4529 return rdev_change_bss(rdev, dev, &params); 4537 wdev_lock(wdev);
4538 err = rdev_change_bss(rdev, dev, &params);
4539 wdev_unlock(wdev);
4540
4541 return err;
4530} 4542}
4531 4543
4532static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { 4544static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
@@ -5791,7 +5803,11 @@ skip_beacons:
5791 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) 5803 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
5792 params.block_tx = true; 5804 params.block_tx = true;
5793 5805
5794 return rdev_channel_switch(rdev, dev, &params); 5806 wdev_lock(wdev);
5807 err = rdev_channel_switch(rdev, dev, &params);
5808 wdev_unlock(wdev);
5809
5810 return err;
5795} 5811}
5796 5812
5797static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, 5813static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,