提交 c56589ed 编写于 作者: S Simon Wunderlich 提交者: Johannes Berg

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: NJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: NSimon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 ce953204
...@@ -3218,6 +3218,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) ...@@ -3218,6 +3218,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
return PTR_ERR(params.acl); return PTR_ERR(params.acl);
} }
wdev_lock(wdev);
err = rdev_start_ap(rdev, dev, &params); err = rdev_start_ap(rdev, dev, &params);
if (!err) { if (!err) {
wdev->preset_chandef = params.chandef; wdev->preset_chandef = params.chandef;
...@@ -3226,6 +3227,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) ...@@ -3226,6 +3227,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
wdev->ssid_len = params.ssid_len; wdev->ssid_len = params.ssid_len;
memcpy(wdev->ssid, params.ssid, wdev->ssid_len); memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
} }
wdev_unlock(wdev);
kfree(params.acl); kfree(params.acl);
...@@ -3254,7 +3256,11 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) ...@@ -3254,7 +3256,11 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
if (err) if (err)
return err; return err;
return rdev_change_beacon(rdev, dev, &params); wdev_lock(wdev);
err = rdev_change_beacon(rdev, dev, &params);
wdev_unlock(wdev);
return err;
} }
static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) static 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,7 +4466,9 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
{ {
struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct net_device *dev = info->user_ptr[1]; struct net_device *dev = info->user_ptr[1];
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct bss_parameters params; struct bss_parameters params;
int err;
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
/* default to not changing parameters */ /* default to not changing parameters */
...@@ -4526,7 +4534,11 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) ...@@ -4526,7 +4534,11 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return rdev_change_bss(rdev, dev, &params); wdev_lock(wdev);
err = rdev_change_bss(rdev, dev, &params);
wdev_unlock(wdev);
return err;
} }
static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
...@@ -5791,7 +5803,11 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) ...@@ -5791,7 +5803,11 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
params.block_tx = true; params.block_tx = true;
return rdev_channel_switch(rdev, dev, &params); wdev_lock(wdev);
err = rdev_channel_switch(rdev, dev, &params);
wdev_unlock(wdev);
return err;
} }
static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册