Forwarded: [PATCH] carl9170: fix locking in carl9170_get_queued_skb
From: syzbot
Date: Tue Jul 07 2026 - 08:54:30 EST
For archival purposes, forwarding an incoming command email to
linux-kernel@xxxxxxxxxxxxxxx, syzkaller-bugs@xxxxxxxxxxxxxxxx.
***
Subject: [PATCH] carl9170: fix locking in carl9170_get_queued_skb
Author: malayarout91@xxxxxxxxx
Please test the following patch.
#syz test
The carl9170_get_queued_skb function uses spin_lock_bh/spin_unlock_bh,
but it's called from carl9170_usb_rx_irq_complete, which is a USB URB
completion handler running in interrupt context.
The call path is:
carl9170_usb_rx_irq_complete (IRQ context)
-> carl9170_handle_command_response
-> carl9170_tx_process_status
-> __carl9170_tx_process_status
-> carl9170_get_queued_skb
Using spin_unlock_bh in hardirq context triggers a lockdep warning
because it tries to enable bottom halves while hardware interrupts
are disabled, violating locking rules.
Fix this by replacing spin_lock_bh/spin_unlock_bh with
spin_lock_irqsave/spin_unlock_irqrestore to properly handle the
interrupt context.
Reported-by: syzbot+381102a7292a374fe8a7@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=381102a7292a374fe8a7
Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend")
Signed-off-by: Malaya Kumar Rout <malayarout91@xxxxxxxxx>
---
drivers/net/wireless/ath/carl9170/tx.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index 59caf1e4b158..b5a028abe4c6 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -514,8 +514,9 @@ static struct sk_buff *carl9170_get_queued_skb(struct ar9170 *ar, u8 cookie,
struct sk_buff_head *queue)
{
struct sk_buff *skb;
+ unsigned long flags;
- spin_lock_bh(&queue->lock);
+ spin_lock_irqsave(&queue->lock, flags);
skb_queue_walk(queue, skb) {
struct _carl9170_tx_superframe *txc = (void *) skb->data;
@@ -523,12 +524,12 @@ static struct sk_buff *carl9170_get_queued_skb(struct ar9170 *ar, u8 cookie,
continue;
__skb_unlink(skb, queue);
- spin_unlock_bh(&queue->lock);
+ spin_unlock_irqrestore(&queue->lock, flags);
carl9170_release_dev_space(ar, skb);
return skb;
}
- spin_unlock_bh(&queue->lock);
+ spin_unlock_irqrestore(&queue->lock, flags);
return NULL;
}
--
2.54.0