]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP MLD: Avoid reusing ML wpa state machine for non-ML STA
authorRameshkumar Sundaram <quic_ramess@quicinc.com>
Thu, 3 Apr 2025 06:54:10 +0000 (12:24 +0530)
committerJouni Malinen <j@w1.fi>
Thu, 10 Apr 2025 08:55:15 +0000 (11:55 +0300)
When a STA tries to associate as an MLD initially but doesn't complete
EAPOL due to some reason and reassociates (with the same MAC address)
as a non-ML STA, EAPOL 2/4 fails during MIC verification.

This is because the wpa_state_machine(sta->wpa_sm) is created when the
STA first associates as an ML STA and sm->mld_assoc_link_id is set. Now
when the STA reassociates in non-ML mode (sends Authentication and
Association Request frames without an MLE) the previous STA instance as
well as its previously created wpa_sm will be reused and hence AP MLD's
MLD MAC address is used as AA to derive PTK.

To fix this, reset the sta->wpa_sm if a non MFP or non authorized STA
tries to reassociate.

Also since now sm object is freed directly (without ap_free_sta()),
reset valid flag and release group references for all links.

Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
src/ap/ieee802_11.c
src/ap/sta_info.c
src/ap/sta_info.h
src/ap/wpa_auth.c

index ccc82d04610b6af18cb24d30ab10025f7044abd6..7d207fcde63557900ac6d29091a886152ecefdc3 100644 (file)
@@ -3377,6 +3377,12 @@ static void handle_auth(struct hostapd_data *hapd,
        if (!sta->added_unassoc && auth_transaction == 1) {
                ap_sta_free_sta_profile(&sta->mld_info);
                os_memset(&sta->mld_info, 0, sizeof(sta->mld_info));
+               if ((!(sta->flags & WLAN_STA_MFP) ||
+                    !ap_sta_is_authorized(sta)) && sta->wpa_sm) {
+                       wpa_auth_sta_deinit(sta->wpa_sm);
+                       sta->wpa_sm = NULL;
+                       clear_wpa_sm_for_each_partner_link(hapd, sta);
+               }
 
                if (mld_sta) {
                        u8 link_id = hapd->mld_link_id;
index cfc2082b6711cde175332420df9f357ba9588376..f78820813a9c80e4a7c6bfa1e1774f64eadc44d2 100644 (file)
@@ -202,8 +202,8 @@ static void __ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 
 
 #ifdef CONFIG_IEEE80211BE
-static void clear_wpa_sm_for_each_partner_link(struct hostapd_data *hapd,
-                                              struct sta_info *psta)
+void clear_wpa_sm_for_each_partner_link(struct hostapd_data *hapd,
+                                       struct sta_info *psta)
 {
        struct sta_info *lsta;
        struct hostapd_data *lhapd;
index 1730742a9cbd9590b578f8070b89a6aa0a3bc0c0..9a8f4068a15aceee9dfc44cff14c9a3f2631ca25 100644 (file)
@@ -431,5 +431,7 @@ static inline void ap_sta_set_mld(struct sta_info *sta, bool mld)
 void ap_sta_free_sta_profile(struct mld_info *info);
 
 void hostapd_free_link_stas(struct hostapd_data *hapd);
+void clear_wpa_sm_for_each_partner_link(struct hostapd_data *hapd,
+                                       struct sta_info *psta);
 
 #endif /* STA_INFO_H */
index d337020d6cebfe09851434732ca637323c6dbf00..a27a66a07684f5d38ef26b54af41de8b68bf16e4 100644 (file)
@@ -1115,8 +1115,14 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm)
        os_free(sm->rsnxe);
        os_free(sm->rsn_selection);
 #ifdef CONFIG_IEEE80211BE
-       for_each_sm_auth(sm, link_id)
+       for_each_sm_auth(sm, link_id) {
+               struct wpa_authenticator *wpa_auth;
+
+               wpa_auth = sm->mld_links[link_id].wpa_auth;
                sm->mld_links[link_id].wpa_auth = NULL;
+               sm->mld_links[link_id].valid = false;
+               wpa_group_put(wpa_auth, wpa_auth->group);
+       }
 #endif /* CONFIG_IEEE80211BE */
        wpa_group_put(sm->wpa_auth, sm->group);
 #ifdef CONFIG_DPP2