path: root/wpa_supplicant/bss.c
diff options
authorJouni Malinen <jouni@qca.qualcomm.com>2014-10-27 22:19:24 (GMT)
committerJouni Malinen <j@w1.fi>2014-10-27 22:43:58 (GMT)
commita7f5271d52e7aabf6c6aee54da2fdcb65df89cdc (patch)
tree110b782d31becaadaebe095d14ffb1a1844ff0c9 /wpa_supplicant/bss.c
parent1531402ee4888b28f85ce6333b0f6b7740675990 (diff)
Update pending connect radio work BSS pointer on scan update
It is possible for scan result processing or BSS entry removal to occur while there is a pending connect or sme-connect radio work with a previously selected BSS entry. The BSS pointer was previously verified to be valid, i.e., still point to a BSS entry, at the time the actual connection operation is started. However, that BSS entry could have changed to point to another BSS if the old BSS entry was either removed or reallocated and a new BSS entry was added at the same location in memory. This could result in the connection attempt failing to configure parameters properly due to different BSS information (e.g., different BSSID). Fix this by updated the pending connect radio work data on BSS entry updates similarly to how the last_scan_res array was updated. If the selected BSS entry is removed, this will still result in a failed connection, but reallocated BSS entry is now followed properly and used when the connection work starts. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant/bss.c')
1 files changed, 27 insertions, 0 deletions
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 9b9289f..055aef0 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -174,6 +174,31 @@ static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp)
+static void wpa_bss_update_pending_connect(struct wpa_supplicant *wpa_s,
+ struct wpa_bss *old_bss,
+ struct wpa_bss *new_bss)
+ struct wpa_radio_work *work;
+ struct wpa_connect_work *cwork;
+ work = radio_work_pending(wpa_s, "sme-connect");
+ if (!work)
+ work = radio_work_pending(wpa_s, "connect");
+ if (!work)
+ return;
+ cwork = work->ctx;
+ if (cwork->bss != old_bss)
+ return;
+ wpa_printf(MSG_DEBUG,
+ "Update BSS pointer for the pending connect radio work");
+ cwork->bss = new_bss;
+ if (!new_bss)
+ cwork->bss_removed = 1;
static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
const char *reason)
@@ -190,6 +215,7 @@ static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ wpa_bss_update_pending_connect(wpa_s, bss, NULL);
@@ -543,6 +569,7 @@ wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
if (wpa_s->current_bss == bss)
wpa_s->current_bss = nbss;
+ wpa_bss_update_pending_connect(wpa_s, bss, nbss);
bss = nbss;
os_memcpy(bss + 1, res + 1,
res->ie_len + res->beacon_ie_len);