From 7a7f803a90c9eb98245ca24d9a8c1db2f90d731d Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 22 Feb 2022 00:24:56 +0200 Subject: [PATCH] DPP: Stop offchannel frame TX wait on DPP_STOP_LISTEN in a corner case The offchannel frame TX wait was stopped whenever processing DPP_STOP_LISTEN in most cases. However, there was a corner case on the Responder side where this operation was skipped after PKEX was completed successful and the Authentication Request frame had not yet been received from the Initiator. While this does not normally cause any significant issue, this could result in unexpected behavior especially in test cases that run multiple DPP PKEX operations in a row since the start of a new TX operation might get delayed while waiting for the previous TX-wait to complete. This was found with the following test case sequence: dpp_reconfig_retries dpp_pkex_alloc_fail Signed-off-by: Jouni Malinen --- wpa_supplicant/dpp_supplicant.c | 6 +++++- wpa_supplicant/wpa_supplicant_i.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index f7b638b20..e21e242dd 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -1145,6 +1145,7 @@ static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src, return; } + wpa_s->dpp_pkex_wait_auth_req = false; wpa_s->dpp_gas_client = 0; wpa_s->dpp_gas_server = 0; wpa_s->dpp_auth_ok_on_ack = 0; @@ -2915,6 +2916,7 @@ wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant *wpa_s, const u8 *src, return; } + wpa_s->dpp_pkex_wait_auth_req = false; msg = wpa_s->dpp_pkex->exchange_resp; wait_time = wpa_s->max_remain_on_chan; if (wait_time > 2000) @@ -3031,6 +3033,7 @@ wpas_dpp_rx_pkex_commit_reveal_req(struct wpa_supplicant *wpa_s, const u8 *src, wpabuf_free(msg); wpas_dpp_pkex_finish(wpa_s, src, freq); + wpa_s->dpp_pkex_wait_auth_req = true; } @@ -3727,12 +3730,13 @@ int wpas_dpp_pkex_remove(struct wpa_supplicant *wpa_s, const char *id) void wpas_dpp_stop(struct wpa_supplicant *wpa_s) { - if (wpa_s->dpp_auth || wpa_s->dpp_pkex) + if (wpa_s->dpp_auth || wpa_s->dpp_pkex || wpa_s->dpp_pkex_wait_auth_req) offchannel_send_action_done(wpa_s); dpp_auth_deinit(wpa_s->dpp_auth); wpa_s->dpp_auth = NULL; dpp_pkex_free(wpa_s->dpp_pkex); wpa_s->dpp_pkex = NULL; + wpa_s->dpp_pkex_wait_auth_req = false; if (wpa_s->dpp_gas_client && wpa_s->dpp_gas_dialog_token >= 0) gas_query_stop(wpa_s->gas, wpa_s->dpp_gas_dialog_token); } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index ed1faca9f..111aa0744 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1468,6 +1468,7 @@ struct wpa_supplicant { u8 dpp_last_ssid[SSID_MAX_LEN]; size_t dpp_last_ssid_len; bool dpp_conf_backup_received; + bool dpp_pkex_wait_auth_req; #ifdef CONFIG_DPP2 struct dpp_pfs *dpp_pfs; int dpp_pfs_fallback; -- 2.47.2