mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
fix(esp_wifi): Fix concurrency for flags between wpa3 and Wi-Fi task
This commit is contained in:
@@ -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 *) "",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user