diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2014-12-15 14:25:38 +0300 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-12-18 16:38:09 +0300 |
commit | 31a60ed1e95ab8afbadb65599bef12b195080a0c (patch) | |
tree | 0be2e75a0554a2c1e1c01c6708af80c7388b6e74 /net/wireless/nl80211.c | |
parent | 0f8b82456178d558f14011e06ebf9af937c4b197 (diff) | |
download | linux-31a60ed1e95ab8afbadb65599bef12b195080a0c.tar.xz |
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, struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_sched_scan_request *sched_scan_req; int err; if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || @@ -6199,27 +6200,29 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, if (rdev->sched_scan_req) return -EINPROGRESS; - rdev->sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev, - info->attrs); - err = PTR_ERR_OR_ZERO(rdev->sched_scan_req); + sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev, + info->attrs); + + err = PTR_ERR_OR_ZERO(sched_scan_req); if (err) goto out_err; - err = rdev_sched_scan_start(rdev, dev, rdev->sched_scan_req); + err = rdev_sched_scan_start(rdev, dev, sched_scan_req); if (err) goto out_free; - rdev->sched_scan_req->dev = dev; - rdev->sched_scan_req->wiphy = &rdev->wiphy; + sched_scan_req->dev = dev; + sched_scan_req->wiphy = &rdev->wiphy; + + rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req); nl80211_send_sched_scan(rdev, dev, NL80211_CMD_START_SCHED_SCAN); return 0; out_free: - kfree(rdev->sched_scan_req); + kfree(sched_scan_req); out_err: - rdev->sched_scan_req = NULL; return err; } |