]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
mac80211: treat some SAE auth steps as final
authorJohannes Berg <johannes.berg@intel.com>
Thu, 24 Feb 2022 09:39:34 +0000 (10:39 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 1 Mar 2022 10:33:13 +0000 (11:33 +0100)
When we get anti-clogging token required (added by the commit
mentioned below), or the other status codes added by the later
commit 4e56cde15f7d ("mac80211: Handle special status codes in
SAE commit") we currently just pretend (towards the internal
state machine of authentication) that we didn't receive anything.

This has the undesirable consequence of retransmitting the prior
frame, which is not expected, because the timer is still armed.

If we just disarm the timer at that point, it would result in
the undesirable side effect of being in this state indefinitely
if userspace crashes, or so.

So to fix this, reset the timer and set a new auth_data->waiting
in order to have no more retransmissions, but to have the data
destroyed when the timer actually fires, which will only happen
if userspace didn't continue (i.e. crashed or abandoned it.)

Fixes: a4055e74a2ff ("mac80211: Don't destroy auth data in case of anti-clogging")
Reported-by: Jouni Malinen <j@w1.fi>
Link: https://lore.kernel.org/r/20220224103932.75964e1d7932.Ia487f91556f29daae734bf61f8181404642e1eec@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c

index 330ea62231faa215408921ea45042c94955c3a49..e87bccaab561f449e0bc9770a6ba307a4aa94ca6 100644 (file)
@@ -376,7 +376,7 @@ struct ieee80211_mgd_auth_data {
 
        u8 key[WLAN_KEY_LEN_WEP104];
        u8 key_len, key_idx;
-       bool done;
+       bool done, waiting;
        bool peer_confirmed;
        bool timeout_started;
 
index e5ccf17618ab2f9f6c6a6c1dc6d10bc58445153c..744842c4513b1f6d488b3eb5ac728e76c774ff80 100644 (file)
@@ -37,6 +37,7 @@
 #define IEEE80211_AUTH_TIMEOUT_SAE     (HZ * 2)
 #define IEEE80211_AUTH_MAX_TRIES       3
 #define IEEE80211_AUTH_WAIT_ASSOC      (HZ * 5)
+#define IEEE80211_AUTH_WAIT_SAE_RETRY  (HZ * 2)
 #define IEEE80211_ASSOC_TIMEOUT                (HZ / 5)
 #define IEEE80211_ASSOC_TIMEOUT_LONG   (HZ / 2)
 #define IEEE80211_ASSOC_TIMEOUT_SHORT  (HZ / 10)
@@ -3011,8 +3012,15 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
                    (status_code == WLAN_STATUS_ANTI_CLOG_REQUIRED ||
                     (auth_transaction == 1 &&
                      (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
-                      status_code == WLAN_STATUS_SAE_PK))))
+                      status_code == WLAN_STATUS_SAE_PK)))) {
+                       /* waiting for userspace now */
+                       ifmgd->auth_data->waiting = true;
+                       ifmgd->auth_data->timeout =
+                               jiffies + IEEE80211_AUTH_WAIT_SAE_RETRY;
+                       ifmgd->auth_data->timeout_started = true;
+                       run_again(sdata, ifmgd->auth_data->timeout);
                        goto notify_driver;
+               }
 
                sdata_info(sdata, "%pM denied authentication (status %d)\n",
                           mgmt->sa, status_code);
@@ -4603,10 +4611,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 
        if (ifmgd->auth_data && ifmgd->auth_data->timeout_started &&
            time_after(jiffies, ifmgd->auth_data->timeout)) {
-               if (ifmgd->auth_data->done) {
+               if (ifmgd->auth_data->done || ifmgd->auth_data->waiting) {
                        /*
-                        * ok ... we waited for assoc but userspace didn't,
-                        * so let's just kill the auth data
+                        * ok ... we waited for assoc or continuation but
+                        * userspace didn't do it, so kill the auth data
                         */
                        ieee80211_destroy_auth_data(sdata, false);
                } else if (ieee80211_auth(sdata)) {