diff options
author | Johannes Berg <johannes.berg@intel.com> | 2017-01-05 04:57:14 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-19 14:18:00 -0500 |
commit | 0a28f5393689576a7667a7ef42cb79eafe16b019 (patch) | |
tree | 7f66c2f16cbcb6e14766ca8d913dfd15655a183c | |
parent | 14d6c966744debbafd2f2815e052f2fed1dd154b (diff) |
nl80211: fix sched scan netlink socket owner destruction
commit 753aacfd2e95df6a0caf23c03dc309020765bea9 upstream.
A single netlink socket might own multiple interfaces *and* a
scheduled scan request (which might belong to another interface),
so when it goes away both may need to be destroyed.
Remove the schedule_scan_stop indirection to fix this - it's only
needed for interface destruction because of the way this works
right now, with a single work taking care of all interfaces.
Fixes: 93a1e86ce10e4 ("nl80211: Stop scheduled scan if netlink client disappears")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | net/wireless/nl80211.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index a2dd6edaae37..1b3c18c2c1ec 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -14402,13 +14402,17 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
14402 | 14402 | ||
14403 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { | 14403 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { |
14404 | bool schedule_destroy_work = false; | 14404 | bool schedule_destroy_work = false; |
14405 | bool schedule_scan_stop = false; | ||
14406 | struct cfg80211_sched_scan_request *sched_scan_req = | 14405 | struct cfg80211_sched_scan_request *sched_scan_req = |
14407 | rcu_dereference(rdev->sched_scan_req); | 14406 | rcu_dereference(rdev->sched_scan_req); |
14408 | 14407 | ||
14409 | if (sched_scan_req && notify->portid && | 14408 | if (sched_scan_req && notify->portid && |
14410 | sched_scan_req->owner_nlportid == notify->portid) | 14409 | sched_scan_req->owner_nlportid == notify->portid) { |
14411 | schedule_scan_stop = true; | 14410 | sched_scan_req->owner_nlportid = 0; |
14411 | |||
14412 | if (rdev->ops->sched_scan_stop && | ||
14413 | rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) | ||
14414 | schedule_work(&rdev->sched_scan_stop_wk); | ||
14415 | } | ||
14412 | 14416 | ||
14413 | list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) { | 14417 | list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) { |
14414 | cfg80211_mlme_unregister_socket(wdev, notify->portid); | 14418 | cfg80211_mlme_unregister_socket(wdev, notify->portid); |
@@ -14439,12 +14443,6 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
14439 | spin_unlock(&rdev->destroy_list_lock); | 14443 | spin_unlock(&rdev->destroy_list_lock); |
14440 | schedule_work(&rdev->destroy_work); | 14444 | schedule_work(&rdev->destroy_work); |
14441 | } | 14445 | } |
14442 | } else if (schedule_scan_stop) { | ||
14443 | sched_scan_req->owner_nlportid = 0; | ||
14444 | |||
14445 | if (rdev->ops->sched_scan_stop && | ||
14446 | rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) | ||
14447 | schedule_work(&rdev->sched_scan_stop_wk); | ||
14448 | } | 14446 | } |
14449 | } | 14447 | } |
14450 | 14448 | ||