]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP MLD: Clear wpa_sm entries for all STAs when freeing a wpa_sm
authorJouni Malinen <jouni.malinen@oss.qualcomm.com>
Sun, 25 Jan 2026 18:17:24 +0000 (20:17 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 25 Jan 2026 18:31:12 +0000 (20:31 +0200)
While the use of clear_wpa_sm_for_each_partner_link() is supposed to
handle this, add a more robust approach for making sure no pointers to
freed wpa_sm instances are left behind regardless of how the non-AP MLD
partner STA entries are handled in cases where the same MAC address is
used in ML and non-ML cases.

Signed-off-by: Jouni Malinen <jouni.malinen@oss.qualcomm.com>
src/ap/ieee802_11.c
src/ap/sta_info.c
src/ap/sta_info.h

index 47e5d3a5d2ca39c48fb7723dac54d44921885a1d..1988d3c8a1021daa35625e2549a3e5d3193c2b54 100644 (file)
@@ -3595,7 +3595,10 @@ static void handle_auth(struct hostapd_data *hapd,
 
                if ((!(sta->flags & WLAN_STA_MFP) ||
                     !ap_sta_is_authorized(sta)) && sta->wpa_sm) {
-                       wpa_auth_sta_deinit(sta->wpa_sm);
+                       struct wpa_state_machine *sm = sta->wpa_sm;
+
+                       clear_wpa_sm_for_all_sta(hapd, sm);
+                       wpa_auth_sta_deinit(sm);
                        sta->wpa_sm = NULL;
                        clear_wpa_sm_for_each_partner_link(hapd, sta);
                }
@@ -4927,7 +4930,10 @@ skip_wpa_ies:
 
 out:
        if (resp != WLAN_STATUS_SUCCESS || assoc_wpa_sm) {
-               wpa_auth_sta_deinit(sta->wpa_sm);
+               struct wpa_state_machine *sm = sta->wpa_sm;
+
+               clear_wpa_sm_for_all_sta(hapd, sm);
+               wpa_auth_sta_deinit(sm);
 
                /* Only keep a reference to the main wpa_sm and drop the
                 * per-link instance.
index 6d2bd5f1ca65504a97e6a44f1d9c2a1bfc4b9ef6..0fea6c4fbabd306a129e6392785419e22d25e18a 100644 (file)
@@ -247,6 +247,25 @@ void clear_wpa_sm_for_each_partner_link(struct hostapd_data *hapd,
        set_wpa_sm_for_each_partner_link(hapd, psta, NULL);
 }
 
+
+void clear_wpa_sm_for_all_sta(struct hostapd_data *hapd,
+                             struct wpa_state_machine *wpa_sm)
+{
+       struct hostapd_data *lhapd;
+
+       if (!hapd->mld)
+               return;
+
+       for_each_mld_link(lhapd, hapd) {
+               struct sta_info *sta;
+
+               for (sta = lhapd->sta_list; sta; sta = sta->next) {
+                       if (sta->wpa_sm == wpa_sm)
+                               sta->wpa_sm = NULL;
+               }
+       }
+}
+
 #endif /* CONFIG_IEEE80211BE */
 
 
index 4f41f7028dbdfcf33f118b528d597d038f0601d6..886f9129bc3698d0e0c0f4852d7265bb6675e5eb 100644 (file)
@@ -443,5 +443,7 @@ void set_wpa_sm_for_each_partner_link(struct hostapd_data *hapd,
                                      struct sta_info *psta, void *wpa_sm);
 void clear_wpa_sm_for_each_partner_link(struct hostapd_data *hapd,
                                        struct sta_info *psta);
+void clear_wpa_sm_for_all_sta(struct hostapd_data *hapd,
+                             struct wpa_state_machine *wpa_sm);
 
 #endif /* STA_INFO_H */