linux/net/mac80211
Wen Gong 139234011f wifi: mac80211: allow transmitting EAPOL frames with tainted key
[ Upstream commit 61304336c6 ]

Lower layer device driver stop/wake TX by calling ieee80211_stop_queue()/
ieee80211_wake_queue() while hw scan. Sometimes hw scan and PTK rekey are
running in parallel, when M4 sent from wpa_supplicant arrive while the TX
queue is stopped, then the M4 will pending send, and then new key install
from wpa_supplicant. After TX queue wake up by lower layer device driver,
the M4 will be dropped by below call stack.

When key install started, the current key flag is set KEY_FLAG_TAINTED in
ieee80211_pairwise_rekey(), and then mac80211 wait key install complete by
lower layer device driver. Meanwhile ieee80211_tx_h_select_key() will return
TX_DROP for the M4 in step 12 below, and then ieee80211_free_txskb() called
by ieee80211_tx_dequeue(), so the M4 will not send and free, then the rekey
process failed becaue AP not receive M4. Please see details in steps below.

There are a interval between KEY_FLAG_TAINTED set for current key flag and
install key complete by lower layer device driver, the KEY_FLAG_TAINTED is
set in this interval, all packet including M4 will be dropped in this
interval, the interval is step 8~13 as below.

issue steps:
      TX thread                 install key thread
1.   stop_queue                      -idle-
2.   sending M4                      -idle-
3.   M4 pending                      -idle-
4.     -idle-                  starting install key from wpa_supplicant
5.     -idle-                  =>ieee80211_key_replace()
6.     -idle-                  =>ieee80211_pairwise_rekey() and set
                                 currently key->flags |= KEY_FLAG_TAINTED
7.     -idle-                  =>ieee80211_key_enable_hw_accel()
8.     -idle-                  =>drv_set_key() and waiting key install
                                 complete from lower layer device driver
9.   wake_queue                     -waiting state-
10.  re-sending M4                  -waiting state-
11.  =>ieee80211_tx_h_select_key()  -waiting state-
12.  drop M4 by KEY_FLAG_TAINTED    -waiting state-
13.    -idle-                   install key complete with success/fail
                                  success: clear flag KEY_FLAG_TAINTED
                                  fail: start disconnect

Hence add check in step 11 above to allow the EAPOL send out in the
interval. If lower layer device driver use the old key/cipher to encrypt
the M4, then AP received/decrypt M4 correctly, after M4 send out, lower
layer device driver install the new key/cipher to hardware and return
success.

If lower layer device driver use new key/cipher to send the M4, then AP
will/should drop the M4, then it is same result with this issue, AP will/
should kick out station as well as this issue.

issue log:
kworker/u16:4-5238  [000]  6456.108926: stop_queue:           phy1 queue:0, reason:0
wpa_supplicant-961  [003]  6456.119737: rdev_tx_control_port: wiphy_name=phy1 name=wlan0 ifindex=6 dest=ARRAY[9e, 05, 31, 20, 9b, d0] proto=36488 unencrypted=0
wpa_supplicant-961  [003]  6456.119839: rdev_return_int_cookie: phy1, returned 0, cookie: 504
wpa_supplicant-961  [003]  6456.120287: rdev_add_key:         phy1, netdev:wlan0(6), key_index: 0, mode: 0, pairwise: true, mac addr: 9e:05:31:20:9b:d0
wpa_supplicant-961  [003]  6456.120453: drv_set_key:          phy1 vif:wlan0(2) sta:9e:05:31:20:9b:d0 cipher:0xfac04, flags=0x9, keyidx=0, hw_key_idx=0
kworker/u16:9-3829  [001]  6456.168240: wake_queue:           phy1 queue:0, reason:0
kworker/u16:9-3829  [001]  6456.168255: drv_wake_tx_queue:    phy1 vif:wlan0(2) sta:9e:05:31:20:9b:d0 ac:0 tid:7
kworker/u16:9-3829  [001]  6456.168305: cfg80211_control_port_tx_status: wdev(1), cookie: 504, ack: false
wpa_supplicant-961  [003]  6459.167982: drv_return_int:       phy1 - -110

issue call stack:
nl80211_frame_tx_status+0x230/0x340 [cfg80211]
cfg80211_control_port_tx_status+0x1c/0x28 [cfg80211]
ieee80211_report_used_skb+0x374/0x3e8 [mac80211]
ieee80211_free_txskb+0x24/0x40 [mac80211]
ieee80211_tx_dequeue+0x644/0x954 [mac80211]
ath10k_mac_tx_push_txq+0xac/0x238 [ath10k_core]
ath10k_mac_op_wake_tx_queue+0xac/0xe0 [ath10k_core]
drv_wake_tx_queue+0x80/0x168 [mac80211]
__ieee80211_wake_txqs+0xe8/0x1c8 [mac80211]
_ieee80211_wake_txqs+0xb4/0x120 [mac80211]
ieee80211_wake_txqs+0x48/0x80 [mac80211]
tasklet_action_common+0xa8/0x254
tasklet_action+0x2c/0x38
__do_softirq+0xdc/0x384

Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
Link: https://lore.kernel.org/r/20230801064751.25803-1-quic_wgong@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-10-25 11:53:23 +02:00
..
aead_api.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
aead_api.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
aes_ccm.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
aes_cmac.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
aes_cmac.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
aes_gcm.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
aes_gmac.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
aes_gmac.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
agg-rx.c mac80211: fix lookup when adding AddBA extension element 2021-12-22 09:29:37 +01:00
agg-tx.c mac80211: refuse aggregations sessions before authorized 2022-03-19 13:40:16 +01:00
cfg.c wifi: mac80211: allow bw change during channel switch in mesh 2022-10-26 13:22:22 +02:00
chan.c wifi: mac80211: fix use-after-free in chanctx code 2022-06-14 18:11:44 +02:00
debug.h
debugfs_key.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2019-06-22 08:59:24 -04:00
debugfs_key.h
debugfs_netdev.c mac80211: fix txq null pointer dereference 2019-10-01 17:56:19 +02:00
debugfs_netdev.h
debugfs_sta.c mac80211: drop data frames without key on encrypted links 2020-04-01 11:02:01 +02:00
debugfs_sta.h
debugfs.c mac80211: AMPDU handling for rekeys with Extended Key ID 2019-07-26 13:29:10 +02:00
debugfs.h
driver-ops.c mac80211: fix station rate table updates on assoc 2021-02-10 09:25:29 +01:00
driver-ops.h mac80211: mark TX-during-stop for TX in in_reconfig 2021-12-22 09:29:34 +01:00
ethtool.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 432 2019-06-05 17:37:16 +02:00
fils_aead.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
fils_aead.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
he.c mac80211: fix possible NULL pointerderef in obss pd code 2019-08-21 10:58:32 +02:00
ht.c mac80211: add support for the ADDBA extension element 2019-07-29 16:40:22 +02:00
ibss.c wifi: mac80211: Don't finalize CSA in IBSS mode if state is disconnected 2022-09-15 12:04:53 +02:00
ieee80211_i.h mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh 2023-02-25 11:53:26 +01:00
iface.c mac80211: Fix monitor MTU limit so that A-MSDUs get through 2021-09-22 12:26:32 +02:00
Kconfig Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2019-07-08 20:57:08 -07:00
key.c mac80211: prevent mixed key and fragment cache attacks 2021-06-03 08:59:01 +02:00
key.h mac80211: prevent mixed key and fragment cache attacks 2021-06-03 08:59:01 +02:00
led.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
led.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
main.c wifi: mac80211: fix memory free error when registering wiphy fail 2022-12-08 11:22:56 +01:00
Makefile
mesh_hwmp.c mac80211: fix potential overflow when multiplying to u32 integers 2021-03-04 10:26:17 +01:00
mesh_pathtbl.c mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh 2023-02-25 11:53:26 +01:00
mesh_plink.c mac80211: implement HE support for mesh 2019-07-26 16:14:12 +02:00
mesh_ps.c mac80211: mesh: fix potentially unaligned access 2021-10-06 15:42:32 +02:00
mesh_sync.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
mesh.c mac80211: fix channel switch trigger from unknown mesh peer 2020-05-02 08:48:58 +02:00
mesh.h mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh 2023-02-25 11:53:26 +01:00
michael.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
michael.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
mlme.c wifi: mac80211: fix MBSSID parsing use-after-free 2022-10-17 17:24:32 +02:00
ocb.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
offchannel.c mac80211: pass the vif to cancel_remain_on_channel 2019-07-26 13:08:28 +02:00
pm.c
rate.c mac80211: fix station rate table updates on assoc 2021-02-10 09:25:29 +01:00
rate.h mac80211: populate debugfs only after cfg80211 init 2020-04-29 16:33:18 +02:00
rc80211_minstrel_debugfs.c
rc80211_minstrel_ht_debugfs.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
rc80211_minstrel_ht.c mac80211: populate debugfs only after cfg80211 init 2020-04-29 16:33:18 +02:00
rc80211_minstrel_ht.h mac80211: minstrel_ht: improve rate probing for devices with static fallback 2019-08-21 11:10:13 +02:00
rc80211_minstrel.c mac80211: minstrel: fix tx status processing corner case 2020-11-24 13:29:23 +01:00
rc80211_minstrel.h mac80211: minstrel: remove deferred sampling code 2020-11-24 13:29:23 +01:00
rx.c mac80211: fix rx reordering with non explicit / psmp ack policy 2022-05-25 09:14:37 +02:00
scan.c wifi: mac80211: fix MBSSID parsing use-after-free 2022-10-17 17:24:32 +02:00
spectmgmt.c mac80211: 160MHz with extended NSS BW in CSA 2021-02-13 13:52:55 +01:00
sta_info.c wifi: mac80211: fix invalid drv_sta_pre_rcu_remove calls for non-uploaded sta 2023-04-20 12:07:33 +02:00
sta_info.h mac80211: fix regression in SSN handling of addba tx 2021-12-22 09:29:40 +01:00
status.c mac80211: add ieee80211_is_any_nullfunc() 2020-05-10 10:31:32 +02:00
tdls.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2019-06-17 15:55:34 -07:00
tkip.c mac80211: Fix TKIP replay protection immediately after key setup 2020-02-05 21:22:46 +00:00
tkip.h Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2019-07-08 20:57:08 -07:00
trace_msg.h mac80211: Increase MAX_MSG_LEN 2019-03-29 11:20:36 +01:00
trace.c
trace.h mac80211: pass the vif to cancel_remain_on_channel 2019-07-26 13:08:28 +02:00
tx.c wifi: mac80211: allow transmitting EAPOL frames with tainted key 2023-10-25 11:53:23 +02:00
util.c wifi: mac80211: fix MBSSID parsing use-after-free 2022-10-17 17:24:32 +02:00
vht.c mac80211: don't set set TDLS STA bandwidth wider than possible 2020-12-30 11:51:25 +01:00
wep.c Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2019-07-08 20:57:08 -07:00
wep.h Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2019-07-08 20:57:08 -07:00
wme.c wifi: mac80211: fix qos on mesh interfaces 2023-04-05 11:16:41 +02:00
wme.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00
wpa.c mac80211: fix use-after-free in CCMP/GCMP RX 2021-10-06 15:42:31 +02:00
wpa.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500 2019-06-19 17:09:55 +02:00