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>
This commit is contained in:
Jukka Rissanen 2014-12-15 13:25:38 +02:00 committed by Johannes Berg
commit 31a60ed1e9
5 changed files with 29 additions and 17 deletions

View file

@ -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;
}