mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
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 -----BEGIN PGP SIGNATURE----- iQIcBAABCgAGBQJYSpxnAAoJEGt7eEactAAd3hEP/0RzU5BLTe3FD39i2ESo4fQo q2Wnaa+ES1Ul473rCuSmPLGzlSjh0GciltHXRu7UEf5zXAjwuQtilrKsI9DizVR8 hgTV4Jp0TDLuDudgxEPlpLxcFWALDaK0AlKuL1dY/FSI1BnNnToEeX8Bum6/otqe 2wLQ11+70HrdNHJjvBEHP/kE/2D55easydmkCS30WYlFrd0BEFtGZ6Leb8deIAzL qQpanf26jBYVTm7ls+j0bt4mYbb0RLcsLrOS8EgyIYhCsbJHbaC2OpYGTbGxR6ob KKx01PGVnzytaKXCx/m70923V2mwWZWwa7IgDfoj2IzvsTnfmCgekGdSCiY+DJjE 1jiDYWVK3KgTJQqXRnE1BCbF/FPK6ABKoPgmJBAAiLC48VpmrQwG0OLLQmYVTdp9 KLrQztvZAVV1adA32fGpJHecDyQMMZ2xp7TZn9YY3qAiP4APU8IUscKuSXALmKN9 kMBUBhwkk7QuHZXkry0QFBpFXpOgYjX3vt/gBh8EAmGfyRIklTKtGsmftkuQbWR9 9BN4TbPznEJECqVy/BCL8llHNkfsJgcz3noFOePUjwa4FCAxJst/NFya+IkkqOQ5 eAOj5cjsDfxsrdJFGxIsxXrtGZI1MjwKZf3w6jmu/VVL6BMryxYwtWnwrwcBsit7 nXjitThBO0V2l3Iaf09m =HvKt -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
5ac9efbe1c
@ -4685,6 +4685,17 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
|
||||
*/
|
||||
void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss);
|
||||
|
||||
/**
|
||||
* cfg80211_abandon_assoc - notify cfg80211 of abandoned association attempt
|
||||
* @dev: network device
|
||||
* @bss: The BSS entry with which association was abandoned.
|
||||
*
|
||||
* Call this whenever - for reasons reported through other API, like deauth RX,
|
||||
* an association attempt was abandoned.
|
||||
* This function may sleep. The caller must hold the corresponding wdev's mutex.
|
||||
*/
|
||||
void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss);
|
||||
|
||||
/**
|
||||
* cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame
|
||||
* @dev: network device
|
||||
|
@ -323,7 +323,7 @@
|
||||
* @NL80211_CMD_GET_SCAN: get scan results
|
||||
* @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters
|
||||
* %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
|
||||
* probe requests at CCK rate or not. %NL80211_ATTR_MAC can be used to
|
||||
* probe requests at CCK rate or not. %NL80211_ATTR_BSSID can be used to
|
||||
* specify a BSSID to scan for; if not included, the wildcard BSSID will
|
||||
* be used.
|
||||
* @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to
|
||||
@ -1977,6 +1977,9 @@ enum nl80211_commands {
|
||||
* @NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED: Indicates whether or not multicast
|
||||
* packets should be send out as unicast to all stations (flag attribute).
|
||||
*
|
||||
* @NL80211_ATTR_BSSID: The BSSID of the AP. Note that %NL80211_ATTR_MAC is also
|
||||
* used in various commands/events for specifying the BSSID.
|
||||
*
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@ -2381,6 +2384,8 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED,
|
||||
|
||||
NL80211_ATTR_BSSID,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
|
@ -2518,7 +2518,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
|
||||
bool assoc)
|
||||
bool assoc, bool abandon)
|
||||
{
|
||||
struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
|
||||
|
||||
@ -2541,6 +2541,9 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
|
||||
mutex_lock(&sdata->local->mtx);
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
mutex_unlock(&sdata->local->mtx);
|
||||
|
||||
if (abandon)
|
||||
cfg80211_abandon_assoc(sdata->dev, assoc_data->bss);
|
||||
}
|
||||
|
||||
kfree(assoc_data);
|
||||
@ -2773,7 +2776,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
bssid, reason_code,
|
||||
ieee80211_get_reason_code_string(reason_code));
|
||||
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
ieee80211_destroy_assoc_data(sdata, false, true);
|
||||
|
||||
cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
|
||||
return;
|
||||
@ -3182,14 +3185,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
||||
if (status_code != WLAN_STATUS_SUCCESS) {
|
||||
sdata_info(sdata, "%pM denied association (code=%d)\n",
|
||||
mgmt->sa, status_code);
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
ieee80211_destroy_assoc_data(sdata, false, false);
|
||||
event.u.mlme.status = MLME_DENIED;
|
||||
event.u.mlme.reason = status_code;
|
||||
drv_event_callback(sdata->local, sdata, &event);
|
||||
} else {
|
||||
if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
|
||||
/* oops -- internal error -- send timeout for now */
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
ieee80211_destroy_assoc_data(sdata, false, false);
|
||||
cfg80211_assoc_timeout(sdata->dev, bss);
|
||||
return;
|
||||
}
|
||||
@ -3202,7 +3205,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
||||
* recalc after assoc_data is NULL but before associated
|
||||
* is set can cause the interface to go idle
|
||||
*/
|
||||
ieee80211_destroy_assoc_data(sdata, true);
|
||||
ieee80211_destroy_assoc_data(sdata, true, false);
|
||||
|
||||
/* get uapsd queues configuration */
|
||||
uapsd_queues = 0;
|
||||
@ -3901,7 +3904,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
||||
.u.mlme.status = MLME_TIMEOUT,
|
||||
};
|
||||
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
ieee80211_destroy_assoc_data(sdata, false, false);
|
||||
cfg80211_assoc_timeout(sdata->dev, bss);
|
||||
drv_event_callback(sdata->local, sdata, &event);
|
||||
}
|
||||
@ -4040,7 +4043,7 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
|
||||
WLAN_REASON_DEAUTH_LEAVING,
|
||||
false, frame_buf);
|
||||
if (ifmgd->assoc_data)
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
ieee80211_destroy_assoc_data(sdata, false, true);
|
||||
if (ifmgd->auth_data)
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
||||
@ -4949,7 +4952,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
IEEE80211_STYPE_DEAUTH,
|
||||
req->reason_code, tx,
|
||||
frame_buf);
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
ieee80211_destroy_assoc_data(sdata, false, true);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
req->reason_code);
|
||||
@ -5024,7 +5027,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
|
||||
sdata_lock(sdata);
|
||||
if (ifmgd->assoc_data) {
|
||||
struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
ieee80211_destroy_assoc_data(sdata, false, false);
|
||||
cfg80211_assoc_timeout(sdata->dev, bss);
|
||||
}
|
||||
if (ifmgd->auth_data)
|
||||
|
@ -410,6 +410,7 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev);
|
||||
void cfg80211_sme_deauth(struct wireless_dev *wdev);
|
||||
void cfg80211_sme_auth_timeout(struct wireless_dev *wdev);
|
||||
void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev);
|
||||
void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev);
|
||||
|
||||
/* internal helpers */
|
||||
bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
|
||||
|
@ -149,6 +149,18 @@ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_assoc_timeout);
|
||||
|
||||
void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
|
||||
cfg80211_sme_abandon_assoc(wdev);
|
||||
|
||||
cfg80211_unhold_bss(bss_from_pub(bss));
|
||||
cfg80211_put_bss(wiphy, bss);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_abandon_assoc);
|
||||
|
||||
void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
|
@ -404,6 +404,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
.len = FILS_MAX_KEK_LEN },
|
||||
[NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
|
||||
[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
|
||||
[NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@ -6703,7 +6704,20 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||
request->no_cck =
|
||||
nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
|
||||
|
||||
if (info->attrs[NL80211_ATTR_MAC])
|
||||
/* Initial implementation used NL80211_ATTR_MAC to set the specific
|
||||
* BSSID to scan for. This was problematic because that same attribute
|
||||
* was already used for another purpose (local random MAC address). The
|
||||
* NL80211_ATTR_BSSID attribute was added to fix this. For backwards
|
||||
* compatibility with older userspace components, also use the
|
||||
* NL80211_ATTR_MAC value here if it can be determined to be used for
|
||||
* the specific BSSID use case instead of the random MAC address
|
||||
* (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
|
||||
*/
|
||||
if (info->attrs[NL80211_ATTR_BSSID])
|
||||
memcpy(request->bssid,
|
||||
nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
|
||||
else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
|
||||
info->attrs[NL80211_ATTR_MAC])
|
||||
memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
|
||||
ETH_ALEN);
|
||||
else
|
||||
@ -10628,7 +10642,7 @@ static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
|
||||
if (wdev->iftype != NL80211_IFTYPE_NAN)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!wdev_running(wdev))
|
||||
if (wdev_running(wdev))
|
||||
return -EEXIST;
|
||||
|
||||
if (rfkill_blocked(rdev->rfkill))
|
||||
|
@ -39,6 +39,7 @@ struct cfg80211_conn {
|
||||
CFG80211_CONN_ASSOCIATING,
|
||||
CFG80211_CONN_ASSOC_FAILED,
|
||||
CFG80211_CONN_DEAUTH,
|
||||
CFG80211_CONN_ABANDON,
|
||||
CFG80211_CONN_CONNECTED,
|
||||
} state;
|
||||
u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
|
||||
@ -206,6 +207,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
|
||||
cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
|
||||
NULL, 0,
|
||||
WLAN_REASON_DEAUTH_LEAVING, false);
|
||||
/* fall through */
|
||||
case CFG80211_CONN_ABANDON:
|
||||
/* free directly, disconnected event already sent */
|
||||
cfg80211_sme_free(wdev);
|
||||
return 0;
|
||||
@ -423,6 +426,17 @@ void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
|
||||
schedule_work(&rdev->conn_work);
|
||||
}
|
||||
|
||||
void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
|
||||
if (!wdev->conn)
|
||||
return;
|
||||
|
||||
wdev->conn->state = CFG80211_CONN_ABANDON;
|
||||
schedule_work(&rdev->conn_work);
|
||||
}
|
||||
|
||||
static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev,
|
||||
const u8 *ies, size_t ies_len,
|
||||
const u8 **out_ies, size_t *out_ies_len)
|
||||
|
Loading…
Reference in New Issue
Block a user