Hillf Danton
unread,May 13, 2026, 10:04:51 PM (2 days ago) May 13Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Heitor Alves de Siqueira, Marcel Holtmann, Luiz Augusto von Dentz, Gustavo Padovan, linux-b...@vger.kernel.org, linux-...@vger.kernel.org, kerne...@igalia.com, syzkall...@googlegroups.com, syzbot+97721d...@syzkaller.appspotmail.com
On Wed, 13 May 2026 15:55:23 -0300 Heitor Alves de Siqueira wrote:
> 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+97721d...@syzkaller.appspotmail.com
> Closes:
https://syzkaller.appspot.com/bug?extid=97721dd81f792e838ba0
> Signed-off-by: Heitor Alves de Siqueira <
hal...@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);
>
What you add is not enough, go and see how HCI_CMD_DRAIN_WORKQUEUE is
checked in hci_cmd_work(), and in hci_dev_do_reset() for why.