Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: sco: Fix a race condition in sco_sock_timeout()
@ 2026-06-24 21:33 Sungwoo Kim
  2026-06-24 22:32 ` Sungwoo Kim
  2026-06-25  0:22 ` bluez.test.bot
  0 siblings, 2 replies; 3+ messages in thread
From: Sungwoo Kim @ 2026-06-24 21:33 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Sungwoo Kim, Dave Tian, Luiz Augusto von Dentz, linux-bluetooth,
	linux-kernel

sco_sock_timeout() runs asynchronously and lock_sock(sk). If the socket
is closing while the timer is running, it holds the same lock
(lock_sock(sk)) twice, leading to a deadlock.

CPU 0                      CPU 1
====================       ======================
sco_sock_close()
                           sco_sock_timeout()
lock_sock(sk) // <-- LOCK
  __sco_sock_close()
    sco_chan_del()
      sco_conn_put()
	      sco_conn_free()
	        disable_delayed_work_sync()
	                           lock(sk) // <-- SAME LOCK

Fix this by moving disable_delayed_work_sync() outside of lock_sock(sk),
ensuring that no lock_sock(sk) is held before sco_sock_timeout().

Lockdep splat:

WARNING: possible circular locking dependency detected
6.13.0-rc4 #7 Not tainted

syz-executor292/9514 is trying to acquire lock:
ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: rcu_lock_acquire sect/v6.13-rc4/./include/linux/rcupdate.h:337 [inline]
ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: rcu_read_lock sect/v6.13-rc4/./include/linux/rcupdate.h:849 [inline]
ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: start_flush_work sect/v6.13-rc4/kernel/workqueue.c:4137 [inline]
ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: __flush_work+0xd1/0xc40 sect/v6.13-rc4/kernel/workqueue.c:4195

but task is already holding lock:
ffff88807db3a258 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at: lock_sock sect/v6.13-rc4/./include/net/sock.h:1623 [inline]
ffff88807db3a258 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at: sco_sock_close+0x25/0x100 sect/v6.13-rc4/net/bluetooth/sco.c:524

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #1 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}:
       lock_acquire+0x1c4/0x520 sect/v6.13-rc4/kernel/locking/lockdep.c:5849
       lock_sock_nested+0x48/0x130 sect/v6.13-rc4/net/core/sock.c:3622
       lock_sock sect/v6.13-rc4/./include/net/sock.h:1623 [inline]
       sco_sock_timeout+0xbe/0x270 sect/v6.13-rc4/net/bluetooth/sco.c:158
       process_one_work sect/v6.13-rc4/kernel/workqueue.c:3229 [inline]
       process_scheduled_works+0xa99/0x18f0 sect/v6.13-rc4/kernel/workqueue.c:3310
       worker_thread+0x8a9/0xd80 sect/v6.13-rc4/kernel/workqueue.c:3391
       kthread+0x2c6/0x360 sect/v6.13-rc4/kernel/kthread.c:389
       ret_from_fork+0x4e/0x80 sect/v6.13-rc4/arch/x86/kernel/process.c:147
       ret_from_fork_asm+0x1a/0x30 sect/v6.13-rc4/arch/x86/entry/entry_64.S:244

-> #0 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}:
       check_prev_add sect/v6.13-rc4/kernel/locking/lockdep.c:3161 [inline]
       check_prevs_add sect/v6.13-rc4/kernel/locking/lockdep.c:3280 [inline]
       validate_chain+0x1888/0x5760 sect/v6.13-rc4/kernel/locking/lockdep.c:3904
       __lock_acquire+0x13b4/0x2120 sect/v6.13-rc4/kernel/locking/lockdep.c:5226
       lock_acquire+0x1c4/0x520 sect/v6.13-rc4/kernel/locking/lockdep.c:5849
       touch_work_lockdep_map sect/v6.13-rc4/kernel/workqueue.c:3909 [inline]
       start_flush_work sect/v6.13-rc4/kernel/workqueue.c:4163 [inline]
       __flush_work+0x70f/0xc40 sect/v6.13-rc4/kernel/workqueue.c:4195
       __cancel_work_sync sect/v6.13-rc4/kernel/workqueue.c:4351 [inline]
       disable_delayed_work_sync+0xbb/0xf0 sect/v6.13-rc4/kernel/workqueue.c:4514
       sco_conn_free sect/v6.13-rc4/net/bluetooth/sco.c:95 [inline]
       kref_put sect/v6.13-rc4/./include/linux/kref.h:65 [inline]
       sco_conn_put+0x18f/0x270 sect/v6.13-rc4/net/bluetooth/sco.c:107
       sco_chan_del+0xe2/0x210 sect/v6.13-rc4/net/bluetooth/sco.c:236
       sco_sock_close+0x8f/0x100 sect/v6.13-rc4/net/bluetooth/sco.c:526
       sco_sock_release+0x62/0x2d0 sect/v6.13-rc4/net/bluetooth/sco.c:1300
       __sock_release+0xe1/0x2d0 sect/v6.13-rc4/net/socket.c:640
       sock_close+0x1c/0x30 sect/v6.13-rc4/net/socket.c:1408
       __fput+0x2bd/0xa80 sect/v6.13-rc4/fs/file_table.c:450
       __fput_sync+0x15e/0x1c0 sect/v6.13-rc4/fs/file_table.c:535
       __do_sys_close sect/v6.13-rc4/fs/open.c:1554 [inline]
       __se_sys_close sect/v6.13-rc4/fs/open.c:1539 [inline]
       __x64_sys_close+0x93/0x120 sect/v6.13-rc4/fs/open.c:1539
       do_syscall_x64 sect/v6.13-rc4/arch/x86/entry/common.c:52 [inline]
       do_syscall_64+0xee/0x210 sect/v6.13-rc4/arch/x86/entry/common.c:83
       entry_SYSCALL_64_after_hwframe+0x77/0x7f

Fixes: e6720779ae61 ("Bluetooth: SCO: Use kref to track lifetime of sco_conn")
Acked-by: Dave Tian <daveti@purdue.edu>
Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
---
 net/bluetooth/sco.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index fcc597be5bbd..c05f79b7aa31 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -570,10 +570,23 @@ static void __sco_sock_close(struct sock *sk)
 /* Must be called on unlocked socket. */
 static void sco_sock_close(struct sock *sk)
 {
+	struct sco_conn *conn;
+
+	lock_sock(sk);
+	conn = sco_pi(sk)->conn;
+	if (conn)
+		sco_conn_hold(conn);
+	release_sock(sk);
+
+	if (conn)
+		disable_delayed_work_sync(&conn->timeout_work);
+
 	lock_sock(sk);
-	sco_sock_clear_timer(sk);
 	__sco_sock_close(sk);
 	release_sock(sk);
+
+	if (conn)
+		sco_conn_put(conn);
 }
 
 static void sco_sock_init(struct sock *sk, struct sock *parent)
-- 
2.47.3


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

* Re: [PATCH] Bluetooth: sco: Fix a race condition in sco_sock_timeout()
  2026-06-24 21:33 [PATCH] Bluetooth: sco: Fix a race condition in sco_sock_timeout() Sungwoo Kim
@ 2026-06-24 22:32 ` Sungwoo Kim
  2026-06-25  0:22 ` bluez.test.bot
  1 sibling, 0 replies; 3+ messages in thread
From: Sungwoo Kim @ 2026-06-24 22:32 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: Dave Tian, Luiz Augusto von Dentz, linux-bluetooth, linux-kernel

On Wed, Jun 24, 2026 at 5:36 PM Sungwoo Kim <iam@sung-woo.kim> wrote:
>
> sco_sock_timeout() runs asynchronously and lock_sock(sk). If the socket
> is closing while the timer is running, it holds the same lock
> (lock_sock(sk)) twice, leading to a deadlock.
>
> CPU 0                      CPU 1
> ====================       ======================
> sco_sock_close()
>                            sco_sock_timeout()
> lock_sock(sk) // <-- LOCK
>   __sco_sock_close()
>     sco_chan_del()
>       sco_conn_put()
>               sco_conn_free()
>                 disable_delayed_work_sync()
>                                    lock(sk) // <-- SAME LOCK
>
> Fix this by moving disable_delayed_work_sync() outside of lock_sock(sk),
> ensuring that no lock_sock(sk) is held before sco_sock_timeout().
>
> Lockdep splat:
>
> WARNING: possible circular locking dependency detected
> 6.13.0-rc4 #7 Not tainted
>
> syz-executor292/9514 is trying to acquire lock:
> ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: rcu_lock_acquire sect/v6.13-rc4/./include/linux/rcupdate.h:337 [inline]
> ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: rcu_read_lock sect/v6.13-rc4/./include/linux/rcupdate.h:849 [inline]
> ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: start_flush_work sect/v6.13-rc4/kernel/workqueue.c:4137 [inline]
> ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: __flush_work+0xd1/0xc40 sect/v6.13-rc4/kernel/workqueue.c:4195
>
> but task is already holding lock:
> ffff88807db3a258 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at: lock_sock sect/v6.13-rc4/./include/net/sock.h:1623 [inline]
> ffff88807db3a258 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at: sco_sock_close+0x25/0x100 sect/v6.13-rc4/net/bluetooth/sco.c:524
>
> which lock already depends on the new lock.
>
> the existing dependency chain (in reverse order) is:
>
> -> #1 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}:
>        lock_acquire+0x1c4/0x520 sect/v6.13-rc4/kernel/locking/lockdep.c:5849
>        lock_sock_nested+0x48/0x130 sect/v6.13-rc4/net/core/sock.c:3622
>        lock_sock sect/v6.13-rc4/./include/net/sock.h:1623 [inline]
>        sco_sock_timeout+0xbe/0x270 sect/v6.13-rc4/net/bluetooth/sco.c:158
>        process_one_work sect/v6.13-rc4/kernel/workqueue.c:3229 [inline]
>        process_scheduled_works+0xa99/0x18f0 sect/v6.13-rc4/kernel/workqueue.c:3310
>        worker_thread+0x8a9/0xd80 sect/v6.13-rc4/kernel/workqueue.c:3391
>        kthread+0x2c6/0x360 sect/v6.13-rc4/kernel/kthread.c:389
>        ret_from_fork+0x4e/0x80 sect/v6.13-rc4/arch/x86/kernel/process.c:147
>        ret_from_fork_asm+0x1a/0x30 sect/v6.13-rc4/arch/x86/entry/entry_64.S:244
>
> -> #0 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}:
>        check_prev_add sect/v6.13-rc4/kernel/locking/lockdep.c:3161 [inline]
>        check_prevs_add sect/v6.13-rc4/kernel/locking/lockdep.c:3280 [inline]
>        validate_chain+0x1888/0x5760 sect/v6.13-rc4/kernel/locking/lockdep.c:3904
>        __lock_acquire+0x13b4/0x2120 sect/v6.13-rc4/kernel/locking/lockdep.c:5226
>        lock_acquire+0x1c4/0x520 sect/v6.13-rc4/kernel/locking/lockdep.c:5849
>        touch_work_lockdep_map sect/v6.13-rc4/kernel/workqueue.c:3909 [inline]
>        start_flush_work sect/v6.13-rc4/kernel/workqueue.c:4163 [inline]
>        __flush_work+0x70f/0xc40 sect/v6.13-rc4/kernel/workqueue.c:4195
>        __cancel_work_sync sect/v6.13-rc4/kernel/workqueue.c:4351 [inline]
>        disable_delayed_work_sync+0xbb/0xf0 sect/v6.13-rc4/kernel/workqueue.c:4514
>        sco_conn_free sect/v6.13-rc4/net/bluetooth/sco.c:95 [inline]
>        kref_put sect/v6.13-rc4/./include/linux/kref.h:65 [inline]
>        sco_conn_put+0x18f/0x270 sect/v6.13-rc4/net/bluetooth/sco.c:107
>        sco_chan_del+0xe2/0x210 sect/v6.13-rc4/net/bluetooth/sco.c:236
>        sco_sock_close+0x8f/0x100 sect/v6.13-rc4/net/bluetooth/sco.c:526
>        sco_sock_release+0x62/0x2d0 sect/v6.13-rc4/net/bluetooth/sco.c:1300
>        __sock_release+0xe1/0x2d0 sect/v6.13-rc4/net/socket.c:640
>        sock_close+0x1c/0x30 sect/v6.13-rc4/net/socket.c:1408
>        __fput+0x2bd/0xa80 sect/v6.13-rc4/fs/file_table.c:450
>        __fput_sync+0x15e/0x1c0 sect/v6.13-rc4/fs/file_table.c:535
>        __do_sys_close sect/v6.13-rc4/fs/open.c:1554 [inline]
>        __se_sys_close sect/v6.13-rc4/fs/open.c:1539 [inline]
>        __x64_sys_close+0x93/0x120 sect/v6.13-rc4/fs/open.c:1539
>        do_syscall_x64 sect/v6.13-rc4/arch/x86/entry/common.c:52 [inline]
>        do_syscall_64+0xee/0x210 sect/v6.13-rc4/arch/x86/entry/common.c:83
>        entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
> Fixes: e6720779ae61 ("Bluetooth: SCO: Use kref to track lifetime of sco_conn")
> Acked-by: Dave Tian <daveti@purdue.edu>
> Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
> ---
>  net/bluetooth/sco.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
> index fcc597be5bbd..c05f79b7aa31 100644
> --- a/net/bluetooth/sco.c
> +++ b/net/bluetooth/sco.c
> @@ -570,10 +570,23 @@ static void __sco_sock_close(struct sock *sk)
>  /* Must be called on unlocked socket. */
>  static void sco_sock_close(struct sock *sk)
>  {
> +       struct sco_conn *conn;
> +
> +       lock_sock(sk);
> +       conn = sco_pi(sk)->conn;
> +       if (conn)
> +               sco_conn_hold(conn);
> +       release_sock(sk);
> +
> +       if (conn)
> +               disable_delayed_work_sync(&conn->timeout_work);
> +
>         lock_sock(sk);
> -       sco_sock_clear_timer(sk);
>         __sco_sock_close(sk);
>         release_sock(sk);
> +
> +       if (conn)
> +               sco_conn_put(conn);
>  }
>
>  static void sco_sock_init(struct sock *sk, struct sock *parent)
> --
> 2.47.3
>

Although Sashiko [1] pointed out some interesting bugs in this patch,
they appear to be pre-existing.
I can send another patch for this.

[1] https://sashiko.dev/#/patchset/20260624213304.1460149-2-iam%40sung-woo.kim

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

* RE: Bluetooth: sco: Fix a race condition in sco_sock_timeout()
  2026-06-24 21:33 [PATCH] Bluetooth: sco: Fix a race condition in sco_sock_timeout() Sungwoo Kim
  2026-06-24 22:32 ` Sungwoo Kim
@ 2026-06-25  0:22 ` bluez.test.bot
  1 sibling, 0 replies; 3+ messages in thread
From: bluez.test.bot @ 2026-06-25  0:22 UTC (permalink / raw)
  To: linux-bluetooth, iam

[-- Attachment #1: Type: text/plain, Size: 3865 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=1116158

---Test result---

Test Summary:
CheckPatch                    FAIL      1.08 seconds
VerifyFixes                   PASS      0.21 seconds
VerifySignedoff               PASS      0.20 seconds
GitLint                       FAIL      0.45 seconds
SubjectPrefix                 PASS      0.18 seconds
BuildKernel                   PASS      28.74 seconds
CheckAllWarning               PASS      29.24 seconds
CheckSparse                   PASS      28.03 seconds
BuildKernel32                 PASS      26.10 seconds
CheckKernelLLVM               SKIP      0.00 seconds
TestRunnerSetup               PASS      491.15 seconds
TestRunner_sco-tester         PASS      31.94 seconds
IncrementalBuild              PASS      26.32 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
Bluetooth: sco: Fix a race condition in sco_sock_timeout()
WARNING: Prefer a maximum 75 chars per line (possible unwrapped commit description?)
#109: 
ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: rcu_lock_acquire sect/v6.13-rc4/./include/linux/rcupdate.h:337 [inline]

total: 0 errors, 1 warnings, 0 checks, 24 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/patch/14643876.patch has style problems, please review.

NOTE: Ignored message types: UNKNOWN_COMMIT_ID

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.


##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
Bluetooth: sco: Fix a race condition in sco_sock_timeout()

15: B3 Line contains hard tab characters (\t): "	      sco_conn_free()"
16: B3 Line contains hard tab characters (\t): "	        disable_delayed_work_sync()"
17: B3 Line contains hard tab characters (\t): "	                           lock(sk) // <-- SAME LOCK"
28: B1 Line exceeds max length (155>80): "ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: rcu_lock_acquire sect/v6.13-rc4/./include/linux/rcupdate.h:337 [inline]"
29: B1 Line exceeds max length (152>80): "ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: rcu_read_lock sect/v6.13-rc4/./include/linux/rcupdate.h:849 [inline]"
30: B1 Line exceeds max length (148>80): "ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: start_flush_work sect/v6.13-rc4/kernel/workqueue.c:4137 [inline]"
31: B1 Line exceeds max length (146>80): "ffff8881115d5070 ((work_completion)(&(&conn->timeout_work)->work)){+.+.}-{0:0}, at: __flush_work+0xd1/0xc40 sect/v6.13-rc4/kernel/workqueue.c:4195"
34: B1 Line exceeds max length (128>80): "ffff88807db3a258 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at: lock_sock sect/v6.13-rc4/./include/net/sock.h:1623 [inline]"
35: B1 Line exceeds max length (133>80): "ffff88807db3a258 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at: sco_sock_close+0x25/0x100 sect/v6.13-rc4/net/bluetooth/sco.c:524"
47: B1 Line exceeds max length (82>80): "       process_scheduled_works+0xa99/0x18f0 sect/v6.13-rc4/kernel/workqueue.c:3310"
63: B1 Line exceeds max length (81>80): "       disable_delayed_work_sync+0xbb/0xf0 sect/v6.13-rc4/kernel/workqueue.c:4514"
##############################
Test: CheckKernelLLVM - SKIP
Desc: Build kernel with LLVM + context analysis
Output:
Clang not found


https://github.com/bluez/bluetooth-next/pull/349

---
Regards,
Linux Bluetooth


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

end of thread, other threads:[~2026-06-25  0:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-24 21:33 [PATCH] Bluetooth: sco: Fix a race condition in sco_sock_timeout() Sungwoo Kim
2026-06-24 22:32 ` Sungwoo Kim
2026-06-25  0:22 ` bluez.test.bot

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