diff options
author | David S. Miller <davem@davemloft.net> | 2016-12-09 22:59:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-12-09 22:59:05 -0500 |
commit | 5ac9efbe1c825d624eb557e633683c07ee03465b (patch) | |
tree | 05bde543deaac0b0af5854bb48d883a9b58db8eb /net/wireless | |
parent | 524a64c7268f8c8c7f22ab37ef0e72529de727c9 (diff) | |
parent | e6f462df9acd2a3295e5d34eb29e2823220cf129 (diff) |
Merge tag 'mac80211-next-for-davem-2016-12-09' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says:
====================
Three fixes:
* fix a logic bug introduced by a previous cleanup
* fix nl80211 attribute confusing (trying to use
a single attribute for two purposes)
* fix a long-standing BSS leak that happens when an
association attempt is abandoned
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.h | 1 | ||||
-rw-r--r-- | net/wireless/mlme.c | 12 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 18 | ||||
-rw-r--r-- | net/wireless/sme.c | 14 |
4 files changed, 43 insertions, 2 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h index ec5f33311769..af6e023020b1 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -410,6 +410,7 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev); | |||
410 | void cfg80211_sme_deauth(struct wireless_dev *wdev); | 410 | void cfg80211_sme_deauth(struct wireless_dev *wdev); |
411 | void cfg80211_sme_auth_timeout(struct wireless_dev *wdev); | 411 | void cfg80211_sme_auth_timeout(struct wireless_dev *wdev); |
412 | void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev); | 412 | void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev); |
413 | void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev); | ||
413 | 414 | ||
414 | /* internal helpers */ | 415 | /* internal helpers */ |
415 | bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); | 416 | bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index bd1f7a159d6a..4646cf5695b9 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -149,6 +149,18 @@ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss) | |||
149 | } | 149 | } |
150 | EXPORT_SYMBOL(cfg80211_assoc_timeout); | 150 | EXPORT_SYMBOL(cfg80211_assoc_timeout); |
151 | 151 | ||
152 | void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss) | ||
153 | { | ||
154 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
155 | struct wiphy *wiphy = wdev->wiphy; | ||
156 | |||
157 | cfg80211_sme_abandon_assoc(wdev); | ||
158 | |||
159 | cfg80211_unhold_bss(bss_from_pub(bss)); | ||
160 | cfg80211_put_bss(wiphy, bss); | ||
161 | } | ||
162 | EXPORT_SYMBOL(cfg80211_abandon_assoc); | ||
163 | |||
152 | void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len) | 164 | void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len) |
153 | { | 165 | { |
154 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 166 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 24ab199ef2fc..3df85a751a85 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -404,6 +404,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { | |||
404 | .len = FILS_MAX_KEK_LEN }, | 404 | .len = FILS_MAX_KEK_LEN }, |
405 | [NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN }, | 405 | [NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN }, |
406 | [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, }, | 406 | [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, }, |
407 | [NL80211_ATTR_BSSID] = { .len = ETH_ALEN }, | ||
407 | }; | 408 | }; |
408 | 409 | ||
409 | /* policy for the key attributes */ | 410 | /* policy for the key attributes */ |
@@ -6703,7 +6704,20 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
6703 | request->no_cck = | 6704 | request->no_cck = |
6704 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); | 6705 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); |
6705 | 6706 | ||
6706 | if (info->attrs[NL80211_ATTR_MAC]) | 6707 | /* Initial implementation used NL80211_ATTR_MAC to set the specific |
6708 | * BSSID to scan for. This was problematic because that same attribute | ||
6709 | * was already used for another purpose (local random MAC address). The | ||
6710 | * NL80211_ATTR_BSSID attribute was added to fix this. For backwards | ||
6711 | * compatibility with older userspace components, also use the | ||
6712 | * NL80211_ATTR_MAC value here if it can be determined to be used for | ||
6713 | * the specific BSSID use case instead of the random MAC address | ||
6714 | * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use). | ||
6715 | */ | ||
6716 | if (info->attrs[NL80211_ATTR_BSSID]) | ||
6717 | memcpy(request->bssid, | ||
6718 | nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN); | ||
6719 | else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) && | ||
6720 | info->attrs[NL80211_ATTR_MAC]) | ||
6707 | memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]), | 6721 | memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]), |
6708 | ETH_ALEN); | 6722 | ETH_ALEN); |
6709 | else | 6723 | else |
@@ -10628,7 +10642,7 @@ static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info) | |||
10628 | if (wdev->iftype != NL80211_IFTYPE_NAN) | 10642 | if (wdev->iftype != NL80211_IFTYPE_NAN) |
10629 | return -EOPNOTSUPP; | 10643 | return -EOPNOTSUPP; |
10630 | 10644 | ||
10631 | if (!wdev_running(wdev)) | 10645 | if (wdev_running(wdev)) |
10632 | return -EEXIST; | 10646 | return -EEXIST; |
10633 | 10647 | ||
10634 | if (rfkill_blocked(rdev->rfkill)) | 10648 | if (rfkill_blocked(rdev->rfkill)) |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 2b5bb380414b..5e0d19380302 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -39,6 +39,7 @@ struct cfg80211_conn { | |||
39 | CFG80211_CONN_ASSOCIATING, | 39 | CFG80211_CONN_ASSOCIATING, |
40 | CFG80211_CONN_ASSOC_FAILED, | 40 | CFG80211_CONN_ASSOC_FAILED, |
41 | CFG80211_CONN_DEAUTH, | 41 | CFG80211_CONN_DEAUTH, |
42 | CFG80211_CONN_ABANDON, | ||
42 | CFG80211_CONN_CONNECTED, | 43 | CFG80211_CONN_CONNECTED, |
43 | } state; | 44 | } state; |
44 | u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; | 45 | u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; |
@@ -206,6 +207,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
206 | cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, | 207 | cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, |
207 | NULL, 0, | 208 | NULL, 0, |
208 | WLAN_REASON_DEAUTH_LEAVING, false); | 209 | WLAN_REASON_DEAUTH_LEAVING, false); |
210 | /* fall through */ | ||
211 | case CFG80211_CONN_ABANDON: | ||
209 | /* free directly, disconnected event already sent */ | 212 | /* free directly, disconnected event already sent */ |
210 | cfg80211_sme_free(wdev); | 213 | cfg80211_sme_free(wdev); |
211 | return 0; | 214 | return 0; |
@@ -423,6 +426,17 @@ void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev) | |||
423 | schedule_work(&rdev->conn_work); | 426 | schedule_work(&rdev->conn_work); |
424 | } | 427 | } |
425 | 428 | ||
429 | void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev) | ||
430 | { | ||
431 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | ||
432 | |||
433 | if (!wdev->conn) | ||
434 | return; | ||
435 | |||
436 | wdev->conn->state = CFG80211_CONN_ABANDON; | ||
437 | schedule_work(&rdev->conn_work); | ||
438 | } | ||
439 | |||
426 | static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev, | 440 | static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev, |
427 | const u8 *ies, size_t ies_len, | 441 | const u8 *ies, size_t ies_len, |
428 | const u8 **out_ies, size_t *out_ies_len) | 442 | const u8 **out_ies, size_t *out_ies_len) |