| .. | .. |
|---|
| 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); |
|---|
| .. | .. |
|---|
| 694 | 694 | return; |
|---|
| 695 | 695 | } |
|---|
| 696 | 696 | |
|---|
| 697 | + wdev->unprot_beacon_reported = 0; |
|---|
| 697 | 698 | nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr, |
|---|
| 698 | 699 | GFP_KERNEL); |
|---|
| 699 | 700 | |
|---|
| .. | .. |
|---|
| 741 | 742 | } |
|---|
| 742 | 743 | |
|---|
| 743 | 744 | if (cr->status != WLAN_STATUS_SUCCESS) { |
|---|
| 744 | | - kzfree(wdev->connect_keys); |
|---|
| 745 | + kfree_sensitive(wdev->connect_keys); |
|---|
| 745 | 746 | wdev->connect_keys = NULL; |
|---|
| 746 | 747 | wdev->ssid_len = 0; |
|---|
| 747 | 748 | wdev->conn_owner_nlportid = 0; |
|---|
| .. | .. |
|---|
| 796 | 797 | u8 *next; |
|---|
| 797 | 798 | |
|---|
| 798 | 799 | if (params->bss) { |
|---|
| 799 | | - /* Make sure the bss entry provided by the driver is valid. */ |
|---|
| 800 | 800 | struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss); |
|---|
| 801 | 801 | |
|---|
| 802 | | - if (WARN_ON(list_empty(&ibss->list))) { |
|---|
| 803 | | - cfg80211_put_bss(wdev->wiphy, params->bss); |
|---|
| 804 | | - return; |
|---|
| 802 | + if (list_empty(&ibss->list)) { |
|---|
| 803 | + struct cfg80211_bss *found = NULL, *tmp = params->bss; |
|---|
| 804 | + |
|---|
| 805 | + found = cfg80211_get_bss(wdev->wiphy, NULL, |
|---|
| 806 | + params->bss->bssid, |
|---|
| 807 | + wdev->ssid, wdev->ssid_len, |
|---|
| 808 | + wdev->conn_bss_type, |
|---|
| 809 | + IEEE80211_PRIVACY_ANY); |
|---|
| 810 | + if (found) { |
|---|
| 811 | + /* The same BSS is already updated so use it |
|---|
| 812 | + * instead, as it has latest info. |
|---|
| 813 | + */ |
|---|
| 814 | + params->bss = found; |
|---|
| 815 | + } else { |
|---|
| 816 | + /* Update with BSS provided by driver, it will |
|---|
| 817 | + * be freshly added and ref cnted, we can free |
|---|
| 818 | + * the old one. |
|---|
| 819 | + * |
|---|
| 820 | + * signal_valid can be false, as we are not |
|---|
| 821 | + * expecting the BSS to be found. |
|---|
| 822 | + * |
|---|
| 823 | + * keep the old timestamp to avoid confusion |
|---|
| 824 | + */ |
|---|
| 825 | + cfg80211_bss_update(rdev, ibss, false, |
|---|
| 826 | + ibss->ts); |
|---|
| 827 | + } |
|---|
| 828 | + |
|---|
| 829 | + cfg80211_put_bss(wdev->wiphy, tmp); |
|---|
| 805 | 830 | } |
|---|
| 806 | 831 | } |
|---|
| 807 | 832 | |
|---|
| .. | .. |
|---|
| 897 | 922 | cfg80211_hold_bss(bss_from_pub(info->bss)); |
|---|
| 898 | 923 | wdev->current_bss = bss_from_pub(info->bss); |
|---|
| 899 | 924 | |
|---|
| 925 | + wdev->unprot_beacon_reported = 0; |
|---|
| 900 | 926 | nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy), |
|---|
| 901 | 927 | wdev->netdev, info, GFP_KERNEL); |
|---|
| 902 | 928 | |
|---|
| .. | .. |
|---|
| 1072 | 1098 | wdev->current_bss = NULL; |
|---|
| 1073 | 1099 | wdev->ssid_len = 0; |
|---|
| 1074 | 1100 | wdev->conn_owner_nlportid = 0; |
|---|
| 1075 | | - kzfree(wdev->connect_keys); |
|---|
| 1101 | + kfree_sensitive(wdev->connect_keys); |
|---|
| 1076 | 1102 | wdev->connect_keys = NULL; |
|---|
| 1077 | 1103 | |
|---|
| 1078 | 1104 | nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap); |
|---|
| .. | .. |
|---|
| 1092 | 1118 | |
|---|
| 1093 | 1119 | if (wiphy_ext_feature_isset( |
|---|
| 1094 | 1120 | wdev->wiphy, |
|---|
| 1095 | | - NL80211_EXT_FEATURE_BEACON_PROTECTION)) |
|---|
| 1121 | + NL80211_EXT_FEATURE_BEACON_PROTECTION) || |
|---|
| 1122 | + wiphy_ext_feature_isset( |
|---|
| 1123 | + wdev->wiphy, |
|---|
| 1124 | + NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT)) |
|---|
| 1096 | 1125 | max_key_idx = 7; |
|---|
| 1097 | 1126 | for (i = 0; i <= max_key_idx; i++) |
|---|
| 1098 | 1127 | rdev_del_key(rdev, dev, i, false, NULL); |
|---|
| .. | .. |
|---|
| 1182 | 1211 | |
|---|
| 1183 | 1212 | cfg80211_oper_and_ht_capa(&connect->ht_capa_mask, |
|---|
| 1184 | 1213 | rdev->wiphy.ht_capa_mod_mask); |
|---|
| 1214 | + cfg80211_oper_and_vht_capa(&connect->vht_capa_mask, |
|---|
| 1215 | + rdev->wiphy.vht_capa_mod_mask); |
|---|
| 1185 | 1216 | |
|---|
| 1186 | 1217 | if (connkeys && connkeys->def >= 0) { |
|---|
| 1187 | 1218 | int idx; |
|---|
| .. | .. |
|---|
| 1250 | 1281 | |
|---|
| 1251 | 1282 | ASSERT_WDEV_LOCK(wdev); |
|---|
| 1252 | 1283 | |
|---|
| 1253 | | - kzfree(wdev->connect_keys); |
|---|
| 1284 | + kfree_sensitive(wdev->connect_keys); |
|---|
| 1254 | 1285 | wdev->connect_keys = NULL; |
|---|
| 1255 | 1286 | |
|---|
| 1256 | 1287 | wdev->conn_owner_nlportid = 0; |
|---|