From b7275a8142202e730f70c2812a3e37ce763ad25c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 18 Mar 2020 12:41:46 +0200 Subject: [PATCH] Update STA flags to the driver immediately on disconnection hostapd (and wpa_supplicant in AP mode) was internally updating the STA flags on disconnection cases to remove authorization and association. However, some cases did not result in immediate update of the driver STA entry. Update all such cases to send out the update to the driver as well to reduce risk of race conditions where new frames might be accepted for TX or RX after the port authorization or association has been lost and configured keys are removed. Signed-off-by: Jouni Malinen --- src/ap/ap_drv_ops.c | 2 +- src/ap/drv_callbacks.c | 1 + src/ap/ieee802_11.c | 2 ++ src/ap/sta_info.c | 7 ++++++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 1aa2ab038..1f284f0f3 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -588,7 +588,7 @@ int hostapd_set_frag(struct hostapd_data *hapd, int frag) int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr, int total_flags, int flags_or, int flags_and) { - if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL) + if (!hapd->driver || !hapd->drv_priv || !hapd->driver->sta_set_flags) return 0; return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags, flags_or, flags_and); diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 98729f423..baf3f7c3f 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -712,6 +712,7 @@ void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr) ap_sta_set_authorized(hapd, sta, 0); sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); + hostapd_set_sta_flags(hapd, sta); wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index c0f9290f8..1f58ec87c 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -4502,6 +4502,7 @@ static void handle_disassoc(struct hostapd_data *hapd, ap_sta_set_authorized(hapd, sta, 0); sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ; sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK); + hostapd_set_sta_flags(hapd, sta); wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "disassociated"); @@ -4568,6 +4569,7 @@ static void handle_deauth(struct hostapd_data *hapd, sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ; sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK); + hostapd_set_sta_flags(hapd, sta); wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH); hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, "deauthenticated"); diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c index d3aa15da3..903be28d4 100644 --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -164,6 +164,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) /* just in case */ ap_sta_set_authorized(hapd, sta, 0); + hostapd_set_sta_flags(hapd, sta); if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP)) hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0); @@ -544,6 +545,7 @@ skip_poll: case STA_DISASSOC_FROM_CLI: ap_sta_set_authorized(hapd, sta, 0); sta->flags &= ~WLAN_STA_ASSOC; + hostapd_set_sta_flags(hapd, sta); ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); if (!sta->acct_terminate_cause) sta->acct_terminate_cause = @@ -812,6 +814,7 @@ void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta, sta->timeout_next = STA_DEAUTH; } ap_sta_set_authorized(hapd, sta, 0); + hostapd_set_sta_flags(hapd, sta); wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout " "for " MACSTR " (%d seconds - " "AP_MAX_INACTIVITY_AFTER_DISASSOC)", @@ -862,6 +865,7 @@ void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta, sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ; sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK); ap_sta_set_authorized(hapd, sta, 0); + hostapd_set_sta_flags(hapd, sta); sta->timeout_next = STA_REMOVE; wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout " "for " MACSTR " (%d seconds - " @@ -1329,9 +1333,10 @@ void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta, if (sta == NULL) return; ap_sta_set_authorized(hapd, sta, 0); + sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); + hostapd_set_sta_flags(hapd, sta); wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH); ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); - sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); wpa_printf(MSG_DEBUG, "%s: %s: reschedule ap_handle_timer timeout " "for " MACSTR " (%d seconds - " "AP_MAX_INACTIVITY_AFTER_DEAUTH)",