diff options
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r-- | net/wireless/scan.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index fe575a24c95c..7043de6221ab 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #define IEEE80211_SCAN_RESULT_EXPIRE (15 * HZ) | 19 | #define IEEE80211_SCAN_RESULT_EXPIRE (15 * HZ) |
20 | 20 | ||
21 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) | 21 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) |
22 | { | 22 | { |
23 | struct cfg80211_scan_request *request; | 23 | struct cfg80211_scan_request *request; |
24 | struct net_device *dev; | 24 | struct net_device *dev; |
@@ -26,8 +26,13 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) | |||
26 | union iwreq_data wrqu; | 26 | union iwreq_data wrqu; |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | ASSERT_RDEV_LOCK(rdev); | ||
30 | |||
29 | request = rdev->scan_req; | 31 | request = rdev->scan_req; |
30 | 32 | ||
33 | if (!request) | ||
34 | return; | ||
35 | |||
31 | dev = request->dev; | 36 | dev = request->dev; |
32 | 37 | ||
33 | /* | 38 | /* |
@@ -53,7 +58,17 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev) | |||
53 | dev_put(dev); | 58 | dev_put(dev); |
54 | 59 | ||
55 | rdev->scan_req = NULL; | 60 | rdev->scan_req = NULL; |
56 | kfree(request); | 61 | |
62 | /* | ||
63 | * OK. If this is invoked with "leak" then we can't | ||
64 | * free this ... but we've cleaned it up anyway. The | ||
65 | * driver failed to call the scan_done callback, so | ||
66 | * all bets are off, it might still be trying to use | ||
67 | * the scan request or not ... if it accesses the dev | ||
68 | * in there (it shouldn't anyway) then it may crash. | ||
69 | */ | ||
70 | if (!leak) | ||
71 | kfree(request); | ||
57 | } | 72 | } |
58 | 73 | ||
59 | void __cfg80211_scan_done(struct work_struct *wk) | 74 | void __cfg80211_scan_done(struct work_struct *wk) |
@@ -64,7 +79,7 @@ void __cfg80211_scan_done(struct work_struct *wk) | |||
64 | scan_done_wk); | 79 | scan_done_wk); |
65 | 80 | ||
66 | cfg80211_lock_rdev(rdev); | 81 | cfg80211_lock_rdev(rdev); |
67 | ___cfg80211_scan_done(rdev); | 82 | ___cfg80211_scan_done(rdev, false); |
68 | cfg80211_unlock_rdev(rdev); | 83 | cfg80211_unlock_rdev(rdev); |
69 | } | 84 | } |
70 | 85 | ||