* [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