From a14702b8482ff79dc632434e3983c05b9b057d29 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 1 May 2026 12:38:53 +0530 Subject: [PATCH] fix(esp_wifi): Fixed some issues in esp_supplicant code --- .../esp_supplicant/src/esp_dpp.c | 124 ++++++++++++++++-- .../esp_supplicant/src/esp_eap_client.c | 35 ++++- .../esp_supplicant/src/esp_nan_usd.c | 72 ++++++---- 3 files changed, 194 insertions(+), 37 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index 2c99f691efd..c93cdebc5e0 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -37,6 +37,7 @@ static void *s_dpp_event_group = NULL; #define DPP_ROC_EVENT_HANDLED BIT0 static atomic_bool roc_in_progress; +static atomic_bool dpp_shutting_down; static struct esp_dpp_context_t s_dpp_ctx; static int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel); static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action; @@ -46,6 +47,8 @@ static void tx_status_handler(void *arg, esp_event_base_t event_base, static void roc_status_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void dpp_listen_next_channel(void *data, void *user_ctx); +static void esp_dpp_cancel_timeouts(void); + static esp_err_t dpp_api_lock(void) { if (!s_dpp_api_lock) { @@ -211,6 +214,11 @@ static esp_err_t esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t * wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash", i_bootstrap, i_bootstrap_len); own_bi = dpp_bootstrap_get_id(s_dpp_ctx.dpp_global, s_dpp_ctx.id); + if (!own_bi) { + wpa_printf(MSG_ERROR, "DPP: Failed to find responder bootstrap information"); + rc = ESP_ERR_DPP_FAILURE; + return rc; + } /* Try to find own and peer bootstrapping key matches based on the * received hash values */ if (os_memcmp(own_bi->pubkey_hash, r_bootstrap, SHA256_MAC_LEN)) { @@ -225,6 +233,15 @@ static esp_err_t esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t * s_dpp_ctx.dpp_auth = dpp_auth_req_rx(NULL, DPP_CAPAB_ENROLLEE, 0, NULL, own_bi, rx_param->channel, (const u8 *)&rx_param->action_frm->u.public_action.v, dpp_data, len); + if (!s_dpp_ctx.dpp_auth || !s_dpp_ctx.dpp_auth->resp_msg) { + wpa_printf(MSG_ERROR, "DPP: Failed to allocate authentication response"); + if (s_dpp_ctx.dpp_auth) { + dpp_auth_deinit(s_dpp_ctx.dpp_auth); + s_dpp_ctx.dpp_auth = NULL; + } + rc = ESP_ERR_DPP_FAILURE; + return rc; + } os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN); wpa_printf(MSG_INFO, "DPP: Sending authentication response chan(%d)", rx_param->channel); @@ -569,8 +586,14 @@ static void esp_dpp_rx_action(void *data, void *user_ctx) return; } + if (atomic_load(&dpp_shutting_down) || !s_dpp_ctx.dpp_init_done) { + os_free(rx_param); + return; + } + /* we don't cater other action frames except public here */ if (rx_param->action_frm->category != WLAN_ACTION_PUBLIC) { + os_free(rx_param); return; } @@ -621,7 +644,7 @@ static void dpp_listen_next_channel(void *data, void *user_ctx) esp_err_t ret = 0; wifi_roc_req_t req = {0}; - if (!s_dpp_ctx.dpp_listen_ongoing) { + if (atomic_load(&dpp_shutting_down) || !s_dpp_ctx.dpp_listen_ongoing) { return; } if (p->num_chan <= 0) { @@ -644,7 +667,9 @@ static void dpp_listen_next_channel(void *data, void *user_ctx) return; } atomic_store(&roc_in_progress, true); - os_event_group_clear_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED); + if (s_dpp_event_group) { + os_event_group_clear_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED); + } } static void esp_dpp_bootstrap_gen(void *data, void *user_ctx) @@ -652,6 +677,16 @@ static void esp_dpp_bootstrap_gen(void *data, void *user_ctx) char *command = data; const char *uri; uint32_t len; + bool success = false; + wifi_event_dpp_uri_ready_t *event = NULL; + + dpp_api_lock(); + s_dpp_ctx.bootstrap_done = false; + dpp_api_unlock(); + + if (atomic_load(&dpp_shutting_down) || !command || !s_dpp_ctx.dpp_global) { + goto out; + } s_dpp_ctx.id = dpp_bootstrap_gen(s_dpp_ctx.dpp_global, command); @@ -661,23 +696,40 @@ static void esp_dpp_bootstrap_gen(void *data, void *user_ctx) os_free(params->info); params->info = NULL; } + goto fail; } uri = dpp_bootstrap_get_uri(s_dpp_ctx.dpp_global, s_dpp_ctx.id); + if (!uri) { + goto fail; + } - wifi_event_dpp_uri_ready_t *event; len = sizeof(*event) + os_strlen(uri) + 1; event = os_malloc(len); if (!event) { - return; + goto fail; } event->uri_data_len = os_strlen(uri); os_memcpy(event->uri, uri, event->uri_data_len); event->uri[event->uri_data_len++] = '\0'; esp_event_post(WIFI_EVENT, WIFI_EVENT_DPP_URI_READY, event, len, OS_BLOCK); + success = true; + +fail: + if (!success && !atomic_load(&dpp_shutting_down)) { + wifi_event_dpp_failed_t fail_event = { + .failure_reason = ESP_ERR_DPP_FAILURE, + }; + + s_dpp_ctx.id = -1; + esp_event_post(WIFI_EVENT, WIFI_EVENT_DPP_FAILED, + &fail_event, sizeof(fail_event), OS_BLOCK); + } + +out: os_free(event); os_free(command); dpp_api_lock(); - s_dpp_ctx.bootstrap_done = true; + s_dpp_ctx.bootstrap_done = success; dpp_api_unlock(); } @@ -686,8 +738,8 @@ static int esp_dpp_deinit(void *data, void *user_ctx) struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; wpa_printf(MSG_DEBUG, "DPP: Deinitializing DPP"); - /* Cancel all registered timeouts */ - eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + atomic_store(&dpp_shutting_down, true); + esp_dpp_cancel_timeouts(); esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, &tx_status_handler); @@ -707,6 +759,7 @@ static int esp_dpp_deinit(void *data, void *user_ctx) dpp_auth_deinit(s_dpp_ctx.dpp_auth); s_dpp_ctx.dpp_auth = NULL; } + atomic_store(&roc_in_progress, false); s_dpp_ctx.dpp_init_done = false; s_dpp_ctx.bootstrap_done = false; if (s_dpp_event_group) { @@ -779,6 +832,10 @@ static void tx_status_eloop_handler(void *eloop_ctx, void *event_data) if (!evt) { return; } + if (atomic_load(&dpp_shutting_down)) { + os_free(evt); + return; + } wpa_printf(MSG_DEBUG, "Mgmt Tx Status - %d, Cookie - 0x%x", evt->status, (uint32_t)evt->context); @@ -814,6 +871,10 @@ static void tx_status_eloop_handler(void *eloop_ctx, void *event_data) static void tx_status_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + if (atomic_load(&dpp_shutting_down)) { + return; + } + wifi_event_action_tx_status_t *evt_c = os_malloc(sizeof(*evt_c)); if (evt_c) { os_memcpy(evt_c, event_data, sizeof(*evt_c)); @@ -829,6 +890,14 @@ static void roc_status_eloop_handler(void *eloop_ctx, void *event_data) { wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data; + if (atomic_load(&dpp_shutting_down)) { + if (evt) { + os_free(evt); + } + atomic_store(&roc_in_progress, false); + return; + } + if (evt) { if (evt->context == (uint32_t)s_action_rx_cb) { eloop_cancel_timeout(dpp_listen_next_channel, NULL, NULL); @@ -838,12 +907,18 @@ static void roc_status_eloop_handler(void *eloop_ctx, void *event_data) } atomic_store(&roc_in_progress, false); - os_event_group_set_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED); + if (s_dpp_event_group) { + os_event_group_set_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED); + } } static void roc_status_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + if (atomic_load(&dpp_shutting_down)) { + return; + } + wifi_event_roc_done_t *evt_c = os_malloc(sizeof(*evt_c)); if (evt_c) { os_memcpy(evt_c, event_data, sizeof(*evt_c)); @@ -1031,6 +1106,16 @@ static void dpp_listen_start(void *ctx, void *data) dpp_listen_next_channel(NULL, NULL); } +static void esp_dpp_cancel_timeouts(void) +{ + eloop_cancel_timeout(dpp_listen_next_channel, NULL, NULL); + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); + eloop_cancel_timeout(esp_dpp_auth_resp_retry, NULL, NULL); + eloop_cancel_timeout(gas_query_timeout, ELOOP_ALL_CTX, ELOOP_ALL_CTX); + eloop_cancel_timeout(dpp_listen_start, NULL, NULL); +} + esp_err_t esp_supp_dpp_start_listen(void) { int ret = dpp_api_lock(); @@ -1053,7 +1138,11 @@ esp_err_t esp_supp_dpp_start_listen(void) esp_supp_dpp_stop_listen(); /* Give ample time to set the bit, timeout is necessary when ROC is not running previously */ - os_event_group_wait_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED, 0, 0, os_task_ms_to_tick(100)); + if (!s_dpp_event_group) { + return ESP_ERR_INVALID_STATE; + } + os_event_group_wait_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED, 0, 0, + os_task_ms_to_tick(100)); wpa_printf(MSG_DEBUG, "DPP: Starting ROC"); eloop_register_timeout(0, 0, dpp_listen_start, NULL, NULL); return 0; @@ -1092,6 +1181,9 @@ static int esp_dpp_init(void *eloop_data, void *user_ctx) cfg.cb_ctx = &s_dpp_ctx; cfg.msg_ctx = &s_dpp_ctx; os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx)); + atomic_store(&dpp_shutting_down, false); + atomic_store(&roc_in_progress, false); + s_current_tx_op_id = 0; s_dpp_ctx.dpp_global = dpp_global_init(&cfg); if (!s_dpp_ctx.dpp_global) { @@ -1106,11 +1198,19 @@ static int esp_dpp_init(void *eloop_data, void *user_ctx) &roc_status_handler, NULL); s_dpp_event_group = os_event_group_create(); + if (!s_dpp_event_group) { + ret = ESP_ERR_NO_MEM; + goto init_fail; + } wpa_printf(MSG_INFO, "DPP: dpp init done"); s_dpp_ctx.dpp_init_done = true; return ESP_OK; init_fail: + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, + &tx_status_handler); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, + &roc_status_handler); if (s_dpp_ctx.dpp_global) { dpp_global_deinit(s_dpp_ctx.dpp_global); s_dpp_ctx.dpp_global = NULL; @@ -1185,7 +1285,7 @@ esp_err_t esp_supp_dpp_deinit(void) return ESP_OK; } dpp_api_unlock(); - eloop_register_timeout_blocking(esp_dpp_deinit, NULL, NULL); - return ESP_OK; + return eloop_register_timeout_blocking(esp_dpp_deinit, NULL, NULL) == 0 ? + ESP_OK : ESP_FAIL; } #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c index adfafa2fbfd..1b6004ef6f6 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -189,6 +189,25 @@ static struct wpa2_rx_param * wpa2_rxq_dequeue(void) return param; } +static bool wpa2_rxq_remove(struct wpa2_rx_param *target) +{ + struct wpa2_rx_param *param; + bool removed = false; + + DATA_MUTEX_TAKE(); + STAILQ_FOREACH(param, &s_wpa2_rxq, bqentry) { + if (param == target) { + STAILQ_REMOVE(&s_wpa2_rxq, param, wpa2_rx_param, bqentry); + STAILQ_NEXT(param, bqentry) = NULL; + removed = true; + break; + } + } + DATA_MUTEX_GIVE(); + + return removed; +} + static void wpa2_rxq_deinit(void) { struct wpa2_rx_param *param = NULL; @@ -289,6 +308,11 @@ int wpa2_post(uint32_t sig, uint32_t par) evt.sig = sig; evt.par = par; if (os_queue_send(s_wpa2_queue, &evt, os_task_ms_to_tick(10)) != TRUE) { + DATA_MUTEX_TAKE(); + if (sm->wpa2_sig_cnt[sig]) { + sm->wpa2_sig_cnt[sig]--; + } + DATA_MUTEX_GIVE(); wpa_printf(MSG_ERROR, "EAP: Q S E"); return ESP_FAIL; } @@ -484,7 +508,12 @@ static int eap_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid) memcpy(param->sa, src_addr, WPA_ADDR_LEN); wpa2_rxq_enqueue(param); - return wpa2_post(SIG_WPA2_RX, 0); + int ret = wpa2_post(SIG_WPA2_RX, 0); + if (ret != ESP_OK && wpa2_rxq_remove(param)) { + os_free(param->buf); + os_free(param); + } + return ret; } #else @@ -1167,7 +1196,7 @@ esp_err_t esp_eap_client_set_new_password(const unsigned char *new_password, int } os_memcpy(g_wpa_new_password, new_password, len); - g_wpa_password_len = len; + g_wpa_new_password_len = len; eloop_register_timeout(0, 0, config_changed_handler, NULL, NULL); return ESP_OK; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_nan_usd.c b/components/wpa_supplicant/esp_supplicant/src/esp_nan_usd.c index f4a4d941343..30d54c8a8ed 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_nan_usd.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_nan_usd.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,22 @@ static void *s_nan_usd_data_lock = NULL; #define NAN_USD_DATA_LOCK() os_mutex_lock(s_nan_usd_data_lock) #define NAN_USD_DATA_UNLOCK() os_mutex_unlock(s_nan_usd_data_lock) +static bool nan_usd_try_lock_active(struct nan_de **nan_de) +{ + if (!s_nan_usd_data_lock) { + return false; + } + + NAN_USD_DATA_LOCK(); + if (!g_nan_de) { + NAN_USD_DATA_UNLOCK(); + return false; + } + + *nan_de = g_nan_de; + return true; +} + #ifdef DEBUG_PRINT static const char *nan_reason_txt(enum nan_de_reason reason) { @@ -86,6 +102,8 @@ static int esp_nan_freq_to_chan(int freq) static void nan_de_tx_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + struct nan_de *nan_de = NULL; + if (event_id == WIFI_EVENT_ACTION_TX_STATUS) { wifi_event_action_tx_status_t *evt = (wifi_event_action_tx_status_t *)event_data; if (evt->status == WIFI_ACTION_TX_DONE) { @@ -94,12 +112,16 @@ static void nan_de_tx_event_handler(void *arg, esp_event_base_t event_base, wpa_printf(MSG_ERROR, "Invalid channel received from Action Tx handler"); return; } - NAN_USD_DATA_LOCK(); - nan_de_tx_status(g_nan_de, freq, NULL); + if (!nan_usd_try_lock_active(&nan_de)) { + return; + } + nan_de_tx_status(nan_de, freq, NULL); NAN_USD_DATA_UNLOCK(); } else if (evt->status == WIFI_ACTION_TX_DURATION_COMPLETED) { - NAN_USD_DATA_LOCK(); - nan_de_tx_wait_ended(g_nan_de); + if (!nan_usd_try_lock_active(&nan_de)) { + return; + } + nan_de_tx_wait_ended(nan_de); NAN_USD_DATA_UNLOCK(); } } else if (event_id == WIFI_EVENT_ROC_DONE) { @@ -107,9 +129,12 @@ static void nan_de_tx_event_handler(void *arg, esp_event_base_t event_base, int freq = esp_nan_chan_to_freq(evt->channel); if (freq == -1) { wpa_printf(MSG_ERROR, "Invalid channel received from ROC done handler"); + return; } - NAN_USD_DATA_LOCK(); - nan_de_listen_ended(g_nan_de, freq); + if (!nan_usd_try_lock_active(&nan_de)) { + return; + } + nan_de_listen_ended(nan_de, freq); NAN_USD_DATA_UNLOCK(); } } @@ -117,6 +142,7 @@ static void nan_de_tx_event_handler(void *arg, esp_event_base_t event_base, int esp_nan_de_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel) { struct ieee80211_hdr *rx_hdr = (struct ieee80211_hdr *)hdr; + struct nan_de *nan_de = NULL; int freq; if (len < 6) { @@ -152,8 +178,10 @@ int esp_nan_de_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t cha return ESP_FAIL; } - NAN_USD_DATA_LOCK(); - nan_de_rx_sdf(g_nan_de, rx_hdr->addr2, rx_hdr->addr3, freq, payload, len - 6); + if (!nan_usd_try_lock_active(&nan_de)) { + return ESP_FAIL; + } + nan_de_rx_sdf(nan_de, rx_hdr->addr2, rx_hdr->addr3, freq, payload, len - 6); NAN_USD_DATA_UNLOCK(); return ESP_OK; } @@ -315,6 +343,14 @@ static void esp_nan_de_receive(void *ctx, int id, int peer_instance_id, esp_err_t esp_nan_usd_deinit() { + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, &nan_de_tx_event_handler); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, &nan_de_tx_event_handler); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_STOP, + &nan_sta_stop_handler); + + if (!s_nan_usd_data_lock) { + return ESP_FAIL; + } NAN_USD_DATA_LOCK(); if (!g_nan_de) { @@ -326,16 +362,6 @@ esp_err_t esp_nan_usd_deinit() g_nan_de = NULL; NAN_USD_DATA_UNLOCK(); - if (s_nan_usd_data_lock) { - os_mutex_delete(s_nan_usd_data_lock); - s_nan_usd_data_lock = NULL; - } - - esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, &nan_de_tx_event_handler); - esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, &nan_de_tx_event_handler); - esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_STOP, - &nan_sta_stop_handler); - return ESP_OK; } @@ -360,10 +386,12 @@ esp_err_t esp_nan_usd_init(void) cb.subscribe_terminated = esp_nan_de_subscribe_terminated; cb.receive = esp_nan_de_receive; - s_nan_usd_data_lock = os_recursive_mutex_create(); if (!s_nan_usd_data_lock) { - ESP_LOGE("NAN-USD", "Failed to create NAN-USD data lock"); - return ESP_FAIL; + s_nan_usd_data_lock = os_recursive_mutex_create(); + if (!s_nan_usd_data_lock) { + ESP_LOGE("NAN-USD", "Failed to create NAN-USD data lock"); + return ESP_FAIL; + } } ESP_RETURN_ON_ERROR(esp_wifi_get_mac(WIFI_IF_STA, mac), "NAN-USD", "Fetching MAC of STA ifx failed");