All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user
@ 2025-11-05 14:22 ssrane_b23
  2025-11-05 14:40 ` shaurya
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: ssrane_b23 @ 2025-11-05 14:22 UTC (permalink / raw)
  To: marcel
  Cc: johan.hedberg, luiz.dentz, linux-bluetooth, linux-kernel,
	syzbot+14b6d57fb728e27ce23c, linux-kernel-mentees, skhan,
	david.hunter.linux, khalid, Shaurya Rane

From: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>

Syzbot reported a use-after-free in l2cap_unregister_user(), caused by
missing reference counting on the associated hci_dev. If the device is
unregistered while L2CAP users are still active, l2cap_unregister_user()
may access a freed hci_dev when taking its lock.

Fix this by taking a device reference in l2cap_register_user() using
hci_dev_hold(), and releasing it in l2cap_unregister_user() via
hci_dev_put(). This ensures the hci_dev remains valid for the lifetime
of registered L2CAP users.

Reported-by: syzbot+14b6d57fb728e27ce23c@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=14b6d57fb728e27ce23c
Fixes: c8992cffbe74 ("Bluetooth: hci_event: Use of a function table to handle Command Complete")
Signed-off-by: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>
---
 net/bluetooth/l2cap_core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 805c752ac0a9..6a880f8ab6c2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1688,6 +1688,11 @@ int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
 	struct hci_dev *hdev = conn->hcon->hdev;
 	int ret;
 
+	/* Hold a reference to hdev to prevent it from being freed while
+	 * we have registered users.
+	 */
+	hci_dev_hold(hdev);
+
 	/* We need to check whether l2cap_conn is registered. If it is not, we
 	 * must not register the l2cap_user. l2cap_conn_del() is unregisters
 	 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
@@ -1717,6 +1722,10 @@ int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
 
 out_unlock:
 	hci_dev_unlock(hdev);
+
+	if (ret)
+		hci_dev_put(hdev);
+
 	return ret;
 }
 EXPORT_SYMBOL(l2cap_register_user);
@@ -1735,6 +1744,9 @@ void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
 
 out_unlock:
 	hci_dev_unlock(hdev);
+
+	/* Release the reference we took in l2cap_register_user */
+	hci_dev_put(hdev);
 }
 EXPORT_SYMBOL(l2cap_unregister_user);
 
-- 
2.34.1


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

* Re: [PATCH] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user
  2025-11-05 14:22 [PATCH] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user ssrane_b23
@ 2025-11-05 14:40 ` shaurya
  2025-11-05 15:32   ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read " syzbot
  2025-11-05 19:26   ` [PATCH] Bluetooth: L2CAP: Fix use-after-free " shaurya
  2025-11-05 15:05 ` Bluetooth: L2CAP: Fix use-after-free " bluez.test.bot
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 13+ messages in thread
From: shaurya @ 2025-11-05 14:40 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: linux-bluetooth, linux-kernel, luiz.dentz, marcel,
	syzbot+14b6d57fb728e27ce23c

#syz test: 
git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git master


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

* RE: Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user
  2025-11-05 14:22 [PATCH] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user ssrane_b23
  2025-11-05 14:40 ` shaurya
@ 2025-11-05 15:05 ` bluez.test.bot
  2025-11-05 19:36 ` [PATCH] " Pauli Virtanen
  2025-11-06 18:20 ` [PATCH v2 1/1] " ssrane_b23
  3 siblings, 0 replies; 13+ messages in thread
From: bluez.test.bot @ 2025-11-05 15:05 UTC (permalink / raw)
  To: linux-bluetooth, ssrane_b23

[-- Attachment #1: Type: text/plain, Size: 2456 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1019901

---Test result---

Test Summary:
CheckPatch                    PENDING   0.40 seconds
GitLint                       PENDING   0.82 seconds
SubjectPrefix                 PASS      0.09 seconds
BuildKernel                   PASS      24.77 seconds
CheckAllWarning               PASS      27.34 seconds
CheckSparse                   PASS      31.19 seconds
BuildKernel32                 PASS      24.56 seconds
TestRunnerSetup               PASS      494.73 seconds
TestRunner_l2cap-tester       PASS      23.48 seconds
TestRunner_iso-tester         PASS      88.10 seconds
TestRunner_bnep-tester        PASS      6.13 seconds
TestRunner_mgmt-tester        FAIL      111.51 seconds
TestRunner_rfcomm-tester      PASS      9.20 seconds
TestRunner_sco-tester         PASS      14.31 seconds
TestRunner_ioctl-tester       PASS      9.89 seconds
TestRunner_mesh-tester        FAIL      11.50 seconds
TestRunner_smp-tester         PASS      8.34 seconds
TestRunner_userchan-tester    PASS      6.46 seconds
IncrementalBuild              PENDING   0.70 seconds

Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:

##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:

##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 490, Passed: 483 (98.6%), Failed: 3, Not Run: 4

Failed Test Cases
Read Exp Feature - Success                           Failed       0.097 seconds
LL Privacy - Add Device 2 (2 Devices to AL)          Failed       0.173 seconds
LL Privacy - Start Discovery 1 (Disable RL)          Failed       0.171 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0

Failed Test Cases
Mesh - Send cancel - 1                               Timed out    2.009 seconds
Mesh - Send cancel - 2                               Timed out    1.996 seconds
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:



---
Regards,
Linux Bluetooth


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

* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in l2cap_unregister_user
  2025-11-05 14:40 ` shaurya
@ 2025-11-05 15:32   ` syzbot
  2025-11-05 19:03     ` shaurya
  2025-11-05 19:05     ` shaurya
  2025-11-05 19:26   ` [PATCH] Bluetooth: L2CAP: Fix use-after-free " shaurya
  1 sibling, 2 replies; 13+ messages in thread
From: syzbot @ 2025-11-05 15:32 UTC (permalink / raw)
  To: linux-bluetooth, linux-kernel, luiz.dentz, marcel, ssranevjti,
	syzkaller-bugs

Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: slab-use-after-free Read in l2cap_unregister_user

==================================================================
BUG: KASAN: slab-use-after-free in __mutex_waiter_is_first kernel/locking/mutex.c:183 [inline]
BUG: KASAN: slab-use-after-free in __mutex_lock_common+0xd18/0x2678 kernel/locking/mutex.c:678
Read of size 8 at addr ffff0000d69a80a0 by task khidpd_05c25886/7548

CPU: 1 UID: 0 PID: 7548 Comm: khidpd_05c25886 Not tainted syzkaller #0 PREEMPT 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/03/2025
Call trace:
 show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:499 (C)
 __dump_stack+0x30/0x40 lib/dump_stack.c:94
 dump_stack_lvl+0xd8/0x12c lib/dump_stack.c:120
 print_address_description+0xa8/0x238 mm/kasan/report.c:378
 print_report+0x68/0x84 mm/kasan/report.c:482
 kasan_report+0xb0/0x110 mm/kasan/report.c:595
 __asan_report_load8_noabort+0x20/0x2c mm/kasan/report_generic.c:381
 __mutex_waiter_is_first kernel/locking/mutex.c:183 [inline]
 __mutex_lock_common+0xd18/0x2678 kernel/locking/mutex.c:678
 __mutex_lock kernel/locking/mutex.c:760 [inline]
 mutex_lock_nested+0x2c/0x38 kernel/locking/mutex.c:812
 l2cap_unregister_user+0x74/0x190 net/bluetooth/l2cap_core.c:1728
 hidp_session_thread+0x3d0/0x46c net/bluetooth/hidp/core.c:1304
 kthread+0x5fc/0x75c kernel/kthread.c:463
 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:844

Allocated by task 7442:
 kasan_save_stack mm/kasan/common.c:56 [inline]
 kasan_save_track+0x40/0x78 mm/kasan/common.c:77
 kasan_save_alloc_info+0x44/0x54 mm/kasan/generic.c:573
 poison_kmalloc_redzone mm/kasan/common.c:400 [inline]
 __kasan_kmalloc+0x9c/0xb4 mm/kasan/common.c:417
 kasan_kmalloc include/linux/kasan.h:262 [inline]
 __do_kmalloc_node mm/slub.c:5642 [inline]
 __kmalloc_noprof+0x3fc/0x728 mm/slub.c:5654
 kmalloc_noprof include/linux/slab.h:961 [inline]
 kzalloc_noprof include/linux/slab.h:1094 [inline]
 hci_alloc_dev_priv+0x2c/0x1b84 net/bluetooth/hci_core.c:2448
 hci_alloc_dev include/net/bluetooth/hci_core.h:1751 [inline]
 __vhci_create_device drivers/bluetooth/hci_vhci.c:421 [inline]
 vhci_create_device+0x108/0x638 drivers/bluetooth/hci_vhci.c:479
 vhci_get_user drivers/bluetooth/hci_vhci.c:536 [inline]
 vhci_write+0x314/0x3d4 drivers/bluetooth/hci_vhci.c:616
 new_sync_write fs/read_write.c:593 [inline]
 vfs_write+0x540/0xa3c fs/read_write.c:686
 ksys_write+0x120/0x210 fs/read_write.c:738
 __do_sys_write fs/read_write.c:749 [inline]
 __se_sys_write fs/read_write.c:746 [inline]
 __arm64_sys_write+0x7c/0x90 fs/read_write.c:746
 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
 invoke_syscall+0x98/0x254 arch/arm64/kernel/syscall.c:49
 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132
 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151
 el0_svc+0x5c/0x254 arch/arm64/kernel/entry-common.c:746
 el0t_64_sync_handler+0x84/0x12c arch/arm64/kernel/entry-common.c:765
 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:596

Freed by task 7595:
 kasan_save_stack mm/kasan/common.c:56 [inline]
 kasan_save_track+0x40/0x78 mm/kasan/common.c:77
 __kasan_save_free_info+0x58/0x70 mm/kasan/generic.c:587
 kasan_save_free_info mm/kasan/kasan.h:406 [inline]
 poison_slab_object mm/kasan/common.c:252 [inline]
 __kasan_slab_free+0x74/0xa4 mm/kasan/common.c:284
 kasan_slab_free include/linux/kasan.h:234 [inline]
 slab_free_hook mm/slub.c:2539 [inline]
 slab_free mm/slub.c:6630 [inline]
 kfree+0x184/0x600 mm/slub.c:6837
 hci_release_dev+0xf48/0x1060 net/bluetooth/hci_core.c:2776
 bt_host_release+0x70/0x8c net/bluetooth/hci_sysfs.c:87
 device_release+0x8c/0x1ac drivers/base/core.c:-1
 kobject_cleanup lib/kobject.c:689 [inline]
 kobject_release lib/kobject.c:720 [inline]
 kref_put include/linux/kref.h:65 [inline]
 kobject_put+0x2b0/0x438 lib/kobject.c:737
 put_device+0x28/0x40 drivers/base/core.c:3797
 hci_free_dev+0x24/0x34 net/bluetooth/hci_core.c:2579
 vhci_release+0x134/0x17c drivers/bluetooth/hci_vhci.c:691
 __fput+0x340/0x75c fs/file_table.c:468
 ____fput+0x20/0x58 fs/file_table.c:496
 task_work_run+0x1dc/0x260 kernel/task_work.c:227
 exit_task_work include/linux/task_work.h:40 [inline]
 do_exit+0x524/0x1a14 kernel/exit.c:966
 do_group_exit+0x194/0x22c kernel/exit.c:1107
 get_signal+0x11dc/0x12f8 kernel/signal.c:3034
 arch_do_signal_or_restart+0x274/0x4414 arch/arm64/kernel/signal.c:1619
 exit_to_user_mode_loop+0x7c/0x178 kernel/entry/common.c:40
 exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
 arm64_exit_to_user_mode arch/arm64/kernel/entry-common.c:103 [inline]
 el0_svc+0x170/0x254 arch/arm64/kernel/entry-common.c:747
 el0t_64_sync_handler+0x84/0x12c arch/arm64/kernel/entry-common.c:765
 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:596

Last potentially related work creation:
 kasan_save_stack+0x40/0x6c mm/kasan/common.c:56
 kasan_record_aux_stack+0xb0/0xc8 mm/kasan/generic.c:559
 insert_work+0x54/0x2cc kernel/workqueue.c:2186
 __queue_work+0xc88/0x1210 kernel/workqueue.c:2345
 queue_work_on+0xdc/0x18c kernel/workqueue.c:2392
 queue_work include/linux/workqueue.h:669 [inline]
 hci_cmd_timeout+0x178/0x1c8 net/bluetooth/hci_core.c:1480
 process_one_work+0x7e8/0x155c kernel/workqueue.c:3263
 process_scheduled_works kernel/workqueue.c:3346 [inline]
 worker_thread+0x958/0xed8 kernel/workqueue.c:3427
 kthread+0x5fc/0x75c kernel/kthread.c:463
 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:844

Second to last potentially related work creation:
 kasan_save_stack+0x40/0x6c mm/kasan/common.c:56
 kasan_record_aux_stack+0xb0/0xc8 mm/kasan/generic.c:559
 insert_work+0x54/0x2cc kernel/workqueue.c:2186
 __queue_work+0xdb0/0x1210 kernel/workqueue.c:2341
 delayed_work_timer_fn+0x74/0x90 kernel/workqueue.c:2487
 call_timer_fn+0x1b4/0x818 kernel/time/timer.c:1747
 expire_timers kernel/time/timer.c:1793 [inline]
 __run_timers kernel/time/timer.c:2372 [inline]
 __run_timer_base+0x54c/0x76c kernel/time/timer.c:2384
 run_timer_base kernel/time/timer.c:2393 [inline]
 run_timer_softirq+0xcc/0x194 kernel/time/timer.c:2403
 handle_softirqs+0x328/0xc88 kernel/softirq.c:622
 __do_softirq+0x14/0x20 kernel/softirq.c:656

The buggy address belongs to the object at ffff0000d69a8000
 which belongs to the cache kmalloc-8k of size 8192
The buggy address is located 160 bytes inside of
 freed 8192-byte region [ffff0000d69a8000, ffff0000d69aa000)

The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1169a8
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
anon flags: 0x5ffc00000000040(head|node=0|zone=2|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 05ffc00000000040 ffff0000c0002280 0000000000000000 0000000000000001
raw: 0000000000000000 0000000000020002 00000000f5000000 0000000000000000
head: 05ffc00000000040 ffff0000c0002280 0000000000000000 0000000000000001
head: 0000000000000000 0000000000020002 00000000f5000000 0000000000000000
head: 05ffc00000000003 fffffdffc35a6a01 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff0000d69a7f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff0000d69a8000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff0000d69a8080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                               ^
 ffff0000d69a8100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff0000d69a8180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================


Tested on:

commit:         8d59fba4 Bluetooth: MGMT: Fix OOB access in parse_adv_..
git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git master
console output: https://syzkaller.appspot.com/x/log.txt?x=11a52084580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=5eeb63aaf73b06da
dashboard link: https://syzkaller.appspot.com/bug?extid=14b6d57fb728e27ce23c
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
userspace arch: arm64

Note: no patches were applied.

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

* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in l2cap_unregister_user
  2025-11-05 15:32   ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read " syzbot
@ 2025-11-05 19:03     ` shaurya
  2025-11-05 19:04       ` syzbot
  2025-11-05 19:05     ` shaurya
  1 sibling, 1 reply; 13+ messages in thread
From: shaurya @ 2025-11-05 19:03 UTC (permalink / raw)
  To: syzbot+14b6d57fb728e27ce23c
  Cc: linux-bluetooth, linux-kernel, luiz.dentz, marcel, ssranevjti,
	syzkaller-bugs

#syz test: 
https://lore.kernel.org/all/20251105142251.101852-1-ssranevjti@gmail.com/T/


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

* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in l2cap_unregister_user
  2025-11-05 19:03     ` shaurya
@ 2025-11-05 19:04       ` syzbot
  0 siblings, 0 replies; 13+ messages in thread
From: syzbot @ 2025-11-05 19:04 UTC (permalink / raw)
  To: ssranevjti
  Cc: linux-bluetooth, linux-kernel, luiz.dentz, marcel, ssranevjti,
	syzkaller-bugs

> #syz test: 

I've failed to parse your command.
Did you perhaps forget to provide the branch name, or added an extra ':'?
Please use one of the two supported formats:
1. #syz test
2. #syz test: repo branch-or-commit-hash
Note the lack of ':' in option 1.

> https://lore.kernel.org/all/20251105142251.101852-1-ssranevjti@gmail.com/T/
>

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

* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in l2cap_unregister_user
  2025-11-05 15:32   ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read " syzbot
  2025-11-05 19:03     ` shaurya
@ 2025-11-05 19:05     ` shaurya
  2025-11-05 19:05       ` syzbot
  1 sibling, 1 reply; 13+ messages in thread
From: shaurya @ 2025-11-05 19:05 UTC (permalink / raw)
  To: syzbot+14b6d57fb728e27ce23c
  Cc: linux-bluetooth, linux-kernel, ssranevjti, syzkaller-bugs

#syz test: 
https://lore.kernel.org/all/20251105142251.101852-1-ssranevjti@gmail.com/T/


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

* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in l2cap_unregister_user
  2025-11-05 19:05     ` shaurya
@ 2025-11-05 19:05       ` syzbot
  0 siblings, 0 replies; 13+ messages in thread
From: syzbot @ 2025-11-05 19:05 UTC (permalink / raw)
  To: ssranevjti; +Cc: linux-bluetooth, linux-kernel, ssranevjti, syzkaller-bugs

> #syz test: 

I've failed to parse your command.
Did you perhaps forget to provide the branch name, or added an extra ':'?
Please use one of the two supported formats:
1. #syz test
2. #syz test: repo branch-or-commit-hash
Note the lack of ':' in option 1.

> https://lore.kernel.org/all/20251105142251.101852-1-ssranevjti@gmail.com/T/
>

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

* Re: [PATCH] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user
  2025-11-05 14:40 ` shaurya
  2025-11-05 15:32   ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read " syzbot
@ 2025-11-05 19:26   ` shaurya
  2025-11-05 20:14     ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read " syzbot
  1 sibling, 1 reply; 13+ messages in thread
From: shaurya @ 2025-11-05 19:26 UTC (permalink / raw)
  To: syzbot+14b6d57fb728e27ce23c
  Cc: linux-bluetooth, linux-kernel, syzbot+14b6d57fb728e27ce23c

#syz test: 
git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git master
https://lore.kernel.org/all/20251105142251.101852-1-ssranevjti@gmail.com/T/


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

* Re: [PATCH] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user
  2025-11-05 14:22 [PATCH] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user ssrane_b23
  2025-11-05 14:40 ` shaurya
  2025-11-05 15:05 ` Bluetooth: L2CAP: Fix use-after-free " bluez.test.bot
@ 2025-11-05 19:36 ` Pauli Virtanen
  2025-11-06 18:20 ` [PATCH v2 1/1] " ssrane_b23
  3 siblings, 0 replies; 13+ messages in thread
From: Pauli Virtanen @ 2025-11-05 19:36 UTC (permalink / raw)
  To: ssrane_b23
  Cc: linux-bluetooth, linux-kernel, linux-kernel-mentees, skhan,
	david.hunter.linux, khalid

ke, 2025-11-05 kello 19:52 +0530, ssrane_b23@ee.vjti.ac.in kirjoitti:
> From: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>
> 
> Syzbot reported a use-after-free in l2cap_unregister_user(), caused by
> missing reference counting on the associated hci_dev. If the device is
> unregistered while L2CAP users are still active, l2cap_unregister_user()
> may access a freed hci_dev when taking its lock.
> 
> Fix this by taking a device reference in l2cap_register_user() using
> hci_dev_hold(), and releasing it in l2cap_unregister_user() via
> hci_dev_put(). This ensures the hci_dev remains valid for the lifetime
> of registered L2CAP users.
> 
> Reported-by: syzbot+14b6d57fb728e27ce23c@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=14b6d57fb728e27ce23c
> Fixes: c8992cffbe74 ("Bluetooth: hci_event: Use of a function table to handle Command Complete")
> Signed-off-by: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>
> ---
>  net/bluetooth/l2cap_core.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 805c752ac0a9..6a880f8ab6c2 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -1688,6 +1688,11 @@ int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
>  	struct hci_dev *hdev = conn->hcon->hdev;
>  	int ret;
>  
> +	/* Hold a reference to hdev to prevent it from being freed while
> +	 * we have registered users.
> +	 */
> +	hci_dev_hold(hdev);
> +
>  	/* We need to check whether l2cap_conn is registered. If it is not, we
>  	 * must not register the l2cap_user. l2cap_conn_del() is unregisters
>  	 * l2cap_conn objects, but doesn't provide its own locking. Instead, it

The old comment here seems out of date since commit ab4eedb790cae,
currently l2cap_conn_del() appears to be using conn->lock to do

	mutex_lock(&conn->lock);
	...
	l2cap_unregister_all_users(conn);
	...
        hci_chan_del(conn->hchan);
        conn->hchan = NULL;
	...
	mutex_unlock(&conn->lock);

so it looks likely also taking conn->lock could avoid the races with
conn->users and conn->hchan.

> @@ -1717,6 +1722,10 @@ int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
>  
>  out_unlock:
>  	hci_dev_unlock(hdev);
> +
> +	if (ret)
> +		hci_dev_put(hdev);
> +
>  	return ret;
>  }
>  EXPORT_SYMBOL(l2cap_register_user);
> @@ -1735,6 +1744,9 @@ void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
>  
>  out_unlock:
>  	hci_dev_unlock(hdev);
> +
> +	/* Release the reference we took in l2cap_register_user */
> +	hci_dev_put(hdev);
>  }
>  EXPORT_SYMBOL(l2cap_unregister_user);
>  

-- 
Pauli Virtanen

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

* Re: [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in l2cap_unregister_user
  2025-11-05 19:26   ` [PATCH] Bluetooth: L2CAP: Fix use-after-free " shaurya
@ 2025-11-05 20:14     ` syzbot
  0 siblings, 0 replies; 13+ messages in thread
From: syzbot @ 2025-11-05 20:14 UTC (permalink / raw)
  To: linux-bluetooth, linux-kernel, ssranevjti, syzkaller-bugs

Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: slab-use-after-free Read in l2cap_unregister_user

==================================================================
BUG: KASAN: slab-use-after-free in __mutex_waiter_is_first kernel/locking/mutex.c:183 [inline]
BUG: KASAN: slab-use-after-free in __mutex_lock_common+0xd18/0x2678 kernel/locking/mutex.c:678
Read of size 8 at addr ffff0000de1180a0 by task khidpd_05c25886/7093

CPU: 0 UID: 0 PID: 7093 Comm: khidpd_05c25886 Not tainted syzkaller #0 PREEMPT 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/03/2025
Call trace:
 show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:499 (C)
 __dump_stack+0x30/0x40 lib/dump_stack.c:94
 dump_stack_lvl+0xd8/0x12c lib/dump_stack.c:120
 print_address_description+0xa8/0x238 mm/kasan/report.c:378
 print_report+0x68/0x84 mm/kasan/report.c:482
 kasan_report+0xb0/0x110 mm/kasan/report.c:595
 __asan_report_load8_noabort+0x20/0x2c mm/kasan/report_generic.c:381
 __mutex_waiter_is_first kernel/locking/mutex.c:183 [inline]
 __mutex_lock_common+0xd18/0x2678 kernel/locking/mutex.c:678
 __mutex_lock kernel/locking/mutex.c:760 [inline]
 mutex_lock_nested+0x2c/0x38 kernel/locking/mutex.c:812
 l2cap_unregister_user+0x74/0x190 net/bluetooth/l2cap_core.c:1728
 hidp_session_thread+0x3d0/0x46c net/bluetooth/hidp/core.c:1304
 kthread+0x5fc/0x75c kernel/kthread.c:463
 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:844

Allocated by task 6997:
 kasan_save_stack mm/kasan/common.c:56 [inline]
 kasan_save_track+0x40/0x78 mm/kasan/common.c:77
 kasan_save_alloc_info+0x44/0x54 mm/kasan/generic.c:573
 poison_kmalloc_redzone mm/kasan/common.c:400 [inline]
 __kasan_kmalloc+0x9c/0xb4 mm/kasan/common.c:417
 kasan_kmalloc include/linux/kasan.h:262 [inline]
 __do_kmalloc_node mm/slub.c:5642 [inline]
 __kmalloc_noprof+0x3fc/0x728 mm/slub.c:5654
 kmalloc_noprof include/linux/slab.h:961 [inline]
 kzalloc_noprof include/linux/slab.h:1094 [inline]
 hci_alloc_dev_priv+0x2c/0x1b84 net/bluetooth/hci_core.c:2448
 hci_alloc_dev include/net/bluetooth/hci_core.h:1751 [inline]
 __vhci_create_device drivers/bluetooth/hci_vhci.c:421 [inline]
 vhci_create_device+0x108/0x638 drivers/bluetooth/hci_vhci.c:479
 vhci_get_user drivers/bluetooth/hci_vhci.c:536 [inline]
 vhci_write+0x314/0x3d4 drivers/bluetooth/hci_vhci.c:616
 new_sync_write fs/read_write.c:593 [inline]
 vfs_write+0x540/0xa3c fs/read_write.c:686
 ksys_write+0x120/0x210 fs/read_write.c:738
 __do_sys_write fs/read_write.c:749 [inline]
 __se_sys_write fs/read_write.c:746 [inline]
 __arm64_sys_write+0x7c/0x90 fs/read_write.c:746
 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
 invoke_syscall+0x98/0x254 arch/arm64/kernel/syscall.c:49
 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132
 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151
 el0_svc+0x5c/0x254 arch/arm64/kernel/entry-common.c:746
 el0t_64_sync_handler+0x84/0x12c arch/arm64/kernel/entry-common.c:765
 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:596

Freed by task 7412:
 kasan_save_stack mm/kasan/common.c:56 [inline]
 kasan_save_track+0x40/0x78 mm/kasan/common.c:77
 __kasan_save_free_info+0x58/0x70 mm/kasan/generic.c:587
 kasan_save_free_info mm/kasan/kasan.h:406 [inline]
 poison_slab_object mm/kasan/common.c:252 [inline]
 __kasan_slab_free+0x74/0xa4 mm/kasan/common.c:284
 kasan_slab_free include/linux/kasan.h:234 [inline]
 slab_free_hook mm/slub.c:2539 [inline]
 slab_free mm/slub.c:6630 [inline]
 kfree+0x184/0x600 mm/slub.c:6837
 hci_release_dev+0xf48/0x1060 net/bluetooth/hci_core.c:2776
 bt_host_release+0x70/0x8c net/bluetooth/hci_sysfs.c:87
 device_release+0x8c/0x1ac drivers/base/core.c:-1
 kobject_cleanup lib/kobject.c:689 [inline]
 kobject_release lib/kobject.c:720 [inline]
 kref_put include/linux/kref.h:65 [inline]
 kobject_put+0x2b0/0x438 lib/kobject.c:737
 put_device+0x28/0x40 drivers/base/core.c:3797
 hci_free_dev+0x24/0x34 net/bluetooth/hci_core.c:2579
 vhci_release+0x134/0x17c drivers/bluetooth/hci_vhci.c:691
 __fput+0x340/0x75c fs/file_table.c:468
 ____fput+0x20/0x58 fs/file_table.c:496
 task_work_run+0x1dc/0x260 kernel/task_work.c:227
 exit_task_work include/linux/task_work.h:40 [inline]
 do_exit+0x524/0x1a14 kernel/exit.c:966
 do_group_exit+0x194/0x22c kernel/exit.c:1107
 get_signal+0x11dc/0x12f8 kernel/signal.c:3034
 arch_do_signal_or_restart+0x274/0x4414 arch/arm64/kernel/signal.c:1619
 exit_to_user_mode_loop+0x7c/0x178 kernel/entry/common.c:40
 exit_to_user_mode_prepare include/linux/irq-entry-common.h:225 [inline]
 arm64_exit_to_user_mode arch/arm64/kernel/entry-common.c:103 [inline]
 el0_svc+0x170/0x254 arch/arm64/kernel/entry-common.c:747
 el0t_64_sync_handler+0x84/0x12c arch/arm64/kernel/entry-common.c:765
 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:596

Last potentially related work creation:
 kasan_save_stack+0x40/0x6c mm/kasan/common.c:56
 kasan_record_aux_stack+0xb0/0xc8 mm/kasan/generic.c:559
 insert_work+0x54/0x2cc kernel/workqueue.c:2186
 __queue_work+0xc88/0x1210 kernel/workqueue.c:2345
 queue_work_on+0xdc/0x18c kernel/workqueue.c:2392
 queue_work include/linux/workqueue.h:669 [inline]
 hci_cmd_timeout+0x178/0x1c8 net/bluetooth/hci_core.c:1480
 process_one_work+0x7e8/0x155c kernel/workqueue.c:3263
 process_scheduled_works kernel/workqueue.c:3346 [inline]
 worker_thread+0x958/0xed8 kernel/workqueue.c:3427
 kthread+0x5fc/0x75c kernel/kthread.c:463
 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:844

Second to last potentially related work creation:
 kasan_save_stack+0x40/0x6c mm/kasan/common.c:56
 kasan_record_aux_stack+0xb0/0xc8 mm/kasan/generic.c:559
 insert_work+0x54/0x2cc kernel/workqueue.c:2186
 __queue_work+0xdb0/0x1210 kernel/workqueue.c:2341
 delayed_work_timer_fn+0x74/0x90 kernel/workqueue.c:2487
 call_timer_fn+0x1b4/0x818 kernel/time/timer.c:1747
 expire_timers kernel/time/timer.c:1793 [inline]
 __run_timers kernel/time/timer.c:2372 [inline]
 __run_timer_base+0x54c/0x76c kernel/time/timer.c:2384
 run_timer_base kernel/time/timer.c:2393 [inline]
 run_timer_softirq+0xcc/0x194 kernel/time/timer.c:2403
 handle_softirqs+0x328/0xc88 kernel/softirq.c:622
 __do_softirq+0x14/0x20 kernel/softirq.c:656

The buggy address belongs to the object at ffff0000de118000
 which belongs to the cache kmalloc-8k of size 8192
The buggy address is located 160 bytes inside of
 freed 8192-byte region [ffff0000de118000, ffff0000de11a000)

The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x11e118
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
anon flags: 0x5ffc00000000040(head|node=0|zone=2|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 05ffc00000000040 ffff0000c0002280 0000000000000000 dead000000000001
raw: 0000000000000000 0000000000020002 00000000f5000000 0000000000000000
head: 05ffc00000000040 ffff0000c0002280 0000000000000000 dead000000000001
head: 0000000000000000 0000000000020002 00000000f5000000 0000000000000000
head: 05ffc00000000003 fffffdffc3784601 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff0000de117f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff0000de118000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff0000de118080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                               ^
 ffff0000de118100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff0000de118180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================


Tested on:

commit:         8d59fba4 Bluetooth: MGMT: Fix OOB access in parse_adv_..
git tree:       git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git master
console output: https://syzkaller.appspot.com/x/log.txt?x=14d9a532580000
kernel config:  https://syzkaller.appspot.com/x/.config?x=5eeb63aaf73b06da
dashboard link: https://syzkaller.appspot.com/bug?extid=14b6d57fb728e27ce23c
compiler:       Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
userspace arch: arm64

Note: no patches were applied.

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

* [PATCH v2 1/1] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user
  2025-11-05 14:22 [PATCH] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user ssrane_b23
                   ` (2 preceding siblings ...)
  2025-11-05 19:36 ` [PATCH] " Pauli Virtanen
@ 2025-11-06 18:20 ` ssrane_b23
  2025-11-06 18:43   ` [v2,1/1] " bluez.test.bot
  3 siblings, 1 reply; 13+ messages in thread
From: ssrane_b23 @ 2025-11-06 18:20 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: luiz.dentz, marcel, johan.hedberg, pav, linux-kernel,
	linux-kernel-mentees, syzbot+14b6d57fb728e27ce23c, Shaurya Rane

From: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>

After commit ab4eedb790ca ("Bluetooth: L2CAP: Fix corrupted list in
hci_chan_del"), l2cap_conn_del() uses conn->lock to protect access to
conn->users and conn->hchan. However, l2cap_register_user() and
l2cap_unregister_user() still use hci_dev_lock(), creating a race
condition where these functions can access conn->users and conn->hchan
concurrently with l2cap_conn_del().

This can lead to use-after-free and list corruption bugs, as reported
by syzbot.

Fix this by changing l2cap_register_user() and l2cap_unregister_user()
to use conn->lock instead of hci_dev_lock(), ensuring consistent locking
for the l2cap_conn structure.

Reported-by: syzbot+14b6d57fb728e27ce23c@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=14b6d57fb728e27ce23c
Fixes: ab4eedb790ca ("Bluetooth: L2CAP: Fix corrupted list in hci_chan_del")

Changes in v2:
 - Replaced hci_dev_lock()/unlock() with mutex_lock()/unlock(&conn->lock)
   in both l2cap_register_user() and l2cap_unregister_user().
 - Updated comments to match current locking rules.
 - Removed unnecessary hci_dev_hold()/hci_dev_put() usage.

Signed-off-by: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>
---
 net/bluetooth/l2cap_core.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d08320380ad6..29e78801c507 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1685,17 +1685,15 @@ static void l2cap_info_timeout(struct work_struct *work)
 
 int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
 {
-	struct hci_dev *hdev = conn->hcon->hdev;
 	int ret;
 
 	/* We need to check whether l2cap_conn is registered. If it is not, we
-	 * must not register the l2cap_user. l2cap_conn_del() is unregisters
-	 * l2cap_conn objects, but doesn't provide its own locking. Instead, it
-	 * relies on the parent hci_conn object to be locked. This itself relies
-	 * on the hci_dev object to be locked. So we must lock the hci device
-	 * here, too. */
+	 * must not register the l2cap_user. l2cap_conn_del() unregisters
+	 * l2cap_conn objects under conn->lock, and we use the same lock here
+	 * to protect access to conn->users and conn->hchan.
+	 */
 
-	hci_dev_lock(hdev);
+	mutex_lock(&conn->lock);
 
 	if (!list_empty(&user->list)) {
 		ret = -EINVAL;
@@ -1716,16 +1714,14 @@ int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
 	ret = 0;
 
 out_unlock:
-	hci_dev_unlock(hdev);
+	mutex_unlock(&conn->lock);
 	return ret;
 }
 EXPORT_SYMBOL(l2cap_register_user);
 
 void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
 {
-	struct hci_dev *hdev = conn->hcon->hdev;
-
-	hci_dev_lock(hdev);
+	mutex_lock(&conn->lock);
 
 	if (list_empty(&user->list))
 		goto out_unlock;
@@ -1734,7 +1730,7 @@ void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
 	user->remove(conn, user);
 
 out_unlock:
-	hci_dev_unlock(hdev);
+	mutex_unlock(&conn->lock);
 }
 EXPORT_SYMBOL(l2cap_unregister_user);
 
-- 
2.34.1


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

* RE: [v2,1/1] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user
  2025-11-06 18:20 ` [PATCH v2 1/1] " ssrane_b23
@ 2025-11-06 18:43   ` bluez.test.bot
  0 siblings, 0 replies; 13+ messages in thread
From: bluez.test.bot @ 2025-11-06 18:43 UTC (permalink / raw)
  To: linux-bluetooth, ssrane_b23

[-- Attachment #1: Type: text/plain, Size: 2456 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1020593

---Test result---

Test Summary:
CheckPatch                    PENDING   0.33 seconds
GitLint                       PENDING   0.44 seconds
SubjectPrefix                 PASS      0.09 seconds
BuildKernel                   PASS      25.66 seconds
CheckAllWarning               PASS      28.03 seconds
CheckSparse                   PASS      31.80 seconds
BuildKernel32                 PASS      25.17 seconds
TestRunnerSetup               PASS      501.49 seconds
TestRunner_l2cap-tester       PASS      23.83 seconds
TestRunner_iso-tester         PASS      78.32 seconds
TestRunner_bnep-tester        PASS      6.18 seconds
TestRunner_mgmt-tester        FAIL      113.92 seconds
TestRunner_rfcomm-tester      PASS      9.27 seconds
TestRunner_sco-tester         PASS      14.31 seconds
TestRunner_ioctl-tester       PASS      9.92 seconds
TestRunner_mesh-tester        FAIL      11.48 seconds
TestRunner_smp-tester         PASS      8.43 seconds
TestRunner_userchan-tester    PASS      6.47 seconds
IncrementalBuild              PENDING   0.87 seconds

Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:

##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:

##############################
Test: TestRunner_mgmt-tester - FAIL
Desc: Run mgmt-tester with test-runner
Output:
Total: 490, Passed: 483 (98.6%), Failed: 3, Not Run: 4

Failed Test Cases
Read Exp Feature - Success                           Failed       0.104 seconds
LL Privacy - Set Flags 3 (2 Devices to RL)           Failed       0.192 seconds
LL Privacy - Start Discovery 2 (Disable RL)          Failed       0.196 seconds
##############################
Test: TestRunner_mesh-tester - FAIL
Desc: Run mesh-tester with test-runner
Output:
Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0

Failed Test Cases
Mesh - Send cancel - 1                               Timed out    1.897 seconds
Mesh - Send cancel - 2                               Timed out    1.997 seconds
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:



---
Regards,
Linux Bluetooth


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

end of thread, other threads:[~2025-11-06 18:43 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-05 14:22 [PATCH] Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user ssrane_b23
2025-11-05 14:40 ` shaurya
2025-11-05 15:32   ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read " syzbot
2025-11-05 19:03     ` shaurya
2025-11-05 19:04       ` syzbot
2025-11-05 19:05     ` shaurya
2025-11-05 19:05       ` syzbot
2025-11-05 19:26   ` [PATCH] Bluetooth: L2CAP: Fix use-after-free " shaurya
2025-11-05 20:14     ` [syzbot] [bluetooth?] KASAN: slab-use-after-free Read " syzbot
2025-11-05 15:05 ` Bluetooth: L2CAP: Fix use-after-free " bluez.test.bot
2025-11-05 19:36 ` [PATCH] " Pauli Virtanen
2025-11-06 18:20 ` [PATCH v2 1/1] " ssrane_b23
2025-11-06 18:43   ` [v2,1/1] " bluez.test.bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.