From 4d83458e6b2526c51d5a4bb1dad2b15690a6885e Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Wed, 12 Feb 2025 14:21:11 +0530 Subject: [PATCH 1/4] fix(esp_wifi): Fixed memory corruption in wifi enterprise Closes https://github.com/espressif/esp-idf/issues/15370 --- .../esp_supplicant/src/esp_eap_client.c | 56 ++++++++----------- 1 file changed, 23 insertions(+), 33 deletions(-) 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 6830a16156..aedc3f1652 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c @@ -196,7 +196,7 @@ static void wpa2_rxq_deinit(void) void wpa2_task(void *pvParameters) { - ETSEvent *e; + ETSEvent e; struct eap_sm *sm = gEapSm; bool task_del = false; @@ -206,16 +206,16 @@ void wpa2_task(void *pvParameters) for (;;) { if (TRUE == os_queue_recv(s_wpa2_queue, &e, OS_BLOCK)) { - if (e->sig < SIG_WPA2_MAX) { + if (e.sig < SIG_WPA2_MAX) { DATA_MUTEX_TAKE(); - if (sm->wpa2_sig_cnt[e->sig]) { - sm->wpa2_sig_cnt[e->sig]--; + if (sm->wpa2_sig_cnt[e.sig]) { + sm->wpa2_sig_cnt[e.sig]--; } else { - wpa_printf(MSG_ERROR, "wpa2_task: invalid sig cnt, sig=%" PRId32 " cnt=%d", e->sig, sm->wpa2_sig_cnt[e->sig]); + wpa_printf(MSG_ERROR, "wpa2_task: invalid sig cnt, sig=%" PRId32 " cnt=%d", e.sig, sm->wpa2_sig_cnt[e.sig]); } DATA_MUTEX_GIVE(); } - switch (e->sig) { + switch (e.sig) { case SIG_WPA2_TASK_DEL: task_del = true; break; @@ -235,12 +235,9 @@ void wpa2_task(void *pvParameters) default: break; } - os_free(e); - } - - if (task_del) { - break; - } else { + if (task_del) { + break; + } if (s_wifi_wpa2_sync_sem) { wpa_printf(MSG_DEBUG, "EAP: wifi->EAP api completed"); os_semphr_give(s_wifi_wpa2_sync_sem); @@ -268,6 +265,7 @@ void wpa2_task(void *pvParameters) int wpa2_post(uint32_t sig, uint32_t par) { struct eap_sm *sm = gEapSm; + ETSEvent evt; if (!sm) { return ESP_FAIL; @@ -277,28 +275,20 @@ int wpa2_post(uint32_t sig, uint32_t par) if (sm->wpa2_sig_cnt[sig]) { DATA_MUTEX_GIVE(); return ESP_OK; + } + sm->wpa2_sig_cnt[sig]++; + DATA_MUTEX_GIVE(); + evt.sig = sig; + evt.par = par; + if (os_queue_send(s_wpa2_queue, &evt, os_task_ms_to_tick(10)) != TRUE) { + wpa_printf(MSG_ERROR, "EAP: Q S E"); + return ESP_FAIL; + } + if (s_wifi_wpa2_sync_sem) { + os_semphr_take(s_wifi_wpa2_sync_sem, OS_BLOCK); + wpa_printf(MSG_DEBUG, "EAP: EAP api return, sm->state(%d)", sm->finish_state); } else { - ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent)); - if (evt == NULL) { - wpa_printf(MSG_ERROR, "EAP: E N M"); - DATA_MUTEX_GIVE(); - return ESP_FAIL; - } - sm->wpa2_sig_cnt[sig]++; - DATA_MUTEX_GIVE(); - evt->sig = sig; - evt->par = par; - if (os_queue_send(s_wpa2_queue, &evt, os_task_ms_to_tick(10)) != TRUE) { - wpa_printf(MSG_ERROR, "EAP: Q S E"); - return ESP_FAIL; - } else { - if (s_wifi_wpa2_sync_sem) { - os_semphr_take(s_wifi_wpa2_sync_sem, OS_BLOCK); - wpa_printf(MSG_DEBUG, "EAP: EAP api return, sm->state(%d)", sm->finish_state); - } else { - wpa_printf(MSG_ERROR, "EAP: null wifi->EAP sync sem"); - } - } + wpa_printf(MSG_ERROR, "EAP: null wifi->EAP sync sem"); } return ESP_OK; } From e48122f4a8b2f5e78d29b5c5b36059c5e690ac89 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Wed, 12 Feb 2025 21:00:12 +0530 Subject: [PATCH 2/4] fix(esp_wifi): fixed Stack corruption in WPS processing --- .../esp_supplicant/src/esp_wps.c | 58 ++++++++----------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index dcb5321729..d3a8a2b3b2 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -119,7 +119,7 @@ static void wps_rxq_deinit(void) #ifdef USE_WPS_TASK void wps_task(void *pvParameters) { - ETSEvent *e; + ETSEvent e; wps_ioctl_param_t *param; bool del_task = false; @@ -129,32 +129,32 @@ void wps_task(void *pvParameters) for (;;) { if (TRUE == os_queue_recv(s_wps_queue, &e, OS_BLOCK)) { - if ((e->sig >= SIG_WPS_ENABLE) && (e->sig < SIG_WPS_NUM)) { + if ((e.sig >= SIG_WPS_ENABLE) && (e.sig < SIG_WPS_NUM)) { DATA_MUTEX_TAKE(); - if (s_wps_sig_cnt[e->sig]) { - s_wps_sig_cnt[e->sig]--; + if (s_wps_sig_cnt[e.sig]) { + s_wps_sig_cnt[e.sig]--; } else { - wpa_printf(MSG_ERROR, "wpsT: invalid sig cnt, sig=%" PRId32 " cnt=%d", e->sig, s_wps_sig_cnt[e->sig]); + wpa_printf(MSG_ERROR, "wpsT: invalid sig cnt, sig=%" PRId32 " cnt=%d", e.sig, s_wps_sig_cnt[e.sig]); } DATA_MUTEX_GIVE(); } - wpa_printf(MSG_DEBUG, "wpsT: rx sig=%" PRId32 "", e->sig); + wpa_printf(MSG_DEBUG, "wpsT: rx sig=%" PRId32 "", e.sig); - switch (e->sig) { + switch (e.sig) { case SIG_WPS_ENABLE: case SIG_WPS_DISABLE: case SIG_WPS_START: - param = (wps_ioctl_param_t *)e->par; + param = (wps_ioctl_param_t *)e.par; if (!param) { - wpa_printf(MSG_ERROR, "wpsT: invalid param sig=%" PRId32 "", e->sig); + wpa_printf(MSG_ERROR, "wpsT: invalid param sig=%" PRId32 "", e.sig); os_semphr_give(s_wps_api_sem); break; } - if (e->sig == SIG_WPS_ENABLE) { + if (e.sig == SIG_WPS_ENABLE) { param->ret = wifi_wps_enable_internal((esp_wps_config_t *)(param->arg)); - } else if (e->sig == SIG_WPS_DISABLE) { + } else if (e.sig == SIG_WPS_DISABLE) { DATA_MUTEX_TAKE(); param->ret = wifi_wps_disable_internal(); del_task = true; @@ -198,10 +198,9 @@ void wps_task(void *pvParameters) break; default: - wpa_printf(MSG_ERROR, "wpsT: invalid sig=%" PRId32 "", e->sig); + wpa_printf(MSG_ERROR, "wpsT: invalid sig=%" PRId32 "", e.sig); break; } - os_free(e); if (del_task) { wpa_printf(MSG_DEBUG, "wpsT: delete task"); @@ -218,39 +217,30 @@ void wps_task(void *pvParameters) int wps_post(uint32_t sig, uint32_t par) { wpa_printf(MSG_DEBUG, "wps post: sig=%" PRId32 " cnt=%d", sig, s_wps_sig_cnt[sig]); - - DATA_MUTEX_TAKE(); + ETSEvent evt; if (!s_wps_task_hdl) { wpa_printf(MSG_DEBUG, "wps post: sig=%" PRId32 " failed as wps task has been deinited", sig); - DATA_MUTEX_GIVE(); return ESP_FAIL; } + DATA_MUTEX_TAKE(); if (s_wps_sig_cnt[sig]) { wpa_printf(MSG_DEBUG, "wps post: sig=%" PRId32 " processing", sig); DATA_MUTEX_GIVE(); return ESP_OK; - } else { - ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent)); + } - if (evt == NULL) { - wpa_printf(MSG_ERROR, "WPS: E N M"); - DATA_MUTEX_GIVE(); - return ESP_FAIL; - } + s_wps_sig_cnt[sig]++; + evt.sig = sig; + evt.par = par; + DATA_MUTEX_GIVE(); - s_wps_sig_cnt[sig]++; - evt->sig = sig; - evt->par = par; + if (os_queue_send(s_wps_queue, &evt, os_task_ms_to_tick(10)) != TRUE) { + wpa_printf(MSG_ERROR, "WPS: Q S E"); + DATA_MUTEX_TAKE(); + s_wps_sig_cnt[sig]--; DATA_MUTEX_GIVE(); - - if (os_queue_send(s_wps_queue, &evt, os_task_ms_to_tick(10)) != TRUE) { - wpa_printf(MSG_ERROR, "WPS: Q S E"); - DATA_MUTEX_TAKE(); - s_wps_sig_cnt[sig]--; - DATA_MUTEX_GIVE(); - return ESP_FAIL; - } + return ESP_FAIL; } return ESP_OK; } From 534fce5fbf2db03728c6a407b0ebff5c263161d2 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Wed, 12 Feb 2025 21:22:25 +0530 Subject: [PATCH 3/4] fix(esp_wifi): fixed Stack corruption in DPP task --- .../esp_supplicant/src/esp_dpp.c | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index 9d9e168fc0..840d88a6ea 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -42,15 +42,11 @@ struct action_rx_param { esp_err_t esp_dpp_post_evt(uint32_t evt_id, uint32_t data) { - dpp_event_t *evt = os_zalloc(sizeof(dpp_event_t)); + dpp_event_t evt; esp_err_t ret = ESP_OK; - if (evt == NULL) { - ret = ESP_ERR_NO_MEM; - goto end; - } - evt->id = evt_id; - evt->data = data; + evt.id = evt_id; + evt.data = data; if (s_dpp_api_lock) { DPP_API_LOCK(); } else { @@ -69,9 +65,6 @@ esp_err_t esp_dpp_post_evt(uint32_t evt_id, uint32_t data) return ret; end: - if (evt) { - os_free(evt); - } wpa_printf(MSG_ERROR, "DPP: Failed to send event %d to DPP task", evt_id); return ret; } @@ -518,17 +511,16 @@ static esp_err_t esp_dpp_rx_action(struct action_rx_param *rx_param) static void esp_dpp_task(void *pvParameters) { - dpp_event_t *evt; + dpp_event_t evt; bool task_del = false; for (;;) { if (os_queue_recv(s_dpp_evt_queue, &evt, OS_BLOCK) == TRUE) { - if (evt->id >= SIG_DPP_MAX) { - os_free(evt); + if (evt.id >= SIG_DPP_MAX) { continue; } - switch (evt->id) { + switch (evt.id) { case SIG_DPP_DEL_TASK: struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); @@ -549,7 +541,7 @@ static void esp_dpp_task(void *pvParameters) break; case SIG_DPP_BOOTSTRAP_GEN: { - char *command = (char *)evt->data; + char *command = (char *)evt.data; const char *uri; s_dpp_ctx.id = dpp_bootstrap_gen(s_dpp_ctx.dpp_global, command); @@ -561,7 +553,7 @@ static void esp_dpp_task(void *pvParameters) break; case SIG_DPP_RX_ACTION: { - esp_dpp_rx_action((struct action_rx_param *)evt->data); + esp_dpp_rx_action((struct action_rx_param *)evt.data); } break; @@ -588,7 +580,7 @@ static void esp_dpp_task(void *pvParameters) break; case SIG_DPP_START_NET_INTRO: { - esp_dpp_start_net_intro_protocol((uint8_t*)evt->data); + esp_dpp_start_net_intro_protocol((uint8_t*)evt.data); } break; @@ -605,8 +597,6 @@ static void esp_dpp_task(void *pvParameters) break; } - os_free(evt); - if (task_del) { break; } From b5eadb56e71f0571ed2ed15f1f0e1c496872eddb Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Wed, 12 Feb 2025 23:14:53 +0530 Subject: [PATCH 4/4] fix(esp_wifi): Fix stack corruption in wpa3 task --- .../esp_supplicant/src/esp_wpa3.c | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c index 776469d2e4..7135a03f5a 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c @@ -412,38 +412,32 @@ SemaphoreHandle_t g_wpa3_hostap_auth_api_lock = NULL; int wpa3_hostap_post_evt(uint32_t evt_id, uint32_t data) { - wpa3_hostap_auth_event_t *evt = os_zalloc(sizeof(wpa3_hostap_auth_event_t)); - if (evt == NULL) { - return ESP_FAIL; - } - evt->id = evt_id; - evt->data = data; + wpa3_hostap_auth_event_t evt; + + evt.id = evt_id; + evt.data = data; if (g_wpa3_hostap_auth_api_lock) { WPA3_HOSTAP_AUTH_API_LOCK(); if (g_wpa3_hostap_evt_queue == NULL) { WPA3_HOSTAP_AUTH_API_UNLOCK(); - os_free(evt); wpa_printf(MSG_DEBUG, "hostap evt queue NULL"); return ESP_FAIL; } } else { - os_free(evt); wpa_printf(MSG_DEBUG, "g_wpa3_hostap_auth_api_lock not found"); return ESP_FAIL; } - if (evt->id == SIG_WPA3_RX_CONFIRM || evt->id == SIG_TASK_DEL) { + if (evt.id == SIG_WPA3_RX_CONFIRM || evt.id == SIG_TASK_DEL) { /* prioritising confirm for completing handshake for committed sta */ if (os_queue_send_to_front(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) { WPA3_HOSTAP_AUTH_API_UNLOCK(); wpa_printf(MSG_DEBUG, "failed to add msg to queue front"); - os_free(evt); return ESP_FAIL; } } else { if (os_queue_send(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) { WPA3_HOSTAP_AUTH_API_UNLOCK(); - os_free(evt); wpa_printf(MSG_DEBUG, "failed to send msg to queue"); return ESP_FAIL; } @@ -562,18 +556,18 @@ done: static void esp_wpa3_hostap_task(void *pvParameters) { - wpa3_hostap_auth_event_t *evt; + wpa3_hostap_auth_event_t evt; bool task_del = false; while (1) { if (os_queue_recv(g_wpa3_hostap_evt_queue, &evt, portMAX_DELAY) == pdTRUE) { - switch (evt->id) { + switch (evt.id) { case SIG_WPA3_RX_COMMIT: { - wpa3_process_rx_commit(evt); + wpa3_process_rx_commit(&evt); break; } case SIG_WPA3_RX_CONFIRM: { - wpa3_process_rx_confirm(evt); + wpa3_process_rx_confirm(&evt); break; } case SIG_TASK_DEL: @@ -582,7 +576,6 @@ static void esp_wpa3_hostap_task(void *pvParameters) default: break; } - os_free(evt); if (task_del) { break; @@ -593,10 +586,9 @@ static void esp_wpa3_hostap_task(void *pvParameters) while (items_in_queue--) { /* Free events posted to queue */ os_queue_recv(g_wpa3_hostap_evt_queue, &evt, portMAX_DELAY); - if (evt->id == SIG_WPA3_RX_CONFIRM) { - os_free((void *)evt->data); + if (evt.id == SIG_WPA3_RX_CONFIRM) { + os_free((void *)evt.data); } - os_free(evt); } os_queue_delete(g_wpa3_hostap_evt_queue); g_wpa3_hostap_evt_queue = NULL;