83 lines
2.8 KiB
Diff
83 lines
2.8 KiB
Diff
From a8826b1848003eb84a6a287d4d71183ba2192dd6 Mon Sep 17 00:00:00 2001
|
|
From: Jouni Malinen <j@w1.fi>
|
|
Date: Sat, 17 Jan 2015 01:43:00 +0200
|
|
Subject: [PATCH] Interworking: Avoid busy loop in scan result mismatch corner
|
|
cases
|
|
|
|
It was possible for interworking_find_network_match() to find a possible
|
|
BSS match in a case where more thorough checks in
|
|
wpa_supplicant_select_bss() reject network. This itself is fine, in
|
|
general, but when combined with wpa_supplicant_fast_associate()
|
|
optimization and auto_interworking=1, this resulted in a busy loop of up
|
|
to five seconds and a possible stack overflow due to recursion in that
|
|
loop.
|
|
|
|
Fix this by limiting the Interworking wpa_supplicant_fast_associate()
|
|
call to be used only once per scan iteration, so that new scan
|
|
operations can be completed before going through the scan results again.
|
|
|
|
Signed-off-by: Jouni Malinen <j@w1.fi>
|
|
---
|
|
wpa_supplicant/interworking.c | 7 ++++++-
|
|
wpa_supplicant/scan.c | 3 +++
|
|
wpa_supplicant/wpa_supplicant_i.h | 1 +
|
|
3 files changed, 10 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
|
|
index 27c4561..f085c89 100644
|
|
--- a/wpa_supplicant/interworking.c
|
|
+++ b/wpa_supplicant/interworking.c
|
|
@@ -73,6 +73,8 @@ static int cred_prio_cmp(const struct wpa_cred *a, const struct wpa_cred *b)
|
|
|
|
static void interworking_reconnect(struct wpa_supplicant *wpa_s)
|
|
{
|
|
+ unsigned int tried;
|
|
+
|
|
if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
|
|
wpa_supplicant_cancel_sched_scan(wpa_s);
|
|
wpa_supplicant_deauthenticate(wpa_s,
|
|
@@ -80,10 +82,13 @@ static void interworking_reconnect(struct wpa_supplicant *wpa_s)
|
|
}
|
|
wpa_s->disconnected = 0;
|
|
wpa_s->reassociate = 1;
|
|
+ tried = wpa_s->interworking_fast_assoc_tried;
|
|
+ wpa_s->interworking_fast_assoc_tried = 1;
|
|
|
|
- if (wpa_supplicant_fast_associate(wpa_s) >= 0)
|
|
+ if (!tried && wpa_supplicant_fast_associate(wpa_s) >= 0)
|
|
return;
|
|
|
|
+ wpa_s->interworking_fast_assoc_tried = 0;
|
|
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
|
}
|
|
|
|
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
|
|
index cb2c8d6..86fe2ba 100644
|
|
--- a/wpa_supplicant/scan.c
|
|
+++ b/wpa_supplicant/scan.c
|
|
@@ -1002,6 +1002,9 @@ scan:
|
|
wpa_supplicant_req_scan(wpa_s, 1, 0);
|
|
} else {
|
|
wpa_s->scan_for_connection = 0;
|
|
+#ifdef CONFIG_INTERWORKING
|
|
+ wpa_s->interworking_fast_assoc_tried = 0;
|
|
+#endif /* CONFIG_INTERWORKING */
|
|
}
|
|
}
|
|
|
|
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
|
|
index e396a5d..2cb55cc 100644
|
|
--- a/wpa_supplicant/wpa_supplicant_i.h
|
|
+++ b/wpa_supplicant/wpa_supplicant_i.h
|
|
@@ -857,6 +857,7 @@ struct wpa_supplicant {
|
|
unsigned int network_select:1;
|
|
unsigned int auto_select:1;
|
|
unsigned int auto_network_select:1;
|
|
+ unsigned int interworking_fast_assoc_tried:1;
|
|
unsigned int fetch_all_anqp:1;
|
|
unsigned int fetch_osu_info:1;
|
|
unsigned int fetch_osu_waiting_scan:1;
|
|
--
|
|
1.7.9.5
|
|
|