Merge branch 'bugfix/skip_memory_reordering_wpa2_semaphr_v5.0' into 'release/v5.0'

fix(esp_wifi): fixed stack corruption in WiFi tasks (v5.0)

See merge request espressif/esp-idf!36940
This commit is contained in:
Kapil Gupta 2025-02-14 19:06:36 +08:00
commit e2a2dcd808
4 changed files with 64 additions and 103 deletions

View File

@ -105,7 +105,7 @@ static int mgmt_rx_action(u8 *frame, size_t len, u8 *sender, int8_t rssi, u8 cha
#ifdef CONFIG_SUPPLICANT_TASK
static void btm_rrm_task(void *pvParameters)
{
supplicant_event_t *evt;
supplicant_event_t evt;
bool task_del = false;
while(1) {
@ -113,15 +113,14 @@ static void btm_rrm_task(void *pvParameters)
continue;
/* event validation failed */
if (evt->id >= SIG_SUPPLICANT_MAX) {
os_free(evt);
if (evt.id >= SIG_SUPPLICANT_MAX) {
continue;
}
switch (evt->id) {
switch (evt.id) {
case SIG_SUPPLICANT_RX_ACTION:
{
struct ieee_mgmt_frame *frm = (struct ieee_mgmt_frame *)evt->data;
struct ieee_mgmt_frame *frm = (struct ieee_mgmt_frame *)evt.data;
mgmt_rx_action(frm->payload, frm->len, frm->sender, frm->rssi, frm->channel);
os_free(frm);
break;
@ -137,8 +136,6 @@ static void btm_rrm_task(void *pvParameters)
break;
}
os_free(evt);
if (task_del)
break;
}
@ -798,13 +795,9 @@ cleanup:
#ifdef CONFIG_SUPPLICANT_TASK
int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data)
{
supplicant_event_t *evt = os_zalloc(sizeof(supplicant_event_t));
if (!evt) {
wpa_printf(MSG_ERROR, "Failed to allocated memory");
return -1;
}
evt->id = evt_id;
evt->data = data;
supplicant_event_t evt;
evt.id = evt_id;
evt.data = data;
/* Make sure lock exists before taking it */
SUPPLICANT_API_LOCK();
@ -812,13 +805,11 @@ int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data)
/* Make sure no event can be sent when deletion event is sent or task not initialized */
if (!s_supplicant_task_init_done) {
SUPPLICANT_API_UNLOCK();
os_free(evt);
return -1;
}
if (os_queue_send(s_supplicant_evt_queue, &evt, os_task_ms_to_tick(10)) != TRUE) {
SUPPLICANT_API_UNLOCK();
os_free(evt);
return -1;
}
if (evt_id == SIG_SUPPLICANT_DEL_TASK) {

View File

@ -40,15 +40,11 @@ struct action_rx_param {
static int esp_dpp_post_evt(uint32_t evt_id, uint32_t data)
{
dpp_event_t *evt = os_zalloc(sizeof(dpp_event_t));
int ret = ESP_OK;
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 {
@ -67,10 +63,7 @@ static int 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);
wpa_printf(MSG_ERROR, "DPP: Failed to send event %d to DPP task", evt_id);
return ret;
}
@ -381,17 +374,16 @@ static void 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);
@ -412,7 +404,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);
@ -424,7 +416,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;
@ -462,8 +454,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

@ -131,7 +131,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;
@ -141,32 +141,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;
@ -210,10 +210,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");
@ -230,39 +229,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;
}