mirror of https://lore.kernel.org/lkml/
 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-26 11:16 ` patchwork-bot+bluetooth
  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	[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-26 11:16 ` patchwork-bot+bluetooth
  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: [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-26 11:16 ` patchwork-bot+bluetooth
  1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+bluetooth @ 2026-06-26 11:16 UTC (permalink / raw)
  To: Sungwoo Kim
  Cc: marcel, luiz.dentz, daveti, luiz.von.dentz, linux-bluetooth,
	linux-kernel

Hello:

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

On Wed, 24 Jun 2026 17:33:04 -0400 you 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
> 
> [...]

Here is the summary with links:
  - Bluetooth: sco: Fix a race condition in sco_sock_timeout()
    https://git.kernel.org/bluetooth/bluetooth-next/c/cddcc54a7afe

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] 3+ messages in thread

end of thread, other threads:[~2026-06-26 11:17 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-26 11:16 ` 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

all inboxes | Powered by JetHome®