Linux Kernel Mentees list
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths
@ 2026-06-01 11:19 SeungJu Cheon
  2026-06-01 11:19 ` [PATCH v2 1/2] Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls SeungJu Cheon
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: SeungJu Cheon @ 2026-06-01 11:19 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, me, skhan, linux-kernel-mentees,
	SeungJu Cheon

The connect paths read socket address and config fields without
lock_sock() and pass them to hci_get_route() and hci_connect_*(),
while connect()/bind()/setsockopt() can update them concurrently.

Patch 1 covers ISO (iso_connect_bis/cis, iso_listen_bis,
iso_conn_big_sync), patch 2 covers SCO (sco_connect).

The added lock_sock() sections are reached with the lock not held and
released before hci_get_route()/hci_dev_lock(), so no recursive locking
or new lock ordering is introduced.

Tested on KCSAN + PROVE_LOCKING with VHCI reproducers on the SCO and
ISO CIS connect paths; the hci_get_route() race no longer reproduces
and no lockdep splat is seen.

Changes in v2:
- ISO: cache bc_sid too, and pass cached src/dst/bc_sid to
  __iso_get_sock_listen_by_sid() in iso_listen_bis() (missed in v1)
- ISO: use cached bc_sid in BT_DBG() in iso_connect_bis()
- SCO: also snapshot src, setting and codec; v1 only did dst
- reword: the fix stops torn reads, it does not close the TOCTOU window
- fix the SCO Fixes: tag title

SeungJu Cheon (2):
  Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls
  Bluetooth: SCO: Fix data-race on sco_pi fields in sco_connect

 net/bluetooth/iso.c | 60 +++++++++++++++++++++++++++++++++------------
 net/bluetooth/sco.c | 20 +++++++++++----
 2 files changed, 59 insertions(+), 21 deletions(-)

-- 
2.52.0


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

* [PATCH v2 1/2] Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls
  2026-06-01 11:19 [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths SeungJu Cheon
@ 2026-06-01 11:19 ` SeungJu Cheon
  2026-06-01 11:19 ` [PATCH v2 2/2] Bluetooth: SCO: Fix data-race on sco_pi fields in sco_connect SeungJu Cheon
  2026-06-02 17:20 ` [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths patchwork-bot+bluetooth
  2 siblings, 0 replies; 4+ messages in thread
From: SeungJu Cheon @ 2026-06-01 11:19 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, me, skhan, linux-kernel-mentees,
	SeungJu Cheon

iso_connect_bis(), iso_connect_cis(), iso_listen_bis(), and
iso_conn_big_sync() call hci_get_route() using iso_pi(sk)->dst,
iso_pi(sk)->src, and iso_pi(sk)->src_type without holding lock_sock().

These fields may be modified concurrently by connect() or setsockopt()
on the same socket, resulting in data-races reported by KCSAN.

Fix this by snapshotting the required fields under lock_sock() before
calling hci_get_route().

BUG: KCSAN: data-race in memcmp+0x45/0xb0

race at unknown origin, with read to 0xffff8880122135cf of 1 bytes
by task 333 on cpu 1:
 memcmp+0x45/0xb0
 hci_get_route+0x27e/0x490
 iso_connect_cis+0x4c/0xa10
 iso_sock_connect+0x60e/0xb30
 __sys_connect_file+0xbd/0xe0
 __sys_connect+0xe0/0x110
 __x64_sys_connect+0x40/0x50
 x64_sys_call+0xcad/0x1c60
 do_syscall_64+0x133/0x590
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

Fixes: 241f51931c35 ("Bluetooth: ISO: Avoid circular locking dependency")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
---
 net/bluetooth/iso.c | 60 +++++++++++++++++++++++++++++++++------------
 1 file changed, 44 insertions(+), 16 deletions(-)

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index d7af617cda45..b4196ccaf766 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -337,12 +337,20 @@ static int iso_connect_bis(struct sock *sk)
 	struct iso_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_dev  *hdev;
+	bdaddr_t src, dst;
+	u8 src_type, bc_sid;
 	int err;
 
-	BT_DBG("%pMR (SID 0x%2.2x)", &iso_pi(sk)->src, iso_pi(sk)->bc_sid);
+	lock_sock(sk);
+	bacpy(&src, &iso_pi(sk)->src);
+	bacpy(&dst, &iso_pi(sk)->dst);
+	src_type = iso_pi(sk)->src_type;
+	bc_sid = iso_pi(sk)->bc_sid;
+	release_sock(sk);
 
-	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
-			     iso_pi(sk)->src_type);
+	BT_DBG("%pMR (SID 0x%2.2x)", &src, bc_sid);
+
+	hdev = hci_get_route(&dst, &src, src_type);
 	if (!hdev)
 		return -EHOSTUNREACH;
 
@@ -430,12 +438,19 @@ static int iso_connect_cis(struct sock *sk)
 	struct iso_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_dev  *hdev;
+	bdaddr_t src, dst;
+	u8 src_type;
 	int err;
 
-	BT_DBG("%pMR -> %pMR", &iso_pi(sk)->src, &iso_pi(sk)->dst);
+	lock_sock(sk);
+	bacpy(&src, &iso_pi(sk)->src);
+	bacpy(&dst, &iso_pi(sk)->dst);
+	src_type = iso_pi(sk)->src_type;
+	release_sock(sk);
+
+	BT_DBG("%pMR -> %pMR", &src, &dst);
 
-	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
-			     iso_pi(sk)->src_type);
+	hdev = hci_get_route(&dst, &src, src_type);
 	if (!hdev)
 		return -EHOSTUNREACH;
 
@@ -1208,18 +1223,25 @@ static int iso_sock_connect(struct socket *sock, struct sockaddr_unsized *addr,
 
 static int iso_listen_bis(struct sock *sk)
 {
-	struct hci_dev *hdev;
-	int err = 0;
 	struct iso_conn *conn;
 	struct hci_conn *hcon;
+	struct hci_dev *hdev;
+	bdaddr_t src, dst;
+	u8 src_type, bc_sid;
+	int err = 0;
+
+	lock_sock(sk);
+	bacpy(&src, &iso_pi(sk)->src);
+	bacpy(&dst, &iso_pi(sk)->dst);
+	src_type = iso_pi(sk)->src_type;
+	bc_sid = iso_pi(sk)->bc_sid;
+	release_sock(sk);
 
-	BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &iso_pi(sk)->src,
-	       &iso_pi(sk)->dst, iso_pi(sk)->bc_sid);
+	BT_DBG("%pMR -> %pMR (SID 0x%2.2x)", &src, &dst, bc_sid);
 
 	write_lock(&iso_sk_list.lock);
 
-	if (__iso_get_sock_listen_by_sid(&iso_pi(sk)->src, &iso_pi(sk)->dst,
-					 iso_pi(sk)->bc_sid))
+	if (__iso_get_sock_listen_by_sid(&src, &dst, bc_sid))
 		err = -EADDRINUSE;
 
 	write_unlock(&iso_sk_list.lock);
@@ -1227,8 +1249,7 @@ static int iso_listen_bis(struct sock *sk)
 	if (err)
 		return err;
 
-	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
-			     iso_pi(sk)->src_type);
+	hdev = hci_get_route(&dst, &src, src_type);
 	if (!hdev)
 		return -EHOSTUNREACH;
 
@@ -1564,9 +1585,16 @@ static void iso_conn_big_sync(struct sock *sk)
 {
 	int err;
 	struct hci_dev *hdev;
+	bdaddr_t src, dst;
+	u8 src_type;
+
+	lock_sock(sk);
+	bacpy(&src, &iso_pi(sk)->src);
+	bacpy(&dst, &iso_pi(sk)->dst);
+	src_type = iso_pi(sk)->src_type;
+	release_sock(sk);
 
-	hdev = hci_get_route(&iso_pi(sk)->dst, &iso_pi(sk)->src,
-			     iso_pi(sk)->src_type);
+	hdev = hci_get_route(&dst, &src, src_type);
 
 	if (!hdev)
 		return;
-- 
2.52.0


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

* [PATCH v2 2/2] Bluetooth: SCO: Fix data-race on sco_pi fields in sco_connect
  2026-06-01 11:19 [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths SeungJu Cheon
  2026-06-01 11:19 ` [PATCH v2 1/2] Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls SeungJu Cheon
@ 2026-06-01 11:19 ` SeungJu Cheon
  2026-06-02 17:20 ` [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths patchwork-bot+bluetooth
  2 siblings, 0 replies; 4+ messages in thread
From: SeungJu Cheon @ 2026-06-01 11:19 UTC (permalink / raw)
  To: marcel, luiz.dentz
  Cc: linux-bluetooth, linux-kernel, me, skhan, linux-kernel-mentees,
	SeungJu Cheon

sco_sock_connect() copies the destination address into sco_pi(sk)->dst
under lock_sock(), then releases the lock and calls sco_connect(),
which reads dst, src, setting, and codec without holding lock_sock() in
hci_get_route() and hci_connect_sco().

These fields may be modified concurrently by connect(), bind(), or
setsockopt() on the same socket, resulting in data-races reported by
KCSAN.

Fix this by snapshotting dst, src, setting, and codec under lock_sock()
at the start of sco_connect() before passing them to hci_get_route()
and hci_connect_sco().

BUG: KCSAN: data-race in memcmp+0x45/0xb0

race at unknown origin, with read to 0xffff88800e6b0dd0 of 1 bytes
by task 315 on cpu 0:
 memcmp+0x45/0xb0
 hci_connect_acl+0x1b7/0x6b0
 hci_connect_sco+0x4d/0xb30
 sco_sock_connect+0x27b/0xd60
 __sys_connect_file+0xbd/0xe0
 __sys_connect+0xe0/0x110
 __x64_sys_connect+0x40/0x50
 x64_sys_call+0xcad/0x1c60
 do_syscall_64+0x133/0x590
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

Fixes: 9a8ec9e8ebb5 ("Bluetooth: SCO: Fix possible circular locking dependency on sco_connect_cfm")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
---
 net/bluetooth/sco.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index f1799c6a6f87..140869e5b2df 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -312,11 +312,21 @@ static int sco_connect(struct sock *sk)
 	struct sco_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_dev  *hdev;
+	bdaddr_t src, dst;
+	struct bt_codec codec;
+	__u16 setting;
 	int err, type;
 
-	BT_DBG("%pMR -> %pMR", &sco_pi(sk)->src, &sco_pi(sk)->dst);
+	lock_sock(sk);
+	bacpy(&src, &sco_pi(sk)->src);
+	bacpy(&dst, &sco_pi(sk)->dst);
+	setting = sco_pi(sk)->setting;
+	codec = sco_pi(sk)->codec;
+	release_sock(sk);
+
+	BT_DBG("%pMR -> %pMR", &src, &dst);
 
-	hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src, BDADDR_BREDR);
+	hdev = hci_get_route(&dst, &src, BDADDR_BREDR);
 	if (!hdev)
 		return -EHOSTUNREACH;
 
@@ -327,7 +337,7 @@ static int sco_connect(struct sock *sk)
 	else
 		type = SCO_LINK;
 
-	switch (sco_pi(sk)->setting & SCO_AIRMODE_MASK) {
+	switch (setting & SCO_AIRMODE_MASK) {
 	case SCO_AIRMODE_TRANSP:
 		if (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev)) {
 			err = -EOPNOTSUPP;
@@ -336,8 +346,8 @@ static int sco_connect(struct sock *sk)
 		break;
 	}
 
-	hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst,
-			       sco_pi(sk)->setting, &sco_pi(sk)->codec,
+	hcon = hci_connect_sco(hdev, type, &dst,
+			       setting, &codec,
 			       READ_ONCE(sk->sk_sndtimeo));
 	if (IS_ERR(hcon)) {
 		err = PTR_ERR(hcon);
-- 
2.52.0


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

* Re: [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths
  2026-06-01 11:19 [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths SeungJu Cheon
  2026-06-01 11:19 ` [PATCH v2 1/2] Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls SeungJu Cheon
  2026-06-01 11:19 ` [PATCH v2 2/2] Bluetooth: SCO: Fix data-race on sco_pi fields in sco_connect SeungJu Cheon
@ 2026-06-02 17:20 ` patchwork-bot+bluetooth
  2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+bluetooth @ 2026-06-02 17:20 UTC (permalink / raw)
  To: SeungJu Cheon
  Cc: marcel, luiz.dentz, linux-bluetooth, linux-kernel, me, skhan,
	linux-kernel-mentees

Hello:

This series was applied to bluetooth/bluetooth-next.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Mon,  1 Jun 2026 20:19:06 +0900 you wrote:
> The connect paths read socket address and config fields without
> lock_sock() and pass them to hci_get_route() and hci_connect_*(),
> while connect()/bind()/setsockopt() can update them concurrently.
> 
> Patch 1 covers ISO (iso_connect_bis/cis, iso_listen_bis,
> iso_conn_big_sync), patch 2 covers SCO (sco_connect).
> 
> [...]

Here is the summary with links:
  - [v2,1/2] Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls
    https://git.kernel.org/bluetooth/bluetooth-next/c/961ea93b3ceb
  - [v2,2/2] Bluetooth: SCO: Fix data-race on sco_pi fields in sco_connect
    https://git.kernel.org/bluetooth/bluetooth-next/c/4a17208f1b99

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2026-06-02 17:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-01 11:19 [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths SeungJu Cheon
2026-06-01 11:19 ` [PATCH v2 1/2] Bluetooth: ISO: Fix data-race on iso_pi fields in hci_get_route calls SeungJu Cheon
2026-06-01 11:19 ` [PATCH v2 2/2] Bluetooth: SCO: Fix data-race on sco_pi fields in sco_connect SeungJu Cheon
2026-06-02 17:20 ` [PATCH v2 0/2] Bluetooth: Fix data-races in SCO/ISO connect paths patchwork-bot+bluetooth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox