summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinsuk Kang <linuxlovemin@yonsei.ac.kr>2023-11-22 20:31:04 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-02-05 20:14:20 +0000
commite4f4bac7d3b64eb75f70cd3345712de6f68a215d (patch)
tree6b2473cfdbc63e37427ed60c3379978ec76cab22
parente02851adca4ec36a09f681d4fa4adb3df200bd99 (diff)
wifi: ath9k: Fix potential array-index-out-of-bounds read in ath9k_htc_txstatus()
[ Upstream commit 2adc886244dff60f948497b59affb6c6ebb3c348 ] Fix an array-index-out-of-bounds read in ath9k_htc_txstatus(). The bug occurs when txs->cnt, data from a URB provided by a USB device, is bigger than the size of the array txs->txstatus, which is HTC_MAX_TX_STATUS. WARN_ON() already checks it, but there is no bug handling code after the check. Make the function return if that is the case. Found by a modified version of syzkaller. UBSAN: array-index-out-of-bounds in htc_drv_txrx.c index 13 is out of range for type '__wmi_event_txstatus [12]' Call Trace: ath9k_htc_txstatus ath9k_wmi_event_tasklet tasklet_action_common __do_softirq irq_exit_rxu sysvec_apic_timer_interrupt Signed-off-by: Minsuk Kang <linuxlovemin@yonsei.ac.kr> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://lore.kernel.org/r/20231113065756.1491991-1-linuxlovemin@yonsei.ac.kr Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 672789e3c55d..d6a3f001dacb 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -652,9 +652,10 @@ void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event)
struct ath9k_htc_tx_event *tx_pend;
int i;
- for (i = 0; i < txs->cnt; i++) {
- WARN_ON(txs->cnt > HTC_MAX_TX_STATUS);
+ if (WARN_ON_ONCE(txs->cnt > HTC_MAX_TX_STATUS))
+ return;
+ for (i = 0; i < txs->cnt; i++) {
__txs = &txs->txstatus[i];
skb = ath9k_htc_tx_get_packet(priv, __txs);