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:
parent
0f8b824561
commit
31a60ed1e9
5 changed files with 29 additions and 17 deletions
|
@ -257,7 +257,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
|
|||
|
||||
rtnl_lock();
|
||||
|
||||
request = rdev->sched_scan_req;
|
||||
request = rtnl_dereference(rdev->sched_scan_req);
|
||||
|
||||
/* we don't have sched_scan_req anymore if the scan is stopping */
|
||||
if (request) {
|
||||
|
@ -279,7 +279,8 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy)
|
|||
{
|
||||
trace_cfg80211_sched_scan_results(wiphy);
|
||||
/* ignore if we're not scanning */
|
||||
if (wiphy_to_rdev(wiphy)->sched_scan_req)
|
||||
|
||||
if (rcu_access_pointer(wiphy_to_rdev(wiphy)->sched_scan_req))
|
||||
queue_work(cfg80211_wq,
|
||||
&wiphy_to_rdev(wiphy)->sched_scan_results_wk);
|
||||
}
|
||||
|
@ -308,6 +309,7 @@ EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
|
|||
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
||||
bool driver_initiated)
|
||||
{
|
||||
struct cfg80211_sched_scan_request *sched_scan_req;
|
||||
struct net_device *dev;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
@ -315,7 +317,8 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
|||
if (!rdev->sched_scan_req)
|
||||
return -ENOENT;
|
||||
|
||||
dev = rdev->sched_scan_req->dev;
|
||||
sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
|
||||
dev = sched_scan_req->dev;
|
||||
|
||||
if (!driver_initiated) {
|
||||
int err = rdev_sched_scan_stop(rdev, dev);
|
||||
|
@ -325,8 +328,8 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
|||
|
||||
nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
|
||||
|
||||
kfree(rdev->sched_scan_req);
|
||||
rdev->sched_scan_req = NULL;
|
||||
RCU_INIT_POINTER(rdev->sched_scan_req, NULL);
|
||||
kfree_rcu(sched_scan_req, rcu_head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue