The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [syzbot] [bluetooth?] KASAN: null-ptr-deref Read in l2cap_chan_hold_unless_zero
@ 2026-07-20 23:56 syzbot
  2026-07-21  4:26 ` Hillf Danton
  2026-08-08 12:00 ` Forwarded: [PATCH] Bluetooth: L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chan syzbot
  0 siblings, 2 replies; 4+ messages in thread
From: syzbot @ 2026-07-20 23:56 UTC (permalink / raw)
  To: linux-bluetooth, linux-kernel, luiz.dentz, marcel, syzkaller-bugs

Hello,

syzbot found the following issue on:

HEAD commit:    e22254e9ddd8 Merge tag 'xfs-fixes-7.2-rc4' of git://git.ke..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=13d46789580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=48ef5c5c0f192153
dashboard link: https://syzkaller.appspot.com/bug?extid=e6382a2f53f5fc7453ac
compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=17b434b9580000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=17d46789580000

Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/d900f083ada3/non_bootable_disk-e22254e9.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/c69a30d7d78f/vmlinux-e22254e9.xz
kernel image: https://storage.googleapis.com/syzbot-assets/f15a346cc7e1/bzImage-e22254e9.xz

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+e6382a2f53f5fc7453ac@syzkaller.appspotmail.com

==================================================================
BUG: KASAN: null-ptr-deref in instrument_atomic_read include/linux/instrumented.h:82 [inline]
BUG: KASAN: null-ptr-deref in atomic_read include/linux/atomic/atomic-instrumented.h:32 [inline]
BUG: KASAN: null-ptr-deref in refcount_read include/linux/refcount.h:170 [inline]
BUG: KASAN: null-ptr-deref in __refcount_add_not_zero include/linux/refcount.h:176 [inline]
BUG: KASAN: null-ptr-deref in __refcount_inc_not_zero include/linux/refcount.h:317 [inline]
BUG: KASAN: null-ptr-deref in refcount_inc_not_zero include/linux/refcount.h:335 [inline]
BUG: KASAN: null-ptr-deref in kref_get_unless_zero include/linux/kref.h:133 [inline]
BUG: KASAN: null-ptr-deref in l2cap_chan_hold_unless_zero+0x80/0x290 net/bluetooth/l2cap_core.c:511
Read of size 4 at addr 0000000000000008 by task syz.0.158/6397

CPU: 2 UID: 0 PID: 6397 Comm: syz.0.158 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
 kasan_report+0xdf/0x1c0 mm/kasan/report.c:595
 check_region_inline mm/kasan/generic.c:186 [inline]
 kasan_check_range+0x10f/0x1e0 mm/kasan/generic.c:200
 instrument_atomic_read include/linux/instrumented.h:82 [inline]
 atomic_read include/linux/atomic/atomic-instrumented.h:32 [inline]
 refcount_read include/linux/refcount.h:170 [inline]
 __refcount_add_not_zero include/linux/refcount.h:176 [inline]
 __refcount_inc_not_zero include/linux/refcount.h:317 [inline]
 refcount_inc_not_zero include/linux/refcount.h:335 [inline]
 kref_get_unless_zero include/linux/kref.h:133 [inline]
 l2cap_chan_hold_unless_zero+0x80/0x290 net/bluetooth/l2cap_core.c:511
 l2cap_sock_cleanup_listen+0x8a/0x4d0 net/bluetooth/l2cap_sock.c:1535
 l2cap_sock_release+0x69/0x280 net/bluetooth/l2cap_sock.c:1480
 __sock_release+0xb3/0x260 net/socket.c:710
 sock_close+0x1c/0x30 net/socket.c:1501
 __fput+0x3ff/0xb50 fs/file_table.c:512
 task_work_run+0x150/0x240 kernel/task_work.c:233
 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
 __exit_to_user_mode_loop kernel/entry/common.c:70 [inline]
 exit_to_user_mode_loop+0x1d8/0x6f0 kernel/entry/common.c:101
 __exit_to_user_mode_prepare include/linux/irq-entry-common.h:207 [inline]
 syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:230 [inline]
 syscall_exit_to_user_mode include/linux/entry-common.h:318 [inline]
 do_syscall_64+0x666/0x870 arch/x86/entry/syscall_64.c:100
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f3758d9de99
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fff659f88f8 EFLAGS: 00000246 ORIG_RAX: 00000000000001b4
RAX: 0000000000000000 RBX: 00007f3759027da0 RCX: 00007f3758d9de99
RDX: 0000000000000000 RSI: 000000000000001e RDI: 0000000000000003
RBP: 00007f3759027da0 R08: 0000000000000006 R09: 0000000000000000
R10: 00007f3759027cb0 R11: 0000000000000246 R12: 0000000000046482
R13: 00007f375902609c R14: 00000000000461ac R15: 00007f3759026090
 </TASK>
==================================================================


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title

If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.

If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)

If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report

If you want to undo deduplication, reply with:
#syz undup

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

* Re: [syzbot] [bluetooth?] KASAN: null-ptr-deref Read in l2cap_chan_hold_unless_zero
  2026-07-20 23:56 [syzbot] [bluetooth?] KASAN: null-ptr-deref Read in l2cap_chan_hold_unless_zero syzbot
@ 2026-07-21  4:26 ` Hillf Danton
  2026-07-21  4:57   ` syzbot
  2026-08-08 12:00 ` Forwarded: [PATCH] Bluetooth: L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chan syzbot
  1 sibling, 1 reply; 4+ messages in thread
From: Hillf Danton @ 2026-07-21  4:26 UTC (permalink / raw)
  To: syzbot; +Cc: linux-kernel, syzkaller-bugs

> Date: Mon, 20 Jul 2026 16:56:27 -0700
> Hello,
> 
> syzbot found the following issue on:
> 
> HEAD commit:    e22254e9ddd8 Merge tag 'xfs-fixes-7.2-rc4' of git://git.ke..
> git tree:       upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=13d46789580000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=48ef5c5c0f192153
> dashboard link: https://syzkaller.appspot.com/bug?extid=e6382a2f53f5fc7453ac
> compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
> syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=17b434b9580000
> C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=17d46789580000

#syz test

--- x/net/bluetooth/l2cap_sock.c
+++ y/net/bluetooth/l2cap_sock.c
@@ -1532,7 +1532,9 @@ static void l2cap_sock_cleanup_listen(st
 		struct l2cap_chan *chan;
 
 		lock_sock_nested(sk, L2CAP_NESTING_NORMAL);
-		chan = l2cap_chan_hold_unless_zero(l2cap_pi(sk)->chan);
+		chan = l2cap_pi(sk)->chan;
+		if (chan)
+			chan = l2cap_chan_hold_unless_zero(l2cap_pi(sk)->chan);
 		release_sock(sk);
 		if (!chan) {
 			/* l2cap_conn_del() already tearing this child down */
--

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

* Re: [syzbot] [bluetooth?] KASAN: null-ptr-deref Read in l2cap_chan_hold_unless_zero
  2026-07-21  4:26 ` Hillf Danton
@ 2026-07-21  4:57   ` syzbot
  0 siblings, 0 replies; 4+ messages in thread
From: syzbot @ 2026-07-21  4:57 UTC (permalink / raw)
  To: hdanton, linux-kernel, syzkaller-bugs

Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-by: syzbot+e6382a2f53f5fc7453ac@syzkaller.appspotmail.com
Tested-by: syzbot+e6382a2f53f5fc7453ac@syzkaller.appspotmail.com

Tested on:

commit:         b95f03f0 Merge tag 'mm-hotfixes-stable-2026-07-20-11-3..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=123b8ab9580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=48ef5c5c0f192153
dashboard link: https://syzkaller.appspot.com/bug?extid=e6382a2f53f5fc7453ac
compiler:       gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
patch:          https://syzkaller.appspot.com/x/patch.diff?x=13b912b9580000

Note: testing is done by a robot and is best-effort only.

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

* Forwarded: [PATCH] Bluetooth: L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chan
  2026-07-20 23:56 [syzbot] [bluetooth?] KASAN: null-ptr-deref Read in l2cap_chan_hold_unless_zero syzbot
  2026-07-21  4:26 ` Hillf Danton
@ 2026-08-08 12:00 ` syzbot
  1 sibling, 0 replies; 4+ messages in thread
From: syzbot @ 2026-08-08 12:00 UTC (permalink / raw)
  To: linux-kernel

For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org.

***

Subject: [PATCH] Bluetooth: L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chan
Author: pav@iki.fi

For L2CAP sockets without owning sk->sk_socket, reading
l2cap_pi(sk)->chan may race against concurrent l2cap_sock_kill() ->
l2cap_sock_put_chan().  This excludes simultaneous proto_ops callbacks,
but access in l2cap_sock_cleanup_listen() has unsafe lockless read.

 [Task 1]                         [Task 2 (hdev->workqueue)]
 l2cap_sock_release(parent)       l2cap_disconn_cfm
   l2cap_sock_cleanup_listen        l2cap_conn_del
     bt_accept_dequeue                l2cap_chan_del
       lock_sock(sk)                    l2cap_sock_teardown_cb
       bt_accept_unlink
         bt_sk(sk)->parent = NULL
       release_sock(sk) ----------------> lock_sock(sk)
                                          parent = /* NULL */
     lock_sock(sk) <--------------------- release_sock(sk)
                                          sock_set_flag(sk, SOCK_ZAPPED)
                                      l2cap_sock_close_cb
                                        l2cap_sock_kill(sk)
                                          l2cap_sock_put_chan
     chan = READ l2cap_pi(sk)->chan         l2cap_pi(sk)->chan = NULL
     l2cap_chan_hold_unless_zero            l2cap_put_chan(chan)
       kref_get_unless_zero(&chan->ref)

Task 1 may observe NULL which causes null-ptr-deref.

Fix the race by taking lock_sock() in l2cap_sock_kill() to
synchronize with l2cap_sock_cleanup_listen().  hold_unless_zero() is not
needed here, l2cap_pi(sk)->chan owns reference if it is non-NULL.

Clarify code comments vs. locking.

Fixes: 0e2c0392b9dc ("Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_new_connection_cb()")
Reported-by: syzbot+e6382a2f53f5fc7453ac@syzkaller.appspotmail.com
---

#syz test

 include/net/bluetooth/l2cap.h |  5 +++++
 net/bluetooth/l2cap_sock.c    | 23 +++++++++++++----------
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index ef6ce1c20a4f..3d9a32094347 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -699,7 +699,12 @@ struct l2cap_rx_busy {
 
 struct l2cap_pinfo {
 	struct bt_sock		bt;
+
+	/* With owning sk_socket chan may be read without lock, other access
+	 * should hold lock_sock.
+	 */
 	struct l2cap_chan	*chan;
+
 	struct list_head	rx_busy;
 };
 
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 735167f73f31..9540617a0e6c 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1312,7 +1312,12 @@ static void l2cap_sock_kill(struct sock *sk)
 
 	BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));
 
+	/* Take lock to synchronize against access without owning sk->sk_socket,
+	 * eg. in l2cap_sock_cleanup_listen(). proto_ops etc. don't need lock.
+	 */
+	lock_sock(sk);
 	l2cap_sock_put_chan(sk);
+	release_sock(sk);
 
 	/* Kill poor orphan */
 	sock_set_flag(sk, SOCK_DEAD);
@@ -1516,14 +1521,10 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
 	 * establish sk_lock -> conn->lock and invert the established
 	 * conn->lock -> chan->lock -> sk_lock order (lockdep deadlock).
 	 *
-	 * Instead, briefly take the child sk lock to fetch and pin its chan.
-	 * l2cap_conn_del() reaches the chan free only via
-	 * l2cap_chan_del() -> l2cap_sock_teardown_cb(), which itself takes
-	 * the child sk lock; holding it across l2cap_chan_hold_unless_zero()
-	 * therefore guarantees the chan cannot be freed while we read and
-	 * pin it (hold_unless_zero() additionally skips a chan already past
-	 * its last reference).  We then drop the sk lock before taking
-	 * chan->lock, so sk and chan locks are never held together.
+	 * Instead, briefly take the child sk lock to synchronize vs.
+	 * l2cap_sock_kill that puts l2cap_pi(sk)->chan. We then drop the sk
+	 * lock before taking chan->lock, so sk and chan locks are never held
+	 * together.
 	 *
 	 * Since we cannot call l2cap_chan_close() without conn->lock,
 	 * schedule l2cap_chan_timeout to close the channel; it already
@@ -1533,10 +1534,12 @@ static void l2cap_sock_cleanup_listen(struct sock *parent)
 		struct l2cap_chan *chan;
 
 		lock_sock_nested(sk, L2CAP_NESTING_NORMAL);
-		chan = l2cap_chan_hold_unless_zero(l2cap_pi(sk)->chan);
+		chan = l2cap_pi(sk)->chan;
+		if (chan)
+			l2cap_chan_hold(chan);
 		release_sock(sk);
 		if (!chan) {
-			/* l2cap_conn_del() already tearing this child down */
+			/* Already torn down */
 			sock_put(sk);
 			continue;
 		}
-- 
2.55.0


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

end of thread, other threads:[~2026-08-08 12:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20 23:56 [syzbot] [bluetooth?] KASAN: null-ptr-deref Read in l2cap_chan_hold_unless_zero syzbot
2026-07-21  4:26 ` Hillf Danton
2026-07-21  4:57   ` syzbot
2026-08-08 12:00 ` Forwarded: [PATCH] Bluetooth: L2CAP: fix race l2cap_sock_cleanup_listen() vs. put_chan syzbot

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