summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-12-09 22:59:05 -0500
committerDavid S. Miller <davem@davemloft.net>2016-12-09 22:59:05 -0500
commit5ac9efbe1c825d624eb557e633683c07ee03465b (patch)
tree05bde543deaac0b0af5854bb48d883a9b58db8eb /net/wireless
parent524a64c7268f8c8c7f22ab37ef0e72529de727c9 (diff)
parente6f462df9acd2a3295e5d34eb29e2823220cf129 (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.h1
-rw-r--r--net/wireless/mlme.c12
-rw-r--r--net/wireless/nl80211.c18
-rw-r--r--net/wireless/sme.c14
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);
410void cfg80211_sme_deauth(struct wireless_dev *wdev); 410void cfg80211_sme_deauth(struct wireless_dev *wdev);
411void cfg80211_sme_auth_timeout(struct wireless_dev *wdev); 411void cfg80211_sme_auth_timeout(struct wireless_dev *wdev);
412void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev); 412void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev);
413void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev);
413 414
414/* internal helpers */ 415/* internal helpers */
415bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); 416bool 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}
150EXPORT_SYMBOL(cfg80211_assoc_timeout); 150EXPORT_SYMBOL(cfg80211_assoc_timeout);
151 151
152void 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}
162EXPORT_SYMBOL(cfg80211_abandon_assoc);
163
152void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len) 164void 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
429void 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
426static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev, 440static 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)