fix(esp_wifi): Fix concurrency for flags between wpa3 and Wi-Fi task

This commit is contained in:
Shreyas Sheth
2026-05-08 13:32:45 +05:30
parent 697239e7e3
commit d841c78cf0
6 changed files with 31 additions and 29 deletions
@@ -595,7 +595,7 @@ static void ap_free_sta_timeout(void *ctx, void *data)
HOSTAPD_STA_LIST_UNLOCK(hapd);
ap_free_sta(hapd, sta);
} else {
sta->remove_pending = true;
atomic_store(&sta->remove_pending, true);
HOSTAPD_STA_LIST_UNLOCK(hapd);
}
goto done;
@@ -650,7 +650,7 @@ bool wpa_ap_remove(u8* bssid)
HOSTAPD_STA_LIST_UNLOCK(hapd);
ap_free_sta(hapd, sta);
} else {
sta->remove_pending = true;
atomic_store(&sta->remove_pending, true);
HOSTAPD_STA_LIST_UNLOCK(hapd);
}
return true;
@@ -543,17 +543,17 @@ static void wpa3_process_rx_commit(wpa3_hostap_auth_event_t *evt)
}
if (sta->lock && os_semphr_take(sta->lock, 0)) {
atomic_store(&sta->sae_commit_processing, true);
HOSTAPD_STA_LIST_UNLOCK(hapd);
sta->sae_commit_processing = true;
ret = handle_auth_sae(hapd, sta, frm->msg, frm->len, frm->bssid, frm->auth_transaction, frm->status);
if (sta->remove_pending) {
if (atomic_load(&sta->remove_pending)) {
ap_free_sta(hapd, sta);
os_free(frm);
return;
}
sta->sae_commit_processing = false;
atomic_store(&sta->sae_commit_processing, false);
os_semphr_give(sta->lock);
uint16_t aid = 0;
if (ret != WLAN_STATUS_SUCCESS &&
@@ -613,7 +613,7 @@ static void wpa3_process_rx_confirm(wpa3_hostap_auth_event_t *evt)
ret = handle_auth_sae(hapd, sta, frm->msg, frm->len, frm->bssid, frm->auth_transaction, frm->status);
if (sta->remove_pending) {
if (atomic_load(&sta->remove_pending)) {
ap_free_sta(hapd, sta);
goto done;
}
@@ -782,7 +782,7 @@ static int wpa3_hostap_handle_auth(u8 *buf, size_t len, u32 auth_transaction, u1
if (auth_transaction == SAE_MSG_COMMIT) {
HOSTAPD_STA_LIST_LOCK(hapd);
struct sta_info *sta = ap_get_sta_internal(hapd, bssid);
if (sta && sta->sae_commit_processing) {
if (sta && atomic_load(&sta->sae_commit_processing)) {
HOSTAPD_STA_LIST_UNLOCK(hapd);
return ESP_OK;
}
@@ -159,7 +159,7 @@ static int auth_sae_send_commit(struct hostapd_data *hapd,
}
#ifdef ESP_SUPPLICANT
if (sta->remove_pending) {
if (atomic_load(&sta->remove_pending)) {
reply_res = -1;
} else {
reply_res = esp_send_sae_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 1,
@@ -185,7 +185,7 @@ static int auth_sae_send_confirm(struct hostapd_data *hapd,
}
#ifdef ESP_SUPPLICANT
if (sta->remove_pending) {
if (atomic_load(&sta->remove_pending)) {
reply_res = -1;
wpabuf_free(data);
} else {
@@ -265,7 +265,7 @@ void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
sta->flags |= WLAN_STA_AUTH;
#ifdef ESP_SUPPLICANT
sta->sae_commit_processing = false;
atomic_store(&sta->sae_commit_processing, false);
#endif /* ESP_SUPPLICANT */
sta->auth_alg = WLAN_AUTH_SAE;
@@ -613,7 +613,7 @@ int handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ;
#ifdef ESP_SUPPLICANT
sta->sae_commit_processing = false;
atomic_store(&sta->sae_commit_processing, false);
#endif /* ESP_SUPPLICANT */
goto reply;
@@ -682,7 +682,7 @@ reply:
data = wpabuf_alloc_copy(pos, 2);
}
#ifdef ESP_SUPPLICANT
if (!sta->remove_pending) {
if (!atomic_load(&sta->remove_pending)) {
esp_send_sae_auth_reply(hapd, bssid, bssid, WLAN_AUTH_SAE,
auth_transaction, resp,
data ? wpabuf_head(data) : (u8 *) "",
+2 -2
View File
@@ -239,8 +239,8 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
/* initialize STA info data */
os_memcpy(sta->addr, addr, ETH_ALEN);
#ifdef CONFIG_SAE
sta->sae_commit_processing = false;
sta->remove_pending = false;
atomic_init(&sta->sae_commit_processing, false);
atomic_init(&sta->remove_pending, false);
sta->lock = os_semphr_create(1, 1);
if (!sta->lock) {
wpa_printf(MSG_ERROR, "Failed to create sta->lock for " MACSTR,
+6 -2
View File
@@ -9,6 +9,10 @@
#ifndef STA_INFO_H
#define STA_INFO_H
#ifdef CONFIG_SAE
#include <stdatomic.h>
#endif
/* STA flags */
#define WLAN_STA_AUTH BIT(0)
#define WLAN_STA_ASSOC BIT(1)
@@ -62,9 +66,9 @@ struct sta_info {
#ifdef CONFIG_SAE
void *lock;
struct sae_data *sae;
volatile bool sae_commit_processing; /* halt queuing commit while we are
atomic_bool sae_commit_processing; /* halt queuing commit while we are
* processing commit for that station */
volatile bool remove_pending; /* Flag to indicate to free station when
atomic_bool remove_pending; /* Flag to indicate to free station when
* whose mutex is taken by task */
struct wpabuf *sae_data;
#endif /* CONFIG_SAE */
+11 -13
View File
@@ -137,12 +137,9 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
}
#if defined(CONFIG_SAE) || defined(CONFIG_OWE_SOFTAP)
/* wpa_auth_get_psk runs on the Wi-Fi task only, so these static buffers are safe */
#ifdef CONFIG_SAE
/* wpa_auth_get_psk runs on the Wi-Fi task only, so sae_pmk_copy is not shared with any other task. */
static u8 sae_pmk_copy[PMK_LEN];
#endif
#ifdef CONFIG_OWE_SOFTAP
static u8 owe_pmk_copy[PMK_LEN_MAX];
#endif
HOSTAPD_STA_LIST_LOCK(hapd);
struct sta_info *sta = ap_get_sta_internal(hapd, addr);
@@ -168,10 +165,8 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
#ifdef CONFIG_OWE_SOFTAP
if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
sta && sta->owe_pmk) {
size_t len = sta->owe_pmk_len > PMK_LEN_MAX ? PMK_LEN_MAX : sta->owe_pmk_len;
os_memcpy(owe_pmk_copy, sta->owe_pmk, len);
HOSTAPD_STA_LIST_UNLOCK(hapd);
return owe_pmk_copy;
return sta->owe_pmk;
}
if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) && sta) {
@@ -179,15 +174,12 @@ static inline const u8 * wpa_auth_get_psk(struct wpa_authenticator *wpa_auth,
sa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
if (sa && sa->akmp == WPA_KEY_MGMT_OWE) {
size_t len = sa->pmk_len > PMK_LEN_MAX ? PMK_LEN_MAX : sa->pmk_len;
os_memcpy(owe_pmk_copy, sa->pmk, len);
HOSTAPD_STA_LIST_UNLOCK(hapd);
return owe_pmk_copy;
return sa->pmk;
}
}
#endif /* CONFIG_OWE_SOFTAP */
HOSTAPD_STA_LIST_UNLOCK(hapd);
#endif /* defined(CONFIG_SAE) || defined(CONFIG_OWE_SOFTAP) */
@@ -358,8 +350,14 @@ int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth,
if (sta_lk) {
HOSTAPD_STA_LIST_LOCK(hapd);
sta = ap_get_sta_internal(hapd, sta_mac);
if (sta && sta->lock == sta_lk)
if (sta && sta->lock == sta_lk) {
os_semphr_give(sta_lk);
} else if (!sta) {
wpa_printf(MSG_DEBUG,
"WPA: sta->lock not released (STA " MACSTR
" gone); ap_free_sta released semaphore",
MAC2STR(sta_mac));
}
HOSTAPD_STA_LIST_UNLOCK(hapd);
sta_lk = NULL;
}