]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP: Stop offchannel frame TX wait on DPP_STOP_LISTEN in a corner case
authorJouni Malinen <quic_jouni@quicinc.com>
Mon, 21 Feb 2022 22:24:56 +0000 (00:24 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 23 Feb 2022 22:23:11 +0000 (00:23 +0200)
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 <quic_jouni@quicinc.com>
wpa_supplicant/dpp_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index f7b638b20fecbedf21226d996a7aee223be59fe1..e21e242dd1e552ec57977617136ae927715a54c5 100644 (file)
@@ -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);
 }
index ed1faca9f00c4b165bf2808a2b0055a3401c0b0e..111aa074403cae04fe5f34e095ea0a3d61e094ea 100644 (file)
@@ -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;