]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Update STA flags to the driver immediately on disconnection
authorJouni Malinen <jouni@codeaurora.org>
Wed, 18 Mar 2020 10:41:46 +0000 (12:41 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 26 Mar 2020 15:51:03 +0000 (17:51 +0200)
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 <jouni@codeaurora.org>
src/ap/ap_drv_ops.c
src/ap/drv_callbacks.c
src/ap/ieee802_11.c
src/ap/sta_info.c

index 1aa2ab038476c6a50b205f133dd912c28ba48b5a..1f284f0f38d035a5cd645e5d433269611372bf8b 100644 (file)
@@ -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);
index 98729f42355c1240fb14fc5c3b6559052fa53dfe..baf3f7c3f1a7b054648802d83159fbf3cd69fea8 100644 (file)
@@ -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);
index c0f9290f882448753be6fe4176027ac319c62e30..1f58ec87cd50a918d0f9ec01c609de2b5c87c0c0 100644 (file)
@@ -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");
index d3aa15da301a4a491e10b9d24c667c6d733abddb..903be28d46db3cc9297a071aac28dc278478575c 100644 (file)
@@ -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)",