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/core.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/core.c')
-rw-r--r-- | net/wireless/core.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c index b661fcce7e3c..0743449405ca 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -867,6 +867,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev) { struct net_device *dev = wdev->netdev; + struct cfg80211_sched_scan_request *sched_scan_req; ASSERT_RTNL(); ASSERT_WDEV_LOCK(wdev); @@ -877,7 +878,8 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev, break; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: - if (rdev->sched_scan_req && dev == rdev->sched_scan_req->dev) + sched_scan_req = rtnl_dereference(rdev->sched_scan_req); + if (sched_scan_req && dev == sched_scan_req->dev) __cfg80211_stop_sched_scan(rdev, false); #ifdef CONFIG_CFG80211_WEXT @@ -956,6 +958,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, struct net_device *dev = netdev_notifier_info_to_dev(ptr); struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev; + struct cfg80211_sched_scan_request *sched_scan_req; if (!wdev) return NOTIFY_DONE; @@ -1021,8 +1024,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, ___cfg80211_scan_done(rdev, false); } - if (WARN_ON(rdev->sched_scan_req && - rdev->sched_scan_req->dev == wdev->netdev)) { + sched_scan_req = rtnl_dereference(rdev->sched_scan_req); + if (WARN_ON(sched_scan_req && + sched_scan_req->dev == wdev->netdev)) { __cfg80211_stop_sched_scan(rdev, false); } |