From edb28006c4d199918d50a08f8c592bd184c22624 Mon Sep 17 00:00:00 2001 From: Ashok Kumar Date: Fri, 12 Oct 2018 09:36:05 +0530 Subject: [PATCH] PMF: Do not start SA Query procedure if there is no association Previous implementation ended up triggering PMF check for previous association and SA Query procedure incorrectly in cases where there is a STA entry in hostapd, but that STA is not in associated state. This resulted in undesired temporary rejection of the association with status code 30. This ended up breaking OWE group negotiation when PMF is in use since the check for the OWE group would have happened only after this earlier PMF check and rejection (i.e., the station got status code 30 instead of the expected 77). For example, when the AP is configured with OWE group 21 and a station tries groups 19, 20, and 21 (in this sequence), the first two Association Request frames should be rejected with status code 77. However, only the first one got that status code while the second one got status code 30 due to that issue with PMF existing association check. Furthermore, hostapd was continuing with SA Query procedure with unencrypted Action frames in this type of case even though there was no existing association (and obviously, not an encryption key either). Fix this by checking that the STA entry is in associated state before initiating SA Query procedure based on the PMF rules. Signed-off-by: Ashok Kumar --- src/ap/drv_callbacks.c | 8 ++++++-- src/ap/ieee802_11.c | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 98a2eecc7..1135aea33 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -338,10 +338,14 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, goto fail; } #ifdef CONFIG_IEEE80211W - if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && + if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) == + (WLAN_STA_ASSOC | WLAN_STA_MFP) && + !sta->sa_query_timed_out && sta->sa_query_count > 0) ap_check_sa_query_timeout(hapd, sta); - if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && + if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) == + (WLAN_STA_ASSOC | WLAN_STA_MFP) && + !sta->sa_query_timed_out && (sta->auth_alg != WLAN_AUTH_FT)) { /* * STA has already been associated with MFP and SA diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 68592d6af..d2d6b1767 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2585,10 +2585,14 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, if (resp != WLAN_STATUS_SUCCESS) return resp; #ifdef CONFIG_IEEE80211W - if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && + if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) == + (WLAN_STA_ASSOC | WLAN_STA_MFP) && + !sta->sa_query_timed_out && sta->sa_query_count > 0) ap_check_sa_query_timeout(hapd, sta); - if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && + if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) == + (WLAN_STA_ASSOC | WLAN_STA_MFP) && + !sta->sa_query_timed_out && (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) { /* * STA has already been associated with MFP and SA