Merge branch 'bugfix/skip_memory_reordering_wpa2_semaphr' into 'master'

fix(esp_wifi): fixed stack corruption in WiFi tasks

Closes IDFGH-14617

See merge request espressif/esp-idf!36905
This commit is contained in:
Jiang Jiang Jian 2025-02-14 14:02:12 +08:00
commit 403cc24a47
4 changed files with 67 additions and 105 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}