cfg80211: don't "leak" uncompleted scans
authorEliad Peller <eliad@wizery.com>
Thu, 5 Dec 2013 16:30:17 +0000 (18:30 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 5 Dec 2013 18:06:47 +0000 (19:06 +0100)
commit4a58e7c38443154fce1b47910e1a9184f65c5d72
tree312b02efaf0de0522cca0eebfac2b5b861430d68
parenta2b70e833e189a4aefb2d3b668e3d7046dcc45c2
cfg80211: don't "leak" uncompleted scans

___cfg80211_scan_done() can be called in some cases
(e.g. on NETDEV_DOWN) before the low level driver
notified scan completion (which is indicated by
passing leak=true).

Clearing rdev->scan_req in this case is buggy, as
scan_done_wk might have already being queued/running
(and can't be flushed as it takes rtnl()).

If a new scan will be requested at this stage, the
scan_done_wk will try freeing it (instead of the
previous scan), and this will later result in
a use after free.

Simply remove the "leak" option, and replace it with
a standard WARN_ON.

An example backtrace after such crash:
Unable to handle kernel paging request at virtual address fffffee5
pgd = c0004000
[fffffee5] *pgd=9fdf6821, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1] SMP ARM
PC is at cfg80211_scan_done+0x28/0xc4 [cfg80211]
LR is at __ieee80211_scan_completed+0xe4/0x2dc [mac80211]
[<bf0077b0>] (cfg80211_scan_done+0x28/0xc4 [cfg80211])
[<bf0973d4>] (__ieee80211_scan_completed+0xe4/0x2dc [mac80211])
[<bf0982cc>] (ieee80211_scan_work+0x94/0x4f0 [mac80211])
[<c005fd10>] (process_one_work+0x1b0/0x4a8)
[<c0060404>] (worker_thread+0x138/0x37c)
[<c0066d70>] (kthread+0xa4/0xb0)

Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/core.c
net/wireless/core.h
net/wireless/scan.c