| From a797fbcfd2b51f89e56317871969f1f8c1abd3fb Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 9 Jun 2025 21:35:27 +0300 |
| Subject: wifi: mac80211: don't complete management TX on SAE commit |
| |
| From: Johannes Berg <johannes.berg@intel.com> |
| |
| [ Upstream commit 6b04716cdcac37bdbacde34def08bc6fdb5fc4e2 ] |
| |
| When SAE commit is sent and received in response, there's no |
| ordering for the SAE confirm messages. As such, don't call |
| drivers to stop listening on the channel when the confirm |
| message is still expected. |
| |
| This fixes an issue if the local confirm is transmitted later |
| than the AP's confirm, for iwlwifi (and possibly mt76) the |
| AP's confirm would then get lost since the device isn't on |
| the channel at the time the AP transmit the confirm. |
| |
| For iwlwifi at least, this also improves the overall timing |
| of the authentication handshake (by about 15ms according to |
| the report), likely since the session protection won't be |
| aborted and rescheduled. |
| |
| Note that even before this, mgd_complete_tx() wasn't always |
| called for each call to mgd_prepare_tx() (e.g. in the case |
| of WEP key shared authentication), and the current drivers |
| that have the complete callback don't seem to mind. Document |
| this as well though. |
| |
| Reported-by: Jan Hendrik Farr <kernel@jfarr.cc> |
| Closes: https://lore.kernel.org/all/aB30Ea2kRG24LINR@archlinux/ |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> |
| Link: https://patch.msgid.link/20250609213232.12691580e140.I3f1d3127acabcd58348a110ab11044213cf147d3@changeid |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/net/mac80211.h | 2 ++ |
| net/mac80211/mlme.c | 9 ++++++++- |
| 2 files changed, 10 insertions(+), 1 deletion(-) |
| |
| diff --git a/include/net/mac80211.h b/include/net/mac80211.h |
| index 6ef8348b5e93..28a9b9c00e6b 100644 |
| --- a/include/net/mac80211.h |
| +++ b/include/net/mac80211.h |
| @@ -4011,6 +4011,8 @@ struct ieee80211_prep_tx_info { |
| * @mgd_complete_tx: Notify the driver that the response frame for a previously |
| * transmitted frame announced with @mgd_prepare_tx was received, the data |
| * is filled similarly to @mgd_prepare_tx though the duration is not used. |
| + * Note that this isn't always called for each mgd_prepare_tx() call, for |
| + * example for SAE the 'confirm' messages can be on the air in any order. |
| * |
| * @mgd_protect_tdls_discover: Protect a TDLS discovery session. After sending |
| * a TDLS discovery-request, we expect a reply to arrive on the AP's |
| diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c |
| index b300972c3150..cc47d6b88f04 100644 |
| --- a/net/mac80211/mlme.c |
| +++ b/net/mac80211/mlme.c |
| @@ -3595,6 +3595,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, |
| struct ieee80211_prep_tx_info info = { |
| .subtype = IEEE80211_STYPE_AUTH, |
| }; |
| + bool sae_need_confirm = false; |
| |
| sdata_assert_lock(sdata); |
| |
| @@ -3638,6 +3639,8 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, |
| jiffies + IEEE80211_AUTH_WAIT_SAE_RETRY; |
| ifmgd->auth_data->timeout_started = true; |
| run_again(sdata, ifmgd->auth_data->timeout); |
| + if (auth_transaction == 1) |
| + sae_need_confirm = true; |
| goto notify_driver; |
| } |
| |
| @@ -3680,6 +3683,9 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, |
| ifmgd->auth_data->expected_transaction == 2)) { |
| if (!ieee80211_mark_sta_auth(sdata)) |
| return; /* ignore frame -- wait for timeout */ |
| + } else if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && |
| + auth_transaction == 1) { |
| + sae_need_confirm = true; |
| } else if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && |
| auth_transaction == 2) { |
| sdata_info(sdata, "SAE peer confirmed\n"); |
| @@ -3688,7 +3694,8 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, |
| |
| cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); |
| notify_driver: |
| - drv_mgd_complete_tx(sdata->local, sdata, &info); |
| + if (!sae_need_confirm) |
| + drv_mgd_complete_tx(sdata->local, sdata, &info); |
| } |
| |
| #define case_WLAN(type) \ |
| -- |
| 2.39.5 |
| |