mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
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> |
||
---|---|---|
.. | ||
aead_api.c | ||
aead_api.h | ||
aes_ccm.h | ||
aes_cmac.c | ||
aes_cmac.h | ||
aes_gcm.h | ||
aes_gmac.c | ||
aes_gmac.h | ||
agg-rx.c | ||
agg-tx.c | ||
airtime.c | ||
cfg.c | ||
chan.c | ||
debug.h | ||
debugfs_key.c | ||
debugfs_key.h | ||
debugfs_netdev.c | ||
debugfs_netdev.h | ||
debugfs_sta.c | ||
debugfs_sta.h | ||
debugfs.c | ||
debugfs.h | ||
driver-ops.c | ||
driver-ops.h | ||
drop.h | ||
eht.c | ||
ethtool.c | ||
fils_aead.c | ||
fils_aead.h | ||
he.c | ||
ht.c | ||
ibss.c | ||
ieee80211_i.h | ||
iface.c | ||
Kconfig | ||
key.c | ||
key.h | ||
led.c | ||
led.h | ||
link.c | ||
main.c | ||
Makefile | ||
mesh_hwmp.c | ||
mesh_pathtbl.c | ||
mesh_plink.c | ||
mesh_ps.c | ||
mesh_sync.c | ||
mesh.c | ||
mesh.h | ||
michael.c | ||
michael.h | ||
mlme.c | ||
ocb.c | ||
offchannel.c | ||
pm.c | ||
rate.c | ||
rate.h | ||
rc80211_minstrel_ht_debugfs.c | ||
rc80211_minstrel_ht.c | ||
rc80211_minstrel_ht.h | ||
rx.c | ||
s1g.c | ||
scan.c | ||
spectmgmt.c | ||
sta_info.c | ||
sta_info.h | ||
status.c | ||
tdls.c | ||
tkip.c | ||
tkip.h | ||
trace_msg.h | ||
trace.c | ||
trace.h | ||
tx.c | ||
util.c | ||
vht.c | ||
wep.c | ||
wep.h | ||
wme.c | ||
wme.h | ||
wpa.c | ||
wpa.h |