* [PATCH v3 2/7] Bluetooth: hci_sync: hold conn in hci_connect_acl/le_sync() callbacks
2026-06-28 12:12 [PATCH v3 1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync() Pauli Virtanen
@ 2026-06-28 12:12 ` Pauli Virtanen
2026-06-28 12:12 ` [PATCH v3 3/7] Bluetooth: hci_sync: hold conn in hci_connect_big_sync() callback Pauli Virtanen
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Pauli Virtanen @ 2026-06-28 12:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen, marcel, luiz.dentz, oss, linux-kernel
There is theoretical UAF if the conn is freed while the hci_sync task
is running.
Hold refcount to avoid that.
Fixes: 881559af5f5c ("Bluetooth: hci_sync: Attempt to dequeue connection attempt")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
Notes:
v3:
- split to multiple patches per different Fixes:
hci_conn_get() was added inside hci_le_create_conn_sync()
in commit 76c2d047410ba, but it is too late to do there as the
hci_conn_get() itself may be UAF.
net/bluetooth/hci_sync.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index a693259dd3ee..66f42a3dc5a1 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -7014,12 +7014,23 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
return err;
}
+static void hci_acl_create_conn_sync_complete(struct hci_dev *hdev, void *data,
+ int err)
+{
+ struct hci_conn *conn = data;
+
+ hci_conn_put(conn);
+}
+
int hci_connect_acl_sync(struct hci_dev *hdev, struct hci_conn *conn)
{
int err;
- err = hci_cmd_sync_queue_once(hdev, hci_acl_create_conn_sync, conn,
- NULL);
+ err = hci_cmd_sync_queue_once(hdev, hci_acl_create_conn_sync,
+ hci_conn_get(conn),
+ hci_acl_create_conn_sync_complete);
+ if (err)
+ hci_conn_put(conn);
return (err == -EEXIST) ? 0 : err;
}
@@ -7030,36 +7041,41 @@ static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
bt_dev_dbg(hdev, "err %d", err);
if (err == -ECANCELED)
- return;
+ goto done;
hci_dev_lock(hdev);
if (!hci_conn_valid(hdev, conn))
- goto done;
+ goto unlock;
if (!err) {
hci_connect_le_scan_cleanup(conn, 0x00);
- goto done;
+ goto unlock;
}
/* Check if connection is still pending */
if (conn != hci_lookup_le_connect(hdev))
- goto done;
+ goto unlock;
/* Flush to make sure we send create conn cancel command if needed */
flush_delayed_work(&conn->le_conn_timeout);
hci_conn_failed(conn, bt_status(err));
-done:
+unlock:
hci_dev_unlock(hdev);
+done:
+ hci_conn_put(conn);
}
int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn)
{
int err;
- err = hci_cmd_sync_queue_once(hdev, hci_le_create_conn_sync, conn,
+ err = hci_cmd_sync_queue_once(hdev, hci_le_create_conn_sync,
+ hci_conn_get(conn),
create_le_conn_complete);
+ if (err)
+ hci_conn_put(conn);
return (err == -EEXIST) ? 0 : err;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v3 3/7] Bluetooth: hci_sync: hold conn in hci_connect_big_sync() callback
2026-06-28 12:12 [PATCH v3 1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync() Pauli Virtanen
2026-06-28 12:12 ` [PATCH v3 2/7] Bluetooth: hci_sync: hold conn in hci_connect_acl/le_sync() callbacks Pauli Virtanen
@ 2026-06-28 12:12 ` Pauli Virtanen
2026-06-28 12:12 ` [PATCH v3 4/7] Bluetooth: hci_sync: hold conn in hci_connect_pa_sync() callback Pauli Virtanen
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Pauli Virtanen @ 2026-06-28 12:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen, marcel, luiz.dentz, oss, linux-kernel
There is theoretical UAF if the conn is freed while the hci_sync task is
running.
Hold refcount to avoid that.
Also hold RCU for hci_conn_valid(), otherwise the return value is
meaningless.
Fixes: 024421cf3992 ("Bluetooth: hci_conn: Fix not setting timeout for BIG Create Sync")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
Notes:
v3:
- split to multiple patches per different Fixes:
- hold RCU instead of hdev->lock
net/bluetooth/hci_sync.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 66f42a3dc5a1..1ec37f6db213 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -7372,10 +7372,17 @@ static void create_big_complete(struct hci_dev *hdev, void *data, int err)
bt_dev_dbg(hdev, "err %d", err);
if (err == -ECANCELED)
- return;
+ goto done;
+
+ rcu_read_lock();
if (hci_conn_valid(hdev, conn))
clear_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags);
+
+ rcu_read_unlock();
+
+done:
+ hci_conn_put(conn);
}
static int hci_le_big_create_sync(struct hci_dev *hdev, void *data)
@@ -7427,8 +7434,11 @@ int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn)
{
int err;
- err = hci_cmd_sync_queue_once(hdev, hci_le_big_create_sync, conn,
+ err = hci_cmd_sync_queue_once(hdev, hci_le_big_create_sync,
+ hci_conn_get(conn),
create_big_complete);
+ if (err)
+ hci_conn_put(conn);
return (err == -EEXIST) ? 0 : err;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v3 4/7] Bluetooth: hci_sync: hold conn in hci_connect_pa_sync() callback
2026-06-28 12:12 [PATCH v3 1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync() Pauli Virtanen
2026-06-28 12:12 ` [PATCH v3 2/7] Bluetooth: hci_sync: hold conn in hci_connect_acl/le_sync() callbacks Pauli Virtanen
2026-06-28 12:12 ` [PATCH v3 3/7] Bluetooth: hci_sync: hold conn in hci_connect_big_sync() callback Pauli Virtanen
@ 2026-06-28 12:12 ` Pauli Virtanen
2026-06-28 12:12 ` [PATCH v3 5/7] Bluetooth: hci_sync: hold conn in hci_past_sync() callback Pauli Virtanen
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Pauli Virtanen @ 2026-06-28 12:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen, marcel, luiz.dentz, oss, linux-kernel
There is theoretical UAF if the conn is freed while the hci_sync task is
running.
Hold refcount to avoid that.
Fixes: 6d0417e4e1cf ("Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast Receiver")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
Notes:
v3:
- split to multiple patches per different Fixes:
net/bluetooth/hci_sync.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 1ec37f6db213..bb59952779dd 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -7198,7 +7198,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
bt_dev_dbg(hdev, "err %d", err);
if (err == -ECANCELED)
- return;
+ goto done;
hci_dev_lock(hdev);
@@ -7222,6 +7222,8 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
unlock:
hci_dev_unlock(hdev);
+done:
+ hci_conn_put(conn);
}
static int hci_le_past_params_sync(struct hci_dev *hdev, struct hci_conn *conn,
@@ -7360,8 +7362,11 @@ int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn)
{
int err;
- err = hci_cmd_sync_queue_once(hdev, hci_le_pa_create_sync, conn,
+ err = hci_cmd_sync_queue_once(hdev, hci_le_pa_create_sync,
+ hci_conn_get(conn),
create_pa_complete);
+ if (err)
+ hci_conn_put(conn);
return (err == -EEXIST) ? 0 : err;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v3 5/7] Bluetooth: hci_sync: hold conn in hci_past_sync() callback
2026-06-28 12:12 [PATCH v3 1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync() Pauli Virtanen
` (2 preceding siblings ...)
2026-06-28 12:12 ` [PATCH v3 4/7] Bluetooth: hci_sync: hold conn in hci_connect_pa_sync() callback Pauli Virtanen
@ 2026-06-28 12:12 ` Pauli Virtanen
2026-06-28 12:12 ` [PATCH v3 6/7] Bluetooth: hci_sync: fix hci_conn_del() use in hci_le_create_conn_sync Pauli Virtanen
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Pauli Virtanen @ 2026-06-28 12:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen, marcel, luiz.dentz, oss, linux-kernel
Avoids giving freed pointers to hci_conn_valid(), which kmalloc may have
reused.
Hold refcount to avoid that.
Fixes: d3413703d5f8 ("Bluetooth: ISO: Add support to bind to trigger PAST")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
Notes:
v3:
- split to multiple patches per different Fixes:
net/bluetooth/hci_sync.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index bb59952779dd..0bbc57792206 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -7458,6 +7458,8 @@ static void past_complete(struct hci_dev *hdev, void *data, int err)
bt_dev_dbg(hdev, "err %d", err);
+ hci_conn_put(past->conn);
+ hci_conn_put(past->le);
kfree(past);
}
@@ -7522,8 +7524,8 @@ int hci_past_sync(struct hci_conn *conn, struct hci_conn *le)
if (!data)
return -ENOMEM;
- data->conn = conn;
- data->le = le;
+ data->conn = hci_conn_get(conn);
+ data->le = hci_conn_get(le);
if (conn->role == HCI_ROLE_MASTER)
err = hci_cmd_sync_queue_once(conn->hdev,
@@ -7533,8 +7535,11 @@ int hci_past_sync(struct hci_conn *conn, struct hci_conn *le)
err = hci_cmd_sync_queue_once(conn->hdev, hci_le_past_sync,
data, past_complete);
- if (err)
+ if (err) {
+ hci_conn_put(data->conn);
+ hci_conn_put(data->le);
kfree(data);
+ }
return (err == -EEXIST) ? 0 : err;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v3 6/7] Bluetooth: hci_sync: fix hci_conn_del() use in hci_le_create_conn_sync
2026-06-28 12:12 [PATCH v3 1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync() Pauli Virtanen
` (3 preceding siblings ...)
2026-06-28 12:12 ` [PATCH v3 5/7] Bluetooth: hci_sync: hold conn in hci_past_sync() callback Pauli Virtanen
@ 2026-06-28 12:12 ` Pauli Virtanen
2026-06-28 12:12 ` [PATCH v3 7/7] Bluetooth: hci_sync: remove unnecessary hci_conn_get in create_conn_sync Pauli Virtanen
2026-06-28 13:27 ` [v3,1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync() bluez.test.bot
6 siblings, 0 replies; 8+ messages in thread
From: Pauli Virtanen @ 2026-06-28 12:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen, marcel, luiz.dentz, oss, linux-kernel
hci_conn_del() caller must hold hdev->lock, check the conn was not
concurrently deleted, and usually inform socket the conn is going to be
deleted.
Use hci_abort_conn_sync() instead of calling hci_conn_del() without
locks etc.
Fixes: 8e8b92ee60de5 ("Bluetooth: hci_sync: Add hci_le_create_conn_sync")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
Notes:
v3:
- use hci_abort_conn_sync instead of lock + hci_conn_valid + hci_conn_del
net/bluetooth/hci_sync.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 0bbc57792206..ab5436e548f9 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -6623,7 +6623,9 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
if (hci_dev_test_flag(hdev, HCI_LE_SCAN) &&
hdev->le_scan_type == LE_SCAN_ACTIVE &&
!hci_dev_test_flag(hdev, HCI_LE_SIMULTANEOUS_ROLES)) {
- hci_conn_del(conn);
+ conn->state = BT_OPEN;
+ hci_abort_conn_sync(hdev, conn,
+ HCI_ERROR_REJ_LIMITED_RESOURCES);
hci_conn_put(conn);
return -EBUSY;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH v3 7/7] Bluetooth: hci_sync: remove unnecessary hci_conn_get in create_conn_sync
2026-06-28 12:12 [PATCH v3 1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync() Pauli Virtanen
` (4 preceding siblings ...)
2026-06-28 12:12 ` [PATCH v3 6/7] Bluetooth: hci_sync: fix hci_conn_del() use in hci_le_create_conn_sync Pauli Virtanen
@ 2026-06-28 12:12 ` Pauli Virtanen
2026-06-28 13:27 ` [v3,1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync() bluez.test.bot
6 siblings, 0 replies; 8+ messages in thread
From: Pauli Virtanen @ 2026-06-28 12:12 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen, marcel, luiz.dentz, oss, linux-kernel
hci_conn_get() without already held reference is data race against
concurrent deletion.
In previous patches, the refcount has been changed to be taken before
starting the hci_sync task, so remove these extra get() + put() as they
are not needed.
Fixes: 76c2d047410ba ("Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
---
net/bluetooth/hci_sync.c | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index ab5436e548f9..e4f63f6a51b0 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -6607,11 +6607,6 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
bt_dev_dbg(hdev, "conn %p", conn);
- /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
- * clear_bit() at done.
- */
- hci_conn_get(conn);
-
clear_bit(HCI_CONN_SCANNING, &conn->flags);
conn->state = BT_CONNECT;
@@ -6626,7 +6621,6 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
conn->state = BT_OPEN;
hci_abort_conn_sync(hdev, conn,
HCI_ERROR_REJ_LIMITED_RESOURCES);
- hci_conn_put(conn);
return -EBUSY;
}
@@ -6720,7 +6714,6 @@ static int hci_le_create_conn_sync(struct hci_dev *hdev, void *data)
/* Re-enable advertising after the connection attempt is finished. */
hci_resume_advertising_sync(hdev);
- hci_conn_put(conn);
return err;
}
@@ -6995,11 +6988,6 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
else
cp.role_switch = 0x00;
- /* Hold a reference so conn stays valid for the HCI_CONN_CREATE
- * clear_bit() below.
- */
- hci_conn_get(conn);
-
/* Mark create connection in flight so hci_cancel_connect_sync() can
* cancel it while blocking on the connection complete event.
*/
@@ -7011,7 +6999,6 @@ static int hci_acl_create_conn_sync(struct hci_dev *hdev, void *data)
conn->conn_timeout, NULL);
clear_bit(HCI_CONN_CREATE, &conn->flags);
- hci_conn_put(conn);
return err;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* RE: [v3,1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync()
2026-06-28 12:12 [PATCH v3 1/7] Bluetooth: hci_conn: hold conn reference in abort_conn_sync() Pauli Virtanen
` (5 preceding siblings ...)
2026-06-28 12:12 ` [PATCH v3 7/7] Bluetooth: hci_sync: remove unnecessary hci_conn_get in create_conn_sync Pauli Virtanen
@ 2026-06-28 13:27 ` bluez.test.bot
6 siblings, 0 replies; 8+ messages in thread
From: bluez.test.bot @ 2026-06-28 13:27 UTC (permalink / raw)
To: linux-bluetooth, pav
[-- Attachment #1: Type: text/plain, Size: 2798 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=1117668
---Test result---
Test Summary:
CheckPatch PASS 8.80 seconds
VerifyFixes PASS 0.28 seconds
VerifySignedoff PASS 0.35 seconds
GitLint FAIL 5.42 seconds
SubjectPrefix PASS 2.39 seconds
BuildKernel PASS 27.39 seconds
CheckAllWarning PASS 30.06 seconds
CheckSparse PASS 30.74 seconds
BuildKernel32 PASS 26.80 seconds
CheckKernelLLVM SKIP 0.00 seconds
TestRunnerSetup PASS 496.49 seconds
TestRunner_l2cap-tester PASS 58.05 seconds
TestRunner_iso-tester PASS 86.54 seconds
TestRunner_bnep-tester PASS 18.91 seconds
TestRunner_mgmt-tester FAIL 210.32 seconds
TestRunner_rfcomm-tester PASS 24.94 seconds
TestRunner_sco-tester PASS 32.29 seconds
TestRunner_ioctl-tester PASS 26.19 seconds
TestRunner_mesh-tester FAIL 26.08 seconds
TestRunner_smp-tester PASS 23.48 seconds
TestRunner_userchan-tester PASS 19.80 seconds
TestRunner_6lowpan-tester PASS 22.69 seconds
IncrementalBuild PASS 48.62 seconds
Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[v3,2/7] Bluetooth: hci_sync: hold conn in hci_connect_acl/le_sync() callbacks
14: B2 Line has trailing whitespace: " "
[v3,7/7] Bluetooth: hci_sync: remove unnecessary hci_conn_get in create_conn_sync
1: T1 Title exceeds max length (81>80): "[v3,7/7] Bluetooth: hci_sync: remove unnecessary hci_conn_get in create_conn_sync"
##############################
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.234 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.555 seconds
Mesh - Send cancel - 2 Timed out 1.990 seconds
https://github.com/bluez/bluetooth-next/pull/363
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 8+ messages in thread