hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/wireless/sme.c
....@@ -5,7 +5,7 @@
55 * (for nl80211's connect() and wext)
66 *
77 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
8
- * Copyright (C) 2009 Intel Corporation. All rights reserved.
8
+ * Copyright (C) 2009, 2020 Intel Corporation. All rights reserved.
99 * Copyright 2017 Intel Deutschland GmbH
1010 */
1111
....@@ -24,7 +24,7 @@
2424
2525 /*
2626 * Software SME in cfg80211, using auth/assoc/deauth calls to the
27
- * driver. This is is for implementing nl80211's connect/disconnect
27
+ * driver. This is for implementing nl80211's connect/disconnect
2828 * and wireless extensions (if configured.)
2929 */
3030
....@@ -205,7 +205,7 @@
205205 return err;
206206 case CFG80211_CONN_ASSOC_FAILED_TIMEOUT:
207207 *treason = NL80211_TIMEOUT_ASSOC;
208
- /* fall through */
208
+ fallthrough;
209209 case CFG80211_CONN_ASSOC_FAILED:
210210 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
211211 NULL, 0,
....@@ -215,7 +215,7 @@
215215 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
216216 NULL, 0,
217217 WLAN_REASON_DEAUTH_LEAVING, false);
218
- /* fall through */
218
+ fallthrough;
219219 case CFG80211_CONN_ABANDON:
220220 /* free directly, disconnected event already sent */
221221 cfg80211_sme_free(wdev);
....@@ -269,6 +269,15 @@
269269 rtnl_unlock();
270270 }
271271
272
+static void cfg80211_step_auth_next(struct cfg80211_conn *conn,
273
+ struct cfg80211_bss *bss)
274
+{
275
+ memcpy(conn->bssid, bss->bssid, ETH_ALEN);
276
+ conn->params.bssid = conn->bssid;
277
+ conn->params.channel = bss->channel;
278
+ conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
279
+}
280
+
272281 /* Returned bss is reference counted and must be cleaned up appropriately. */
273282 static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
274283 {
....@@ -286,10 +295,7 @@
286295 if (!bss)
287296 return NULL;
288297
289
- memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
290
- wdev->conn->params.bssid = wdev->conn->bssid;
291
- wdev->conn->params.channel = bss->channel;
292
- wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
298
+ cfg80211_step_auth_next(wdev->conn, bss);
293299 schedule_work(&rdev->conn_work);
294300
295301 return bss;
....@@ -568,7 +574,12 @@
568574 wdev->conn->params.ssid_len = wdev->ssid_len;
569575
570576 /* see if we have the bss already */
571
- bss = cfg80211_get_conn_bss(wdev);
577
+ bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
578
+ wdev->conn->params.bssid,
579
+ wdev->conn->params.ssid,
580
+ wdev->conn->params.ssid_len,
581
+ wdev->conn_bss_type,
582
+ IEEE80211_PRIVACY(wdev->conn->params.privacy));
572583
573584 if (prev_bssid) {
574585 memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
....@@ -579,6 +590,7 @@
579590 if (bss) {
580591 enum nl80211_timeout_reason treason;
581592
593
+ cfg80211_step_auth_next(wdev->conn, bss);
582594 err = cfg80211_conn_do_work(wdev, &treason);
583595 cfg80211_put_bss(wdev->wiphy, bss);
584596 } else {
....@@ -694,6 +706,7 @@
694706 return;
695707 }
696708
709
+ wdev->unprot_beacon_reported = 0;
697710 nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr,
698711 GFP_KERNEL);
699712
....@@ -741,7 +754,7 @@
741754 }
742755
743756 if (cr->status != WLAN_STATUS_SUCCESS) {
744
- kzfree(wdev->connect_keys);
757
+ kfree_sensitive(wdev->connect_keys);
745758 wdev->connect_keys = NULL;
746759 wdev->ssid_len = 0;
747760 wdev->conn_owner_nlportid = 0;
....@@ -796,12 +809,36 @@
796809 u8 *next;
797810
798811 if (params->bss) {
799
- /* Make sure the bss entry provided by the driver is valid. */
800812 struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss);
801813
802
- if (WARN_ON(list_empty(&ibss->list))) {
803
- cfg80211_put_bss(wdev->wiphy, params->bss);
804
- return;
814
+ if (list_empty(&ibss->list)) {
815
+ struct cfg80211_bss *found = NULL, *tmp = params->bss;
816
+
817
+ found = cfg80211_get_bss(wdev->wiphy, NULL,
818
+ params->bss->bssid,
819
+ wdev->ssid, wdev->ssid_len,
820
+ wdev->conn_bss_type,
821
+ IEEE80211_PRIVACY_ANY);
822
+ if (found) {
823
+ /* The same BSS is already updated so use it
824
+ * instead, as it has latest info.
825
+ */
826
+ params->bss = found;
827
+ } else {
828
+ /* Update with BSS provided by driver, it will
829
+ * be freshly added and ref cnted, we can free
830
+ * the old one.
831
+ *
832
+ * signal_valid can be false, as we are not
833
+ * expecting the BSS to be found.
834
+ *
835
+ * keep the old timestamp to avoid confusion
836
+ */
837
+ cfg80211_bss_update(rdev, ibss, false,
838
+ ibss->ts);
839
+ }
840
+
841
+ cfg80211_put_bss(wdev->wiphy, tmp);
805842 }
806843 }
807844
....@@ -897,6 +934,7 @@
897934 cfg80211_hold_bss(bss_from_pub(info->bss));
898935 wdev->current_bss = bss_from_pub(info->bss);
899936
937
+ wdev->unprot_beacon_reported = 0;
900938 nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy),
901939 wdev->netdev, info, GFP_KERNEL);
902940
....@@ -1072,7 +1110,7 @@
10721110 wdev->current_bss = NULL;
10731111 wdev->ssid_len = 0;
10741112 wdev->conn_owner_nlportid = 0;
1075
- kzfree(wdev->connect_keys);
1113
+ kfree_sensitive(wdev->connect_keys);
10761114 wdev->connect_keys = NULL;
10771115
10781116 nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
....@@ -1092,7 +1130,10 @@
10921130
10931131 if (wiphy_ext_feature_isset(
10941132 wdev->wiphy,
1095
- NL80211_EXT_FEATURE_BEACON_PROTECTION))
1133
+ NL80211_EXT_FEATURE_BEACON_PROTECTION) ||
1134
+ wiphy_ext_feature_isset(
1135
+ wdev->wiphy,
1136
+ NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
10961137 max_key_idx = 7;
10971138 for (i = 0; i <= max_key_idx; i++)
10981139 rdev_del_key(rdev, dev, i, false, NULL);
....@@ -1182,6 +1223,8 @@
11821223
11831224 cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
11841225 rdev->wiphy.ht_capa_mod_mask);
1226
+ cfg80211_oper_and_vht_capa(&connect->vht_capa_mask,
1227
+ rdev->wiphy.vht_capa_mod_mask);
11851228
11861229 if (connkeys && connkeys->def >= 0) {
11871230 int idx;
....@@ -1214,6 +1257,13 @@
12141257 } else {
12151258 if (WARN_ON(connkeys))
12161259 return -EINVAL;
1260
+
1261
+ /* connect can point to wdev->wext.connect which
1262
+ * can hold key data from a previous connection
1263
+ */
1264
+ connect->key = NULL;
1265
+ connect->key_len = 0;
1266
+ connect->key_idx = 0;
12171267 }
12181268
12191269 wdev->connect_keys = connkeys;
....@@ -1250,7 +1300,7 @@
12501300
12511301 ASSERT_WDEV_LOCK(wdev);
12521302
1253
- kzfree(wdev->connect_keys);
1303
+ kfree_sensitive(wdev->connect_keys);
12541304 wdev->connect_keys = NULL;
12551305
12561306 wdev->conn_owner_nlportid = 0;