Skip to content

Commit 328f5bb

Browse files
committed
Merge tag 'mac80211-for-net-2020-03-26' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
Johannes Berg says: ==================== We have the following fixes: * drop data packets if there's no key for them anymore, after there had been one, to avoid sending them in clear when hostapd removes the key before it removes the station and the packets are still queued * check port authorization again after dequeue, to avoid sending packets if the station is no longer authorized * actually remove the authorization flag before the key so packets are also dropped properly because of this * fix nl80211 control port packet tagging to handle them as packets allowed to go out without encryption * fix NL80211_ATTR_CHANNEL_WIDTH outgoing netlink attribute width (should be 32 bits, not 8) * don't WARN in a CSA scenario that happens on some APs * fix HE spatial reuse element size calculation ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f6bf1ba + b95d2cc commit 328f5bb

File tree

8 files changed

+62
-20
lines changed

8 files changed

+62
-20
lines changed

include/linux/ieee80211.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,14 +2102,14 @@ ieee80211_he_spr_size(const u8 *he_spr_ie)
21022102
{
21032103
struct ieee80211_he_spr *he_spr = (void *)he_spr_ie;
21042104
u8 spr_len = sizeof(struct ieee80211_he_spr);
2105-
u32 he_spr_params;
2105+
u8 he_spr_params;
21062106

21072107
/* Make sure the input is not NULL */
21082108
if (!he_spr_ie)
21092109
return 0;
21102110

21112111
/* Calc required length */
2112-
he_spr_params = le32_to_cpu(he_spr->he_sr_control);
2112+
he_spr_params = he_spr->he_sr_control;
21132113
if (he_spr_params & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT)
21142114
spr_len++;
21152115
if (he_spr_params & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT)

net/mac80211/debugfs_sta.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Copyright 2007 Johannes Berg <[email protected]>
66
* Copyright 2013-2014 Intel Mobile Communications GmbH
77
* Copyright(c) 2016 Intel Deutschland GmbH
8-
* Copyright (C) 2018 - 2019 Intel Corporation
8+
* Copyright (C) 2018 - 2020 Intel Corporation
99
*/
1010

1111
#include <linux/debugfs.h>
@@ -78,6 +78,7 @@ static const char * const sta_flag_names[] = {
7878
FLAG(MPSP_OWNER),
7979
FLAG(MPSP_RECIPIENT),
8080
FLAG(PS_DELIVER),
81+
FLAG(USES_ENCRYPTION),
8182
#undef FLAG
8283
};
8384

net/mac80211/key.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Copyright 2007-2008 Johannes Berg <[email protected]>
77
* Copyright 2013-2014 Intel Mobile Communications GmbH
88
* Copyright 2015-2017 Intel Deutschland GmbH
9-
* Copyright 2018-2019 Intel Corporation
9+
* Copyright 2018-2020 Intel Corporation
1010
*/
1111

1212
#include <linux/if_ether.h>
@@ -262,22 +262,29 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
262262
sta ? sta->sta.addr : bcast_addr, ret);
263263
}
264264

265-
int ieee80211_set_tx_key(struct ieee80211_key *key)
265+
static int _ieee80211_set_tx_key(struct ieee80211_key *key, bool force)
266266
{
267267
struct sta_info *sta = key->sta;
268268
struct ieee80211_local *local = key->local;
269269

270270
assert_key_lock(local);
271271

272+
set_sta_flag(sta, WLAN_STA_USES_ENCRYPTION);
273+
272274
sta->ptk_idx = key->conf.keyidx;
273275

274-
if (!ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT))
276+
if (force || !ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT))
275277
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
276278
ieee80211_check_fast_xmit(sta);
277279

278280
return 0;
279281
}
280282

283+
int ieee80211_set_tx_key(struct ieee80211_key *key)
284+
{
285+
return _ieee80211_set_tx_key(key, false);
286+
}
287+
281288
static void ieee80211_pairwise_rekey(struct ieee80211_key *old,
282289
struct ieee80211_key *new)
283290
{
@@ -441,11 +448,8 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
441448
if (pairwise) {
442449
rcu_assign_pointer(sta->ptk[idx], new);
443450
if (new &&
444-
!(new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX)) {
445-
sta->ptk_idx = idx;
446-
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
447-
ieee80211_check_fast_xmit(sta);
448-
}
451+
!(new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX))
452+
_ieee80211_set_tx_key(new, true);
449453
} else {
450454
rcu_assign_pointer(sta->gtk[idx], new);
451455
}

net/mac80211/sta_info.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Copyright 2006-2007 Jiri Benc <[email protected]>
55
* Copyright 2013-2014 Intel Mobile Communications GmbH
66
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
7-
* Copyright (C) 2018-2019 Intel Corporation
7+
* Copyright (C) 2018-2020 Intel Corporation
88
*/
99

1010
#include <linux/module.h>
@@ -1049,6 +1049,11 @@ static void __sta_info_destroy_part2(struct sta_info *sta)
10491049
might_sleep();
10501050
lockdep_assert_held(&local->sta_mtx);
10511051

1052+
while (sta->sta_state == IEEE80211_STA_AUTHORIZED) {
1053+
ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
1054+
WARN_ON_ONCE(ret);
1055+
}
1056+
10521057
/* now keys can no longer be reached */
10531058
ieee80211_free_sta_keys(local, sta);
10541059

net/mac80211/sta_info.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ enum ieee80211_sta_info_flags {
9898
WLAN_STA_MPSP_OWNER,
9999
WLAN_STA_MPSP_RECIPIENT,
100100
WLAN_STA_PS_DELIVER,
101+
WLAN_STA_USES_ENCRYPTION,
101102

102103
NUM_WLAN_STA_FLAGS,
103104
};

net/mac80211/tx.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Copyright 2006-2007 Jiri Benc <[email protected]>
66
* Copyright 2007 Johannes Berg <[email protected]>
77
* Copyright 2013-2014 Intel Mobile Communications GmbH
8-
* Copyright (C) 2018 Intel Corporation
8+
* Copyright (C) 2018, 2020 Intel Corporation
99
*
1010
* Transmit and frame generation functions.
1111
*/
@@ -590,10 +590,13 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
590590
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
591591
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
592592

593-
if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
593+
if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) {
594594
tx->key = NULL;
595-
else if (tx->sta &&
596-
(key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
595+
return TX_CONTINUE;
596+
}
597+
598+
if (tx->sta &&
599+
(key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
597600
tx->key = key;
598601
else if (ieee80211_is_group_privacy_action(tx->skb) &&
599602
(key = rcu_dereference(tx->sdata->default_multicast_key)))
@@ -654,6 +657,9 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
654657
if (!skip_hw && tx->key &&
655658
tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
656659
info->control.hw_key = &tx->key->conf;
660+
} else if (!ieee80211_is_mgmt(hdr->frame_control) && tx->sta &&
661+
test_sta_flag(tx->sta, WLAN_STA_USES_ENCRYPTION)) {
662+
return TX_DROP;
657663
}
658664

659665
return TX_CONTINUE;
@@ -3598,8 +3604,25 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
35983604
tx.skb = skb;
35993605
tx.sdata = vif_to_sdata(info->control.vif);
36003606

3601-
if (txq->sta)
3607+
if (txq->sta) {
36023608
tx.sta = container_of(txq->sta, struct sta_info, sta);
3609+
/*
3610+
* Drop unicast frames to unauthorised stations unless they are
3611+
* EAPOL frames from the local station.
3612+
*/
3613+
if (unlikely(!ieee80211_vif_is_mesh(&tx.sdata->vif) &&
3614+
tx.sdata->vif.type != NL80211_IFTYPE_OCB &&
3615+
!is_multicast_ether_addr(hdr->addr1) &&
3616+
!test_sta_flag(tx.sta, WLAN_STA_AUTHORIZED) &&
3617+
(!(info->control.flags &
3618+
IEEE80211_TX_CTRL_PORT_CTRL_PROTO) ||
3619+
!ether_addr_equal(tx.sdata->vif.addr,
3620+
hdr->addr2)))) {
3621+
I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
3622+
ieee80211_free_txskb(&local->hw, skb);
3623+
goto begin;
3624+
}
3625+
}
36033626

36043627
/*
36053628
* The key can be removed while the packet was queued, so need to call
@@ -5126,6 +5149,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
51265149
struct ieee80211_local *local = sdata->local;
51275150
struct sk_buff *skb;
51285151
struct ethhdr *ehdr;
5152+
u32 ctrl_flags = 0;
51295153
u32 flags;
51305154

51315155
/* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE
@@ -5135,6 +5159,9 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
51355159
proto != cpu_to_be16(ETH_P_PREAUTH))
51365160
return -EINVAL;
51375161

5162+
if (proto == sdata->control_port_protocol)
5163+
ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
5164+
51385165
if (unencrypted)
51395166
flags = IEEE80211_TX_INTFL_DONT_ENCRYPT;
51405167
else
@@ -5160,7 +5187,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
51605187
skb_reset_mac_header(skb);
51615188

51625189
local_bh_disable();
5163-
__ieee80211_subif_start_xmit(skb, skb->dev, flags, 0);
5190+
__ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags);
51645191
local_bh_enable();
51655192

51665193
return 0;

net/wireless/nl80211.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16416,7 +16416,7 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
1641616416
goto nla_put_failure;
1641716417

1641816418
if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
16419-
nla_put_u8(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
16419+
nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
1642016420
goto nla_put_failure;
1642116421

1642216422
if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&

net/wireless/scan.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2022,7 +2022,11 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
20222022

20232023
spin_lock_bh(&rdev->bss_lock);
20242024

2025-
if (WARN_ON(cbss->pub.channel == chan))
2025+
/*
2026+
* Some APs use CSA also for bandwidth changes, i.e., without actually
2027+
* changing the control channel, so no need to update in such a case.
2028+
*/
2029+
if (cbss->pub.channel == chan)
20262030
goto done;
20272031

20282032
/* use transmitting bss */

0 commit comments

Comments
 (0)