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