]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Interworking: Avoid busy loop in scan result mismatch corner cases
authorJouni Malinen <j@w1.fi>
Fri, 16 Jan 2015 23:43:00 +0000 (01:43 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 16 Jan 2015 23:52:07 +0000 (01:52 +0200)
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
wpa_supplicant/scan.c
wpa_supplicant/wpa_supplicant_i.h

index 27c456118a5f84f419c9467c00e22575e16c3e52..f085c8906cfdcf12925a36c1eb781dbf75099ff3 100644 (file)
@@ -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);
 }
 
index cb2c8d6312d7324d72cf2bb1145b82e595726475..86fe2ba292705c630a5e8639fa66b7de6b9a8632 100644 (file)
@@ -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 */
        }
 }
 
index e396a5df692327165e498fa19957debd95ea2f21..2cb55ccb54cb32519287f6feb43858ae1f2394e9 100644 (file)
@@ -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;