[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250207140216.3076952-1-lizhi.xu@windriver.com>
Date: Fri, 7 Feb 2025 22:02:16 +0800
From: Lizhi Xu <lizhi.xu@...driver.com>
To: <syzbot+10bd8fe6741eedd2be2e@...kaller.appspotmail.com>
CC: <eadavis@...com>, <johan.hedberg@...il.com>,
<linux-bluetooth@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
<luiz.dentz@...il.com>, <luiz.von.dentz@...el.com>,
<marcel@...tmann.org>, <syzkaller-bugs@...glegroups.com>
Subject: [PATCH next] Bluetooth: l2cap: protect conn refcnt under hci dev lock
syzbot reported a corrupted list in hci_chan_del. [1]
Use hci dev lock to protect the reference count of conn to avoid race
conditions on l2cap_sock_shutdown and l2cap_connect_cfm paths.
The get/put actions of conn are unbalanced due to abnormal exit, so remove
the redundant get/put actions of conn in l2cap_recv_acldata().
[1]
kernel BUG at lib/list_debug.c:61!
Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI
CPU: 1 UID: 0 PID: 5896 Comm: syz-executor213 Not tainted 6.14.0-rc1-next-20250204-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 12/27/2024
RIP: 0010:__list_del_entry_valid_or_report+0x12c/0x190 lib/list_debug.c:59
Code: 8c 4c 89 fe 48 89 da e8 32 8c 37 fc 90 0f 0b 48 89 df e8 27 9f 14 fd 48 c7 c7 a0 c0 60 8c 4c 89 fe 48 89 da e8 15 8c 37 fc 90 <0f> 0b 4c 89 e7 e8 0a 9f 14 fd 42 80 3c 2b 00 74 08 4c 89 e7 e8 cb
RSP: 0018:ffffc90003f6f998 EFLAGS: 00010246
RAX: 000000000000004e RBX: dead000000000122 RCX: 01454d423f7fbf00
RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000
RBP: dffffc0000000000 R08: ffffffff819f077c R09: 1ffff920007eded0
R10: dffffc0000000000 R11: fffff520007eded1 R12: dead000000000122
R13: dffffc0000000000 R14: ffff8880352248d8 R15: ffff888021297e00
FS: 00007f7ace6686c0(0000) GS:ffff8880b8700000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f7aceeeb1d0 CR3: 000000003527c000 CR4: 00000000003526f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
__list_del_entry_valid include/linux/list.h:124 [inline]
__list_del_entry include/linux/list.h:215 [inline]
list_del_rcu include/linux/rculist.h:168 [inline]
hci_chan_del+0x70/0x1b0 net/bluetooth/hci_conn.c:2858
l2cap_conn_free net/bluetooth/l2cap_core.c:1816 [inline]
kref_put include/linux/kref.h:65 [inline]
l2cap_conn_put+0x70/0xe0 net/bluetooth/l2cap_core.c:1830
l2cap_sock_shutdown+0xa8a/0x1020 net/bluetooth/l2cap_sock.c:1377
l2cap_sock_release+0x79/0x1d0 net/bluetooth/l2cap_sock.c:1416
__sock_release net/socket.c:642 [inline]
sock_close+0xbc/0x240 net/socket.c:1393
__fput+0x3e9/0x9f0 fs/file_table.c:448
task_work_run+0x24f/0x310 kernel/task_work.c:227
ptrace_notify+0x2d2/0x380 kernel/signal.c:2522
ptrace_report_syscall include/linux/ptrace.h:415 [inline]
ptrace_report_syscall_exit include/linux/ptrace.h:477 [inline]
syscall_exit_work+0xc7/0x1d0 kernel/entry/common.c:173
syscall_exit_to_user_mode_prepare kernel/entry/common.c:200 [inline]
__syscall_exit_to_user_mode_work kernel/entry/common.c:205 [inline]
syscall_exit_to_user_mode+0x24a/0x340 kernel/entry/common.c:218
do_syscall_64+0x100/0x230 arch/x86/entry/common.c:89
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Reported-by: syzbot+10bd8fe6741eedd2be2e@...kaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=10bd8fe6741eedd2be2e
Tested-by: syzbot+10bd8fe6741eedd2be2e@...kaller.appspotmail.com
Signed-off-by: Lizhi Xu <lizhi.xu@...driver.com>
---
net/bluetooth/l2cap_core.c | 4 ----
net/bluetooth/l2cap_sock.c | 7 +++++--
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index adb8c33ac595..503626f70be5 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -7497,8 +7497,6 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
if (!conn)
conn = l2cap_conn_add(hcon);
- conn = l2cap_conn_hold_unless_zero(conn);
-
hci_dev_unlock(hcon->hdev);
if (!conn)
@@ -7592,8 +7590,6 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
break;
}
- l2cap_conn_put(conn);
-
drop:
kfree_skb(skb);
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 46ea0bee2259..2a99394925a5 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1359,10 +1359,12 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
l2cap_chan_lock(chan);
conn = chan->conn;
- if (conn)
+ l2cap_chan_unlock(chan);
+ if (conn) {
+ hci_dev_lock(conn->hcon->hdev);
/* prevent conn structure from being freed */
l2cap_conn_get(conn);
- l2cap_chan_unlock(chan);
+ }
if (conn)
/* mutex lock must be taken before l2cap_chan_lock() */
@@ -1375,6 +1377,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
if (conn) {
mutex_unlock(&conn->chan_lock);
l2cap_conn_put(conn);
+ hci_dev_unlock(conn->hcon->hdev);
}
lock_sock(sk);
--
2.43.0
Powered by blists - more mailing lists