* [PATCH] Bluetooth: hci_conn: hold conn for LE timeout work
@ 2026-07-30 10:41 Chengfeng Ye
2026-07-30 12:00 ` bluez.test.bot
0 siblings, 1 reply; 2+ messages in thread
From: Chengfeng Ye @ 2026-07-30 10:41 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, Johan Hedberg
Cc: linux-bluetooth, linux-kernel, Chengfeng Ye, stable
le_conn_timeout is embedded in struct hci_conn, but queuing the work
does not hold a reference to the connection. hci_conn_del() uses
cancel_delayed_work() because synchronous cancellation would deadlock
when le_conn_timeout() itself calls hci_conn_del() while holding
hdev->lock.
This leaves the following interleaving possible:
CPU 0 CPU 1
le_conn_timeout()
hci_conn_del()
cancel_delayed_work() = false
hci_conn_cleanup()
put_device()
kfree(conn)
hci_conn_failed(conn, ...)
The callback then dereferences the released connection. KASAN reported:
BUG: KASAN: slab-use-after-free in hci_conn_failed+0x232/0x250
Read of size 8 at addr ffff8881180e8e20 by task kworker/u33:1/111
Workqueue: hci0 le_conn_timeout
Call Trace:
hci_conn_failed+0x232/0x250
le_conn_timeout+0x23e/0x2c0
process_one_work+0x61b/0xf50
worker_thread+0x45b/0xd10
Allocated by task 115:
__hci_conn_add+0x1758/0x1b90
hci_connect_le+0x523/0x780
l2cap_chan_connect+0xfca/0x1bd0
l2cap_sock_connect+0x310/0x530
Freed by task 110:
kfree+0x149/0x330
device_release+0xc8/0x240
kobject_put+0x14d/0x280
hci_conn_del+0x561/0xe70
hci_abort_conn_sync+0x3e3/0x800
Take a connection device reference before queuing le_conn_timeout. Drop
it when the callback finishes, when queuing fails, or when cancellation
removes a pending instance. If cancellation races an executing callback,
the callback retains the reference until its final access, avoiding the
use-after-free without waiting under hdev->lock.
Fixes: 980ffc0a2cec ("Bluetooth: Fix LE connection timeout deadlock")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
---
net/bluetooth/hci_conn.c | 8 ++++++--
net/bluetooth/hci_event.c | 25 ++++++++++++++++---------
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 1966cd153d97..501a2dd2543b 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -723,10 +723,13 @@ static void le_conn_timeout(struct work_struct *work)
hci_dev_lock(hdev);
hci_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
hci_dev_unlock(hdev);
- return;
+ goto done;
}
hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
+
+done:
+ hci_conn_put(conn);
}
struct iso_list_data {
@@ -1267,7 +1270,8 @@ void hci_conn_del(struct hci_conn *conn)
hdev->acl_cnt += conn->sent;
break;
case LE_LINK:
- cancel_delayed_work(&conn->le_conn_timeout);
+ if (cancel_delayed_work(&conn->le_conn_timeout))
+ hci_conn_put(conn);
if (hdev->le_pkts) {
if (!hci_conn_num(hdev, LE_LINK) ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 741d658e9630..e1e6b5092ce8 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1566,10 +1566,13 @@ static u8 hci_cc_le_set_adv_enable(struct hci_dev *hdev, void *data,
hci_dev_set_flag(hdev, HCI_LE_ADV);
conn = hci_lookup_le_connect(hdev);
- if (conn)
- queue_delayed_work(hdev->workqueue,
- &conn->le_conn_timeout,
- conn->conn_timeout);
+ if (conn) {
+ hci_conn_get(conn);
+ if (!queue_delayed_work(hdev->workqueue,
+ &conn->le_conn_timeout,
+ conn->conn_timeout))
+ hci_conn_put(conn);
+ }
} else {
hci_dev_clear_flag(hdev, HCI_LE_ADV);
}
@@ -1614,10 +1617,13 @@ static u8 hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, void *data,
hci_dev_set_flag(hdev, HCI_LE_ADV_0);
conn = hci_lookup_le_connect(hdev);
- if (conn)
- queue_delayed_work(hdev->workqueue,
- &conn->le_conn_timeout,
- conn->conn_timeout);
+ if (conn) {
+ hci_conn_get(conn);
+ if (!queue_delayed_work(hdev->workqueue,
+ &conn->le_conn_timeout,
+ conn->conn_timeout))
+ hci_conn_put(conn);
+ }
} else {
if (cp->num_of_sets) {
if (adv)
@@ -5771,7 +5777,8 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
}
}
} else {
- cancel_delayed_work(&conn->le_conn_timeout);
+ if (cancel_delayed_work(&conn->le_conn_timeout))
+ hci_conn_put(conn);
}
/* The HCI_LE_Connection_Complete event is only sent once per connection.
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* RE: Bluetooth: hci_conn: hold conn for LE timeout work
2026-07-30 10:41 [PATCH] Bluetooth: hci_conn: hold conn for LE timeout work Chengfeng Ye
@ 2026-07-30 12:00 ` bluez.test.bot
0 siblings, 0 replies; 2+ messages in thread
From: bluez.test.bot @ 2026-07-30 12:00 UTC (permalink / raw)
To: linux-bluetooth, nicoyip.dev
[-- Attachment #1: Type: text/plain, Size: 2389 bytes --]
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1137329
---Test result---
Test Summary:
CheckPatch PASS 0.95 seconds
VerifyFixes PASS 0.14 seconds
VerifySignedoff PASS 0.57 seconds
GitLint PASS 0.33 seconds
SubjectPrefix PASS 0.12 seconds
BuildKernel PASS 26.09 seconds
CheckAllWarning PASS 29.13 seconds
CheckSparse PASS 30.71 seconds
BuildKernel32 PASS 25.55 seconds
CheckKernelLLVM SKIP 0.00 seconds
TestRunnerSetup PASS 492.27 seconds
TestRunner_l2cap-tester PASS 59.61 seconds
TestRunner_iso-tester PASS 76.14 seconds
TestRunner_bnep-tester PASS 18.81 seconds
TestRunner_mgmt-tester FAIL 214.67 seconds
TestRunner_rfcomm-tester PASS 25.22 seconds
TestRunner_sco-tester PASS 30.98 seconds
TestRunner_ioctl-tester PASS 26.20 seconds
TestRunner_mesh-tester FAIL 25.90 seconds
TestRunner_smp-tester PASS 23.22 seconds
TestRunner_userchan-tester PASS 19.91 seconds
TestRunner_6lowpan-tester PASS 22.89 seconds
IncrementalBuild PASS 25.05 seconds
Details
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found
##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4
Failed Test Cases
Read Exp Feature - Success Failed 0.247 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0
Failed Test Cases
Mesh - Send cancel - 1 Timed out 2.372 seconds
Mesh - Send cancel - 2 Timed out 1.989 seconds
https://github.com/bluez/bluetooth-next/pull/515
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-30 12:00 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 10:41 [PATCH] Bluetooth: hci_conn: hold conn for LE timeout work Chengfeng Ye
2026-07-30 12:00 ` bluez.test.bot
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.