summaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2014-12-15 06:25:38 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-12-18 08:38:09 -0500
commit31a60ed1e95ab8afbadb65599bef12b195080a0c (patch)
tree0be2e75a0554a2c1e1c01c6708af80c7388b6e74 /net/wireless/nl80211.c
parent0f8b82456178d558f14011e06ebf9af937c4b197 (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.c19
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
6219out_free: 6223out_free:
6220 kfree(rdev->sched_scan_req); 6224 kfree(sched_scan_req);
6221out_err: 6225out_err:
6222 rdev->sched_scan_req = NULL;
6223 return err; 6226 return err;
6224} 6227}
6225 6228