aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuciano Coelho <coelho@ti.com>2011-05-27 08:34:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-31 14:47:26 -0400
commit66870b1ccd5c1460e437c18b0026e2dcaab1ece9 (patch)
tree0067c12e2014b4e4aa58ca6204236618515b3d79
parent50a66d7f04adbfab9db55144c58dc693358cb635 (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>
-rw-r--r--drivers/net/wireless/wl12xx/scan.c11
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],