aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2014-10-28 00:19:24 +0200
committerLinux Build Service Account <lnxbuild@localhost>2014-11-04 08:24:50 -0700
commite7fe68e35f7263c9529f0cbecad35481d178f433 (patch)
treea5f9e2f15e14a3ac4444aca80967f0a30d6b0e7d
parent036fae13522e46eebd0d99ee35caea438f7c2333 (diff)
downloadandroid_external_wpa_supplicant_8-e7fe68e35f7263c9529f0cbecad35481d178f433.tar.gz
android_external_wpa_supplicant_8-e7fe68e35f7263c9529f0cbecad35481d178f433.tar.bz2
android_external_wpa_supplicant_8-e7fe68e35f7263c9529f0cbecad35481d178f433.zip
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. CRs-fixed: 720732 Git-commit: a7f5271d52e7aabf6c6aee54da2fdcb65df89cdc Git-repo : git://w1.fi/srv/git/hostap.git Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Change-Id: I47a03f7de74346fdd4b4286083260cc1113a84f0
-rw-r--r--wpa_supplicant/bss.c27
-rw-r--r--wpa_supplicant/sme.c3
-rw-r--r--wpa_supplicant/wpa_supplicant.c9
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h4
4 files changed, 37 insertions, 6 deletions
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index f99a8a71..d731a801 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);
dl_list_del(&bss->list);
dl_list_del(&bss->list_id);
wpa_s->num_bss--;
@@ -541,6 +567,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);
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 5188b9f2..83a1471f 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -487,7 +487,8 @@ static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit)
wpa_s->connect_work = work;
- if (!wpas_valid_bss_ssid(wpa_s, cwork->bss, cwork->ssid)) {
+ if (cwork->bss_removed ||
+ !wpas_valid_bss_ssid(wpa_s, cwork->bss, cwork->ssid)) {
wpa_dbg(wpa_s, MSG_DEBUG, "SME: BSS/SSID entry for authentication not valid anymore - drop connection attempt");
wpas_connect_work_done(wpa_s);
return;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 9aa5bea2..e31cc6b4 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1498,7 +1498,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
wpa_s->connect_work = work;
- if (!wpas_valid_bss_ssid(wpa_s, bss, ssid)) {
+ if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid)) {
wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
wpas_connect_work_done(wpa_s);
return;
@@ -3431,17 +3431,18 @@ void radio_work_done(struct wpa_radio_work *work)
}
-int radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
+struct wpa_radio_work *
+radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
{
struct wpa_radio_work *work;
struct wpa_radio *radio = wpa_s->radio;
dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
- return 1;
+ return work;
}
- return 0;
+ return NULL;
}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index ad4deca7..04e35efc 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -320,10 +320,12 @@ void radio_work_done(struct wpa_radio_work *work);
void radio_remove_works(struct wpa_supplicant *wpa_s,
const char *type, int remove_all);
void radio_work_check_next(struct wpa_supplicant *wpa_s);
-int radio_work_pending(struct wpa_supplicant *wpa_s, const char *type);
+struct wpa_radio_work *
+radio_work_pending(struct wpa_supplicant *wpa_s, const char *type);
struct wpa_connect_work {
unsigned int sme:1;
+ unsigned int bss_removed:1;
struct wpa_bss *bss;
struct wpa_ssid *ssid;
};