[PATCH next] Bluetooth: l2cap: protect conn refcnt under hci dev lock

Lizhi Xu posted 1 patch 1 year ago
net/bluetooth/l2cap_core.c | 4 ----
net/bluetooth/l2cap_sock.c | 7 +++++--
2 files changed, 5 insertions(+), 6 deletions(-)
[PATCH next] Bluetooth: l2cap: protect conn refcnt under hci dev lock
Posted by Lizhi Xu 1 year ago
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@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=10bd8fe6741eedd2be2e
Tested-by: syzbot+10bd8fe6741eedd2be2e@syzkaller.appspotmail.com
Signed-off-by: Lizhi Xu <lizhi.xu@windriver.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
Re: [PATCH next] Bluetooth: l2cap: protect conn refcnt under hci dev lock
Posted by kernel test robot 1 year ago
Hi Lizhi,

kernel test robot noticed the following build warnings:

[auto build test WARNING on next-20250207]

url:    https://github.com/intel-lab-lkp/linux/commits/Lizhi-Xu/Bluetooth-l2cap-protect-conn-refcnt-under-hci-dev-lock/20250207-221142
base:   next-20250207
patch link:    https://lore.kernel.org/r/20250207140216.3076952-1-lizhi.xu%40windriver.com
patch subject: [PATCH next] Bluetooth: l2cap: protect conn refcnt under hci dev lock
config: i386-buildonly-randconfig-001-20250208 (https://download.01.org/0day-ci/archive/20250208/202502081633.z7O9VFNy-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250208/202502081633.z7O9VFNy-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202502081633.z7O9VFNy-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> net/bluetooth/l2cap_core.c:7477:27: warning: 'l2cap_conn_hold_unless_zero' defined but not used [-Wunused-function]
    7477 | static struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c)
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/l2cap_conn_hold_unless_zero +7477 net/bluetooth/l2cap_core.c

4d7ea8ee90e42f Luiz Augusto von Dentz 2021-01-13  7476  
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16 @7477  static struct l2cap_conn *l2cap_conn_hold_unless_zero(struct l2cap_conn *c)
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16  7478  {
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16  7479  	BT_DBG("conn %p orig refcnt %u", c, kref_read(&c->ref));
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16  7480  
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16  7481  	if (!kref_get_unless_zero(&c->ref))
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16  7482  		return NULL;
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16  7483  
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16  7484  	return c;
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16  7485  }
6ab54a71718943 Luiz Augusto von Dentz 2025-01-16  7486  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki