| .. | .. |
|---|
| 5 | 5 | * (for nl80211's connect() and wext) |
|---|
| 6 | 6 | * |
|---|
| 7 | 7 | * 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. |
|---|
| 9 | 9 | * Copyright 2017 Intel Deutschland GmbH |
|---|
| 10 | 10 | */ |
|---|
| 11 | 11 | |
|---|
| .. | .. |
|---|
| 24 | 24 | |
|---|
| 25 | 25 | /* |
|---|
| 26 | 26 | * 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 |
|---|
| 28 | 28 | * and wireless extensions (if configured.) |
|---|
| 29 | 29 | */ |
|---|
| 30 | 30 | |
|---|
| .. | .. |
|---|
| 205 | 205 | return err; |
|---|
| 206 | 206 | case CFG80211_CONN_ASSOC_FAILED_TIMEOUT: |
|---|
| 207 | 207 | *treason = NL80211_TIMEOUT_ASSOC; |
|---|
| 208 | | - /* fall through */ |
|---|
| 208 | + fallthrough; |
|---|
| 209 | 209 | case CFG80211_CONN_ASSOC_FAILED: |
|---|
| 210 | 210 | cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, |
|---|
| 211 | 211 | NULL, 0, |
|---|
| .. | .. |
|---|
| 215 | 215 | cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, |
|---|
| 216 | 216 | NULL, 0, |
|---|
| 217 | 217 | WLAN_REASON_DEAUTH_LEAVING, false); |
|---|
| 218 | | - /* fall through */ |
|---|
| 218 | + fallthrough; |
|---|
| 219 | 219 | case CFG80211_CONN_ABANDON: |
|---|
| 220 | 220 | /* free directly, disconnected event already sent */ |
|---|
| 221 | 221 | cfg80211_sme_free(wdev); |
|---|
| .. | .. |
|---|
| 269 | 269 | rtnl_unlock(); |
|---|
| 270 | 270 | } |
|---|
| 271 | 271 | |
|---|
| 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 | + |
|---|
| 272 | 281 | /* Returned bss is reference counted and must be cleaned up appropriately. */ |
|---|
| 273 | 282 | static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev) |
|---|
| 274 | 283 | { |
|---|
| .. | .. |
|---|
| 286 | 295 | if (!bss) |
|---|
| 287 | 296 | return NULL; |
|---|
| 288 | 297 | |
|---|
| 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); |
|---|
| 293 | 299 | schedule_work(&rdev->conn_work); |
|---|
| 294 | 300 | |
|---|
| 295 | 301 | return bss; |
|---|
| .. | .. |
|---|
| 568 | 574 | wdev->conn->params.ssid_len = wdev->ssid_len; |
|---|
| 569 | 575 | |
|---|
| 570 | 576 | /* 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)); |
|---|
| 572 | 583 | |
|---|
| 573 | 584 | if (prev_bssid) { |
|---|
| 574 | 585 | memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN); |
|---|
| .. | .. |
|---|
| 579 | 590 | if (bss) { |
|---|
| 580 | 591 | enum nl80211_timeout_reason treason; |
|---|
| 581 | 592 | |
|---|
| 593 | + cfg80211_step_auth_next(wdev->conn, bss); |
|---|
| 582 | 594 | err = cfg80211_conn_do_work(wdev, &treason); |
|---|
| 583 | 595 | cfg80211_put_bss(wdev->wiphy, bss); |
|---|
| 584 | 596 | } else { |
|---|
| .. | .. |
|---|
| 694 | 706 | return; |
|---|
| 695 | 707 | } |
|---|
| 696 | 708 | |
|---|
| 709 | + wdev->unprot_beacon_reported = 0; |
|---|
| 697 | 710 | nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr, |
|---|
| 698 | 711 | GFP_KERNEL); |
|---|
| 699 | 712 | |
|---|
| .. | .. |
|---|
| 741 | 754 | } |
|---|
| 742 | 755 | |
|---|
| 743 | 756 | if (cr->status != WLAN_STATUS_SUCCESS) { |
|---|
| 744 | | - kzfree(wdev->connect_keys); |
|---|
| 757 | + kfree_sensitive(wdev->connect_keys); |
|---|
| 745 | 758 | wdev->connect_keys = NULL; |
|---|
| 746 | 759 | wdev->ssid_len = 0; |
|---|
| 747 | 760 | wdev->conn_owner_nlportid = 0; |
|---|
| .. | .. |
|---|
| 921 | 934 | cfg80211_hold_bss(bss_from_pub(info->bss)); |
|---|
| 922 | 935 | wdev->current_bss = bss_from_pub(info->bss); |
|---|
| 923 | 936 | |
|---|
| 937 | + wdev->unprot_beacon_reported = 0; |
|---|
| 924 | 938 | nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy), |
|---|
| 925 | 939 | wdev->netdev, info, GFP_KERNEL); |
|---|
| 926 | 940 | |
|---|
| .. | .. |
|---|
| 1096 | 1110 | wdev->current_bss = NULL; |
|---|
| 1097 | 1111 | wdev->ssid_len = 0; |
|---|
| 1098 | 1112 | wdev->conn_owner_nlportid = 0; |
|---|
| 1099 | | - kzfree(wdev->connect_keys); |
|---|
| 1113 | + kfree_sensitive(wdev->connect_keys); |
|---|
| 1100 | 1114 | wdev->connect_keys = NULL; |
|---|
| 1101 | 1115 | |
|---|
| 1102 | 1116 | nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap); |
|---|
| .. | .. |
|---|
| 1116 | 1130 | |
|---|
| 1117 | 1131 | if (wiphy_ext_feature_isset( |
|---|
| 1118 | 1132 | wdev->wiphy, |
|---|
| 1119 | | - 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)) |
|---|
| 1120 | 1137 | max_key_idx = 7; |
|---|
| 1121 | 1138 | for (i = 0; i <= max_key_idx; i++) |
|---|
| 1122 | 1139 | rdev_del_key(rdev, dev, i, false, NULL); |
|---|
| .. | .. |
|---|
| 1206 | 1223 | |
|---|
| 1207 | 1224 | cfg80211_oper_and_ht_capa(&connect->ht_capa_mask, |
|---|
| 1208 | 1225 | rdev->wiphy.ht_capa_mod_mask); |
|---|
| 1226 | + cfg80211_oper_and_vht_capa(&connect->vht_capa_mask, |
|---|
| 1227 | + rdev->wiphy.vht_capa_mod_mask); |
|---|
| 1209 | 1228 | |
|---|
| 1210 | 1229 | if (connkeys && connkeys->def >= 0) { |
|---|
| 1211 | 1230 | int idx; |
|---|
| .. | .. |
|---|
| 1238 | 1257 | } else { |
|---|
| 1239 | 1258 | if (WARN_ON(connkeys)) |
|---|
| 1240 | 1259 | 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; |
|---|
| 1241 | 1267 | } |
|---|
| 1242 | 1268 | |
|---|
| 1243 | 1269 | wdev->connect_keys = connkeys; |
|---|
| .. | .. |
|---|
| 1274 | 1300 | |
|---|
| 1275 | 1301 | ASSERT_WDEV_LOCK(wdev); |
|---|
| 1276 | 1302 | |
|---|
| 1277 | | - kzfree(wdev->connect_keys); |
|---|
| 1303 | + kfree_sensitive(wdev->connect_keys); |
|---|
| 1278 | 1304 | wdev->connect_keys = NULL; |
|---|
| 1279 | 1305 | |
|---|
| 1280 | 1306 | wdev->conn_owner_nlportid = 0; |
|---|