diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2014-12-15 06:25:38 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-12-18 08:38:09 -0500 |
commit | 31a60ed1e95ab8afbadb65599bef12b195080a0c (patch) | |
tree | 0be2e75a0554a2c1e1c01c6708af80c7388b6e74 /net/wireless/nl80211.c | |
parent | 0f8b82456178d558f14011e06ebf9af937c4b197 (diff) |
nl80211: Convert sched_scan_req pointer to RCU pointer
Because of possible races when accessing sched_scan_req pointer in
rdev, the sched_scan_req is converted to RCU pointer.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5b1907f4c181..bacdf22fa472 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -6190,6 +6190,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
6190 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6190 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6191 | struct net_device *dev = info->user_ptr[1]; | 6191 | struct net_device *dev = info->user_ptr[1]; |
6192 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 6192 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
6193 | struct cfg80211_sched_scan_request *sched_scan_req; | ||
6193 | int err; | 6194 | int err; |
6194 | 6195 | ||
6195 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || | 6196 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || |
@@ -6199,27 +6200,29 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
6199 | if (rdev->sched_scan_req) | 6200 | if (rdev->sched_scan_req) |
6200 | return -EINPROGRESS; | 6201 | return -EINPROGRESS; |
6201 | 6202 | ||
6202 | rdev->sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev, | 6203 | sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev, |
6203 | info->attrs); | 6204 | info->attrs); |
6204 | err = PTR_ERR_OR_ZERO(rdev->sched_scan_req); | 6205 | |
6206 | err = PTR_ERR_OR_ZERO(sched_scan_req); | ||
6205 | if (err) | 6207 | if (err) |
6206 | goto out_err; | 6208 | goto out_err; |
6207 | 6209 | ||
6208 | err = rdev_sched_scan_start(rdev, dev, rdev->sched_scan_req); | 6210 | err = rdev_sched_scan_start(rdev, dev, sched_scan_req); |
6209 | if (err) | 6211 | if (err) |
6210 | goto out_free; | 6212 | goto out_free; |
6211 | 6213 | ||
6212 | rdev->sched_scan_req->dev = dev; | 6214 | sched_scan_req->dev = dev; |
6213 | rdev->sched_scan_req->wiphy = &rdev->wiphy; | 6215 | sched_scan_req->wiphy = &rdev->wiphy; |
6216 | |||
6217 | rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req); | ||
6214 | 6218 | ||
6215 | nl80211_send_sched_scan(rdev, dev, | 6219 | nl80211_send_sched_scan(rdev, dev, |
6216 | NL80211_CMD_START_SCHED_SCAN); | 6220 | NL80211_CMD_START_SCHED_SCAN); |
6217 | return 0; | 6221 | return 0; |
6218 | 6222 | ||
6219 | out_free: | 6223 | out_free: |
6220 | kfree(rdev->sched_scan_req); | 6224 | kfree(sched_scan_req); |
6221 | out_err: | 6225 | out_err: |
6222 | rdev->sched_scan_req = NULL; | ||
6223 | return err; | 6226 | return err; |
6224 | } | 6227 | } |
6225 | 6228 | ||