From: Cen Zhang <zzzccc427@gmail.com>
To: marcel@holtmann.org, luiz.dentz@gmail.com, pav@iki.fi
Cc: linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org,
baijiaju1990@gmail.com, jjzuming@gmail.com, zzzccc427@gmail.com
Subject: [PATCH] Bluetooth: hci_sync: Drain LE timeouts before disconnecting
Date: Wed, 14 Oct 2026 00:31:55 +0800 [thread overview]
Message-ID: <pm-bluetooth-objects-candidate-0087-v9-625f001f92d657dbf938@gmail.com> (raw)
A pending LE peripheral connection can be deleted by power-off while its
le_conn_timeout callback is running on hdev->workqueue. The callback uses
a raw hci_conn pointer and waits for hdev->lock before calling
hci_conn_failed(). On the request workqueue, hci_disconnect_all_sync() can
abort the same connection first. hci_conn_del() cancels the timeout
without waiting for a running callback, and the walker's final
hci_conn_put() can free the connection before the timeout resumes. The
subsequent conn->hdev read in hci_conn_failed() is a use-after-free.
Disable and drain le_conn_timeout in hci_disconnect_all_sync() before
hci_abort_conn_sync(), while the walker's existing reference still keeps
the connection alive. Do this outside RCU and before taking hdev->lock so
the callback can finish, and prevent the timeout from being requeued
during teardown. If the callback removes the connection, the existing
hash check in hci_abort_conn_sync() avoids deleting it again.
A matching KASAN report from an instrumented kernel showed:
BUG: KASAN: slab-use-after-free in hci_conn_failed+0x3f8/0x410
Read of size 8 at addr ffff888119e391b0 by task
Workqueue: hci0 le_conn_timeout
[...]
hci_conn_failed+0x3f8/0x410
le_conn_timeout+0x286/0x360
[...]
Freed by task 509:
[...]
bt_link_release+0x87/0x180
[...]
put_device+0x24/0x30
hci_disconnect_all_sync.constprop.0+0x163/0x460
hci_set_powered_sync+0x48f/0x680
[...]
Fixes: 94d9ba9f9888 ("Bluetooth: hci_sync: Fix UAF in hci_disconnect_all_sync")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index efbd2e5387c0b..ba573aeebba88 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -6083,6 +6083,15 @@ static int hci_disconnect_all_sync(struct hci_dev *hdev, u8 reason)
/* Make sure the connection is not freed while unlocking */
conn = hci_conn_get(conn);
rcu_read_unlock();
+
+ /*
+ * The LE timeout takes hdev->lock, so drain it before
+ * deleting the connection. The reference above keeps it
+ * alive while waiting.
+ */
+ if (conn->type == LE_LINK)
+ disable_delayed_work_sync(&conn->le_conn_timeout);
+
/* Disregard possible errors since hci_conn_del shall have been
* called even in case of errors had occurred since it would
* then cause hci_conn_failed to be called which calls
next reply other threads:[~2026-10-13 16:32 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-13 16:31 Cen Zhang [this message]
2026-10-13 20:20 ` Bluetooth: hci_sync: Drain LE timeouts before disconnecting bluez.test.bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pm-bluetooth-objects-candidate-0087-v9-625f001f92d657dbf938@gmail.com \
--to=zzzccc427@gmail.com \
--cc=baijiaju1990@gmail.com \
--cc=jjzuming@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luiz.dentz@gmail.com \
--cc=marcel@holtmann.org \
--cc=pav@iki.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.