diff options
author | Luciano Coelho <coelho@ti.com> | 2011-05-27 08:34:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-05-31 14:47:26 -0400 |
commit | 66870b1ccd5c1460e437c18b0026e2dcaab1ece9 (patch) | |
tree | 0067c12e2014b4e4aa58ca6204236618515b3d79 /drivers/net | |
parent | 50a66d7f04adbfab9db55144c58dc693358cb635 (diff) |
wl12xx: fix oops in sched_scan when forcing a passive scan
Fix kernel oops when trying to use passive scheduled scans. The
reason was that in passive scans there are no SSIDs, so there was a
NULL pointer dereference.
To solve the problem, we now check the number of SSIDs provided in the
sched_scan request and only access the list if there's one or more
(ie. passive scan is not forced). We also force all the channels to
be passive by adding the IEEE80211_CHAN_PASSIVE_SCAN flag locally
before the checks in the wl1271_scan_get_sched_scan_channels()
function.
Signed-off-by: Luciano Coelho <coelho@ti.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/wl12xx/scan.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 28ec0addc657..56f76abc754d 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -331,12 +331,16 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, | |||
331 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; | 331 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; |
332 | int i, j; | 332 | int i, j; |
333 | u32 flags; | 333 | u32 flags; |
334 | bool force_passive = !req->n_ssids; | ||
334 | 335 | ||
335 | for (i = 0, j = start; | 336 | for (i = 0, j = start; |
336 | i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS; | 337 | i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS; |
337 | i++) { | 338 | i++) { |
338 | flags = req->channels[i]->flags; | 339 | flags = req->channels[i]->flags; |
339 | 340 | ||
341 | if (force_passive) | ||
342 | flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
343 | |||
340 | if ((req->channels[i]->band == band) && | 344 | if ((req->channels[i]->band == band) && |
341 | !(flags & IEEE80211_CHAN_DISABLED) && | 345 | !(flags & IEEE80211_CHAN_DISABLED) && |
342 | (!!(flags & IEEE80211_CHAN_RADAR) == radar) && | 346 | (!!(flags & IEEE80211_CHAN_RADAR) == radar) && |
@@ -433,6 +437,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
433 | struct wl1271_cmd_sched_scan_config *cfg = NULL; | 437 | struct wl1271_cmd_sched_scan_config *cfg = NULL; |
434 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; | 438 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; |
435 | int i, total_channels, ret; | 439 | int i, total_channels, ret; |
440 | bool force_passive = !req->n_ssids; | ||
436 | 441 | ||
437 | wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); | 442 | wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); |
438 | 443 | ||
@@ -456,7 +461,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
456 | for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) | 461 | for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) |
457 | cfg->intervals[i] = cpu_to_le32(req->interval); | 462 | cfg->intervals[i] = cpu_to_le32(req->interval); |
458 | 463 | ||
459 | if (req->ssids[0].ssid_len && req->ssids[0].ssid) { | 464 | if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) { |
460 | cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC; | 465 | cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC; |
461 | cfg->ssid_len = req->ssids[0].ssid_len; | 466 | cfg->ssid_len = req->ssids[0].ssid_len; |
462 | memcpy(cfg->ssid, req->ssids[0].ssid, | 467 | memcpy(cfg->ssid, req->ssids[0].ssid, |
@@ -473,7 +478,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
473 | goto out; | 478 | goto out; |
474 | } | 479 | } |
475 | 480 | ||
476 | if (cfg->active[0]) { | 481 | if (!force_passive && cfg->active[0]) { |
477 | ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, | 482 | ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, |
478 | req->ssids[0].ssid_len, | 483 | req->ssids[0].ssid_len, |
479 | ies->ie[IEEE80211_BAND_2GHZ], | 484 | ies->ie[IEEE80211_BAND_2GHZ], |
@@ -485,7 +490,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
485 | } | 490 | } |
486 | } | 491 | } |
487 | 492 | ||
488 | if (cfg->active[1]) { | 493 | if (!force_passive && cfg->active[1]) { |
489 | ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, | 494 | ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid, |
490 | req->ssids[0].ssid_len, | 495 | req->ssids[0].ssid_len, |
491 | ies->ie[IEEE80211_BAND_5GHZ], | 496 | ies->ie[IEEE80211_BAND_5GHZ], |