Skip to content

Commit

Permalink
Merge branch 'bugfix/wpa3_ap_ci_crash_v5.1' into 'release/v5.1'
Browse files Browse the repository at this point in the history
fix(esp_wifi): Fix crash when assoc req comes before confirm is processed

See merge request espressif/esp-idf!29950
  • Loading branch information
jack0c committed Apr 7, 2024
2 parents 368b7eb + a64d8b1 commit 46d402d
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 52 deletions.
39 changes: 21 additions & 18 deletions components/wpa_supplicant/esp_supplicant/src/esp_hostap.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -59,10 +59,7 @@ void *hostap_init(void)
auth_conf = (struct wpa_auth_config *)os_zalloc(sizeof(struct wpa_auth_config));

if (auth_conf == NULL) {
os_free(hapd->conf);
os_free(hapd);
hapd = NULL;
return NULL;
goto fail;
}

hapd->conf->sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_AP);
Expand Down Expand Up @@ -145,23 +142,14 @@ void *hostap_init(void)
hapd->conf->wpa_key_mgmt = auth_conf->wpa_key_mgmt;
hapd->conf->ssid.wpa_passphrase = (char *)os_zalloc(WIFI_PASSWORD_LEN_MAX);
if (hapd->conf->ssid.wpa_passphrase == NULL) {
os_free(auth_conf);
os_free(hapd->conf);
os_free(hapd);
hapd = NULL;
return NULL;
goto fail;
}

#ifdef CONFIG_SAE
if (authmode == WIFI_AUTH_WPA3_PSK ||
authmode == WIFI_AUTH_WPA2_WPA3_PSK) {
if (wpa3_hostap_auth_init(hapd) != 0) {
os_free(hapd->conf->ssid.wpa_passphrase);
os_free(auth_conf);
os_free(hapd->conf);
os_free(hapd);
hapd = NULL;
return NULL;
goto fail;
}
}
#endif /* CONFIG_SAE */
Expand All @@ -176,11 +164,26 @@ void *hostap_init(void)
esp_wifi_get_macaddr_internal(WIFI_IF_AP, hapd->own_addr);

hapd->wpa_auth = wpa_init(hapd->own_addr, auth_conf, NULL);
if (hapd->wpa_auth == NULL) {
goto fail;
}

esp_wifi_set_appie_internal(WIFI_APPIE_WPA, hapd->wpa_auth->wpa_ie, (uint16_t)hapd->wpa_auth->wpa_ie_len, 0);
os_free(auth_conf);
global_hapd = hapd;

return (void *)hapd;
fail:
if (hapd->conf->ssid.wpa_passphrase != NULL) {
os_free(hapd->conf->ssid.wpa_passphrase);
}
if (auth_conf != NULL) {
os_free(auth_conf);
}
os_free(hapd->conf);
os_free(hapd);
hapd = NULL;
return NULL;
}

void hostapd_cleanup(struct hostapd_data *hapd)
Expand Down Expand Up @@ -278,8 +281,8 @@ int esp_wifi_build_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
return pos - eid;
}

u16 esp_send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *addr, u16 status_code, bool omit_rsnxe, int subtype)
u16 esp_send_assoc_resp(struct hostapd_data *hapd, const u8 *addr,
u16 status_code, bool omit_rsnxe, int subtype)
{
#define ASSOC_RESP_LENGTH 20
u8 buf[ASSOC_RESP_LENGTH];
Expand Down
7 changes: 3 additions & 4 deletions components/wpa_supplicant/esp_supplicant/src/esp_hostap.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -15,9 +15,8 @@ extern "C" {
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
void *hostap_init(void);
bool hostap_deinit(void *data);
u16 esp_send_assoc_resp(struct hostapd_data *data, struct sta_info *sta,
const u8 *addr, u16 status_code, bool omit_rsnxe,
int subtype);
u16 esp_send_assoc_resp(struct hostapd_data *data, const u8 *addr,
u16 status_code, bool omit_rsnxe, int subtype);
#endif

#ifdef __cplusplus
Expand Down
6 changes: 1 addition & 5 deletions components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -415,10 +415,6 @@ static void wpa3_process_rx_commit(wpa3_hostap_auth_event_t *evt)
}
}

if (!sta->lock) {
sta->lock = os_semphr_create(1, 1);
}

if (sta->lock && os_semphr_take(sta->lock, 0)) {
sta->sae_commit_processing = true;
ret = handle_auth_sae(hapd, sta, frm->msg, frm->len, frm->bssid, frm->auth_transaction, frm->status);
Expand Down
67 changes: 45 additions & 22 deletions components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -295,7 +295,7 @@ static int check_n_add_wps_sta(struct hostapd_data *hapd, struct sta_info *sta_i

if (sta_info->eapol_sm) {
wpa_printf(MSG_DEBUG, "considering station " MACSTR " for WPS", MAC2STR(sta_info->addr));
if (esp_send_assoc_resp(hapd, sta_info, sta_info->addr, WLAN_STATUS_SUCCESS, true, subtype) != WLAN_STATUS_SUCCESS) {
if (esp_send_assoc_resp(hapd, sta_info->addr, WLAN_STATUS_SUCCESS, true, subtype) != WLAN_STATUS_SUCCESS) {
wpa_printf(MSG_ERROR, "failed to send assoc response " MACSTR, MAC2STR(sta_info->addr));
return -1;
}
Expand All @@ -314,52 +314,75 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len,u8
goto fail;
}

if (*sta && !esp_wifi_ap_is_sta_sae_reauth_node(bssid)) {
ap_free_sta(hapd, *sta);
if (*sta) {
struct sta_info *old_sta = *sta;
#ifdef CONFIG_SAE
if (old_sta->lock && os_semphr_take(old_sta->lock, 0) != TRUE) {
wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid));
if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) {
goto fail;
}
return false;
}
if (!esp_wifi_ap_is_sta_sae_reauth_node(bssid)) {
ap_free_sta(hapd, old_sta);
} else if (old_sta && old_sta->lock) {
sta_info = old_sta;
goto process_old_sta;
}
#endif /* CONFIG_SAE */
}

sta_info = ap_sta_add(hapd, bssid);
sta_info = ap_get_sta(hapd, bssid);
if (!sta_info) {
wpa_printf(MSG_ERROR, "failed to add station " MACSTR, MAC2STR(bssid));
goto fail;
sta_info = ap_sta_add(hapd,bssid);
if (!sta_info) {
wpa_printf(MSG_ERROR, "failed to add station " MACSTR, MAC2STR(bssid));
goto fail;
}
}

#ifdef CONFIG_SAE
if (sta_info->lock && os_semphr_take(sta_info->lock, 0) != TRUE) {
wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid));
if (esp_send_assoc_resp(hapd, sta_info, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) {
if (esp_send_assoc_resp(hapd, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) {
goto fail;
}
return false;
}
#endif /* CONFIG_SAE */

process_old_sta:

#ifdef CONFIG_WPS_REGISTRAR
if (check_n_add_wps_sta(hapd, sta_info, wpa_ie, wpa_ie_len, pmf_enable, subtype) == 0) {
if (sta_info->eapol_sm) {
*sta = sta_info;
#ifdef CONFIG_SAE
if (sta_info->lock) {
os_semphr_give(sta_info->lock);
}
#endif /* CONFIG_SAE */
return true;
goto done;
}
} else {
goto fail;
}
#endif
if (wpa_ap_join(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype)) {
*sta = sta_info;
goto done;
} else {
goto fail;
}
done:
*sta = sta_info;
#ifdef CONFIG_SAE
if (sta_info->lock) {
os_semphr_give(sta_info->lock);
}
#endif /* CONFIG_SAE */
return true;
if (sta_info->lock) {
os_semphr_give(sta_info->lock);
}
#endif /* CONFIG_SAE */
return true;

fail:

#ifdef CONFIG_SAE
if (sta_info && sta_info->lock) {
os_semphr_give(sta_info->lock);
}
#endif /* CONFIG_SAE */
esp_wifi_ap_deauth_internal(bssid, WLAN_REASON_PREV_AUTH_NOT_VALID);
return false;
}
Expand Down
1 change: 1 addition & 0 deletions components/wpa_supplicant/src/ap/sta_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
#ifdef CONFIG_SAE
sta->sae_commit_processing = false;
sta->remove_pending = false;
sta->lock = os_semphr_create(1, 1);
#endif /* CONFIG_SAE */

return sta;
Expand Down
4 changes: 2 additions & 2 deletions components/wpa_supplicant/src/ap/wpa_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *s
* strong random numbers. Reject the first 4-way
* handshake(s) and collect some entropy based on the
* information from it. Once enough entropy is
* available, the next atempt will trigger GMK/Key
* available, the next attempt will trigger GMK/Key
* Counter update and the station will be allowed to
* continue.
*/
Expand Down Expand Up @@ -2601,7 +2601,7 @@ bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie,
omit_rsnxe = true;
}

if (esp_send_assoc_resp(hapd, sta, bssid, resp, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) {
if (esp_send_assoc_resp(hapd, bssid, resp, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) {
resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
}

Expand Down

0 comments on commit 46d402d

Please sign in to comment.