All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: hci_core: Don't queue tx_work while draining workqueue
@ 2026-05-13 18:55 Heitor Alves de Siqueira
  2026-05-13 20:45 ` bluez.test.bot
  2026-05-14  2:04 ` [PATCH] " Hillf Danton
  0 siblings, 2 replies; 8+ messages in thread
From: Heitor Alves de Siqueira @ 2026-05-13 18:55 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Gustavo Padovan
  Cc: linux-bluetooth, linux-kernel, kernel-dev,
	syzbot+97721dd81f792e838ba0

Syzbot reported a warning when L2CAP calls queue_work() on the hdev
workqueue while it's being drained. This can happen during device reset or
close paths for hci_send_acl(), hci_send_sco() and hci_send_iso().

The workqueue is drained in hci_dev_do_reset() and in hci_dev_close_sync():
  - hci_dev_close_sync() clears the HCI_UP bit before draining
  - hci_dev_do_reset() sets HCI_CMD_DRAIN_WORKQUEUE before draining

Add these checks before queuing tx_work, and free the SKB if it's not
queued for transmission.

Fixes: 3eff45eaf817 ("Bluetooth: convert tx_task to workqueue")
Reported-by: syzbot+97721dd81f792e838ba0@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=97721dd81f792e838ba0
Signed-off-by: Heitor Alves de Siqueira <halves@igalia.com>
---
 net/bluetooth/hci_core.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c46c1236ebfa..5d5f8ad7d1a8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3278,6 +3278,12 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
 
 	BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags);
 
+	if (!test_bit(HCI_UP, &hdev->flags) ||
+	    hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) {
+		kfree_skb(skb);
+		return;
+	}
+
 	hci_queue_acl(chan, &chan->data_q, skb, flags);
 
 	queue_work(hdev->workqueue, &hdev->tx_work);
@@ -3291,6 +3297,12 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
 
 	BT_DBG("%s len %d", hdev->name, skb->len);
 
+	if (!test_bit(HCI_UP, &hdev->flags) ||
+	    hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) {
+		kfree_skb(skb);
+		return;
+	}
+
 	hdr.handle = cpu_to_le16(conn->handle);
 	hdr.dlen   = skb->len;
 
@@ -3374,6 +3386,12 @@ void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
 
 	BT_DBG("%s len %d", hdev->name, skb->len);
 
+	if (!test_bit(HCI_UP, &hdev->flags) ||
+	    hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE)) {
+		kfree_skb(skb);
+		return;
+	}
+
 	hci_queue_iso(conn, &conn->data_q, skb);
 
 	queue_work(hdev->workqueue, &hdev->tx_work);

---
base-commit: 1f63dd8ca0dc05a8272bb8155f643c691d29bb11
change-id: 20260513-hci_send-640290de7acc

Best regards,
--  
Heitor Alves de Siqueira <halves@igalia.com>


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-05-20 14:26 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-13 18:55 [PATCH] Bluetooth: hci_core: Don't queue tx_work while draining workqueue Heitor Alves de Siqueira
2026-05-13 20:45 ` bluez.test.bot
2026-05-14  2:04 ` [PATCH] " Hillf Danton
2026-05-14 14:53   ` Heitor Alves de Siqueira
2026-05-15 13:33     ` Luiz Augusto von Dentz
2026-05-18 15:21       ` Heitor Alves de Siqueira
2026-05-18 20:48         ` Luiz Augusto von Dentz
2026-05-20 14:26           ` Heitor Alves de Siqueira

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.