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