forked from mirrors/linux
Station structure is considered as not uploaded (to driver) until drv_sta_state() finishes. This call is however done after the structure is attached to mac80211 internal lists and hashes. This means mac80211 can lookup (and use) station structure before it is uploaded to a driver. If this happens (structure exists, but sta->uploaded is false) fast_tx path can still be taken. Deep in the fastpath call the sta->uploaded is checked against to derive "pubsta" argument for ieee80211_get_txq(). If sta->uploaded is false (and sta is actually non-NULL) ieee80211_get_txq() effectively downgraded to vif->txq. At first glance this may look innocent but coerces mac80211 into a state that is almost guaranteed (codel may drop offending skb) to crash because a station-oriented skb gets queued up on vif-oriented txq. The ieee80211_tx_dequeue() ends up looking at info->control.flags and tries to use txq->sta which in the fail case is NULL. It's probably pointless to pretend one can downgrade skb from sta-txq to vif-txq. Since downgrading unicast traffic to vif->txq must not be done there's no txq to put a frame on if sta->uploaded is false. Therefore the code is made to fall back to regular tx() op path if the described condition is hit. Only drivers using wake_tx_queue were affected. Example crash dump before fix: Unable to handle kernel paging request at virtual address ffffe26c PC is at ieee80211_tx_dequeue+0x204/0x690 [mac80211] [<bf4252a4>] (ieee80211_tx_dequeue [mac80211]) from [<bf4b1388>] (ath10k_mac_tx_push_txq+0x54/0x1c0 [ath10k_core]) [<bf4b1388>] (ath10k_mac_tx_push_txq [ath10k_core]) from [<bf4bdfbc>] (ath10k_htt_txrx_compl_task+0xd78/0x11d0 [ath10k_core]) [<bf4bdfbc>] (ath10k_htt_txrx_compl_task [ath10k_core]) [<bf51c5a4>] (ath10k_pci_napi_poll+0x54/0xe8 [ath10k_pci]) [<bf51c5a4>] (ath10k_pci_napi_poll [ath10k_pci]) from [<c0572e90>] (net_rx_action+0xac/0x160) Reported-by: Mohammed Shafi Shajakhan <mohammed@qti.qualcomm.com> Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
||
|---|---|---|
| .. | ||
| aes_ccm.c | ||
| aes_ccm.h | ||
| aes_cmac.c | ||
| aes_cmac.h | ||
| aes_gcm.c | ||
| aes_gcm.h | ||
| aes_gmac.c | ||
| aes_gmac.h | ||
| agg-rx.c | ||
| agg-tx.c | ||
| cfg.c | ||
| chan.c | ||
| debug.h | ||
| debugfs.c | ||
| debugfs.h | ||
| debugfs_key.c | ||
| debugfs_key.h | ||
| debugfs_netdev.c | ||
| debugfs_netdev.h | ||
| debugfs_sta.c | ||
| debugfs_sta.h | ||
| driver-ops.c | ||
| driver-ops.h | ||
| ethtool.c | ||
| fils_aead.c | ||
| fils_aead.h | ||
| ht.c | ||
| ibss.c | ||
| ieee80211_i.h | ||
| iface.c | ||
| Kconfig | ||
| key.c | ||
| key.h | ||
| led.c | ||
| led.h | ||
| main.c | ||
| Makefile | ||
| mesh.c | ||
| mesh.h | ||
| mesh_hwmp.c | ||
| mesh_pathtbl.c | ||
| mesh_plink.c | ||
| mesh_ps.c | ||
| mesh_sync.c | ||
| michael.c | ||
| michael.h | ||
| mlme.c | ||
| ocb.c | ||
| offchannel.c | ||
| pm.c | ||
| rate.c | ||
| rate.h | ||
| rc80211_minstrel.c | ||
| rc80211_minstrel.h | ||
| rc80211_minstrel_debugfs.c | ||
| rc80211_minstrel_ht.c | ||
| rc80211_minstrel_ht.h | ||
| rc80211_minstrel_ht_debugfs.c | ||
| rx.c | ||
| scan.c | ||
| spectmgmt.c | ||
| sta_info.c | ||
| sta_info.h | ||
| status.c | ||
| tdls.c | ||
| tkip.c | ||
| tkip.h | ||
| trace.c | ||
| trace.h | ||
| trace_msg.h | ||
| tx.c | ||
| util.c | ||
| vht.c | ||
| wep.c | ||
| wep.h | ||
| wme.c | ||
| wme.h | ||
| wpa.c | ||
| wpa.h | ||