* [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3)
@ 2025-05-14 4:27 syzbot
2025-05-14 7:10 ` [syzbot] #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9f35e33144ae5377d6a8de86dd3bd4d995c6ac65 syzbot
` (6 more replies)
0 siblings, 7 replies; 10+ messages in thread
From: syzbot @ 2025-05-14 4:27 UTC (permalink / raw)
To: johan.hedberg, linux-bluetooth, linux-kernel, luiz.dentz, marcel,
syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: ea34704d6ad7 Merge tag 'drm-fixes-2025-05-10' of https://g..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1663acf4580000
kernel config: https://syzkaller.appspot.com/x/.config?x=91c351a0f6229e67
dashboard link: https://syzkaller.appspot.com/bug?extid=feb0dc579bbe30a13190
compiler: Debian clang version 20.1.2 (++20250402124445+58df0ef89dd6-1~exp1~20250402004600.97), Debian LLD 20.1.2
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=112c9768580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1526e670580000
Downloadable assets:
disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/d900f083ada3/non_bootable_disk-ea34704d.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/c7e586f1a091/vmlinux-ea34704d.xz
kernel image: https://storage.googleapis.com/syzbot-assets/cd61ffd40938/bzImage-ea34704d.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com
==================================================================
BUG: KASAN: slab-use-after-free in mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405
Read of size 8 at addr ffff888048891a18 by task kworker/u5:8/5333
CPU: 0 UID: 0 PID: 5333 Comm: kworker/u5:8 Not tainted 6.15.0-rc5-syzkaller-00197-gea34704d6ad7 #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
Workqueue: hci0 hci_cmd_sync_work
Call Trace:
<TASK>
dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:408 [inline]
print_report+0xb4/0x290 mm/kasan/report.c:521
kasan_report+0x118/0x150 mm/kasan/report.c:634
mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405
hci_cmd_sync_work+0x25e/0x3a0 net/bluetooth/hci_sync.c:334
process_one_work kernel/workqueue.c:3238 [inline]
process_scheduled_works+0xadb/0x17a0 kernel/workqueue.c:3319
worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400
kthread+0x70e/0x8a0 kernel/kthread.c:464
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:153
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Allocated by task 5702:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
__kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394
kasan_kmalloc include/linux/kasan.h:260 [inline]
__kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4358
kmalloc_noprof include/linux/slab.h:905 [inline]
kzalloc_noprof include/linux/slab.h:1039 [inline]
mgmt_pending_new+0x65/0x240 net/bluetooth/mgmt_util.c:252
mgmt_pending_add+0x34/0x120 net/bluetooth/mgmt_util.c:279
remove_adv_monitor+0x103/0x1b0 net/bluetooth/mgmt.c:5453
hci_mgmt_cmd+0x9c6/0xef0 net/bluetooth/hci_sock.c:1712
hci_sock_sendmsg+0x6ca/0xee0 net/bluetooth/hci_sock.c:1832
sock_sendmsg_nosec net/socket.c:712 [inline]
__sock_sendmsg+0x219/0x270 net/socket.c:727
sock_write_iter+0x258/0x330 net/socket.c:1131
new_sync_write fs/read_write.c:591 [inline]
vfs_write+0x548/0xa90 fs/read_write.c:684
ksys_write+0x145/0x250 fs/read_write.c:736
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 5700:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x3e/0x80 mm/kasan/common.c:68
kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576
poison_slab_object mm/kasan/common.c:247 [inline]
__kasan_slab_free+0x62/0x70 mm/kasan/common.c:264
kasan_slab_free include/linux/kasan.h:233 [inline]
slab_free_hook mm/slub.c:2380 [inline]
slab_free mm/slub.c:4642 [inline]
kfree+0x193/0x440 mm/slub.c:4841
mgmt_pending_foreach+0xc9/0x120 net/bluetooth/mgmt_util.c:242
mgmt_index_removed+0x10d/0x2f0 net/bluetooth/mgmt.c:9362
hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1307
__sys_bind_socket net/socket.c:1810 [inline]
__sys_bind+0x2c3/0x3e0 net/socket.c:1841
__do_sys_bind net/socket.c:1846 [inline]
__se_sys_bind net/socket.c:1844 [inline]
__x64_sys_bind+0x7a/0x90 net/socket.c:1844
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff888048891a00
which belongs to the cache kmalloc-96 of size 96
The buggy address is located 24 bytes inside of
freed 96-byte region [ffff888048891a00, ffff888048891a60)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x48891
flags: 0x4fff00000000000(node=1|zone=1|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 04fff00000000000 ffff88801a041280 ffffea0000d6e3c0 dead000000000008
raw: 0000000000000000 0000000080200020 00000000f5000000 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x252800(GFP_NOWAIT|__GFP_NORETRY|__GFP_COMP|__GFP_THISNODE), pid 5317, tgid 5317 (syz-executor420), ts 80512529929, free_ts 0
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x1d8/0x230 mm/page_alloc.c:1718
prep_new_page mm/page_alloc.c:1726 [inline]
get_page_from_freelist+0x21ce/0x22b0 mm/page_alloc.c:3688
__alloc_frozen_pages_noprof+0x181/0x370 mm/page_alloc.c:4970
alloc_slab_page mm/slub.c:2452 [inline]
allocate_slab+0x65/0x3b0 mm/slub.c:2618
new_slab mm/slub.c:2672 [inline]
___slab_alloc+0xbfc/0x1480 mm/slub.c:3858
__slab_alloc mm/slub.c:3948 [inline]
__slab_alloc_node mm/slub.c:4023 [inline]
slab_alloc_node mm/slub.c:4184 [inline]
__kmalloc_cache_node_noprof+0x29a/0x3d0 mm/slub.c:4366
kmalloc_node_noprof include/linux/slab.h:928 [inline]
alloc_node_nr_active kernel/workqueue.c:4872 [inline]
__alloc_workqueue+0x6a4/0x1b70 kernel/workqueue.c:5726
alloc_workqueue+0xd4/0x210 kernel/workqueue.c:5786
tipc_topsrv_work_start net/tipc/topsrv.c:635 [inline]
tipc_topsrv_start net/tipc/topsrv.c:679 [inline]
tipc_topsrv_init_net+0x37f/0x830 net/tipc/topsrv.c:725
ops_init+0x359/0x5c0 net/core/net_namespace.c:138
setup_net+0x238/0x830 net/core/net_namespace.c:364
copy_net_ns+0x32e/0x590 net/core/net_namespace.c:518
create_new_namespaces+0x3d3/0x700 kernel/nsproxy.c:110
unshare_nsproxy_namespaces+0x11c/0x170 kernel/nsproxy.c:228
ksys_unshare+0x4c8/0x8c0 kernel/fork.c:3375
__do_sys_unshare kernel/fork.c:3446 [inline]
__se_sys_unshare kernel/fork.c:3444 [inline]
__x64_sys_unshare+0x38/0x50 kernel/fork.c:3444
page_owner free stack trace missing
Memory state around the buggy address:
ffff888048891900: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff888048891980: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
>ffff888048891a00: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
^
ffff888048891a80: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff888048891b00: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
==================================================================
---
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] 10+ messages in thread* Re: [syzbot] #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9f35e33144ae5377d6a8de86dd3bd4d995c6ac65 2025-05-14 4:27 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3) syzbot @ 2025-05-14 7:10 ` syzbot 2025-05-20 13:30 ` [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a5806cd506af5a7c19bcd596e4708b5c464bfd21 syzbot ` (5 subsequent siblings) 6 siblings, 0 replies; 10+ messages in thread From: syzbot @ 2025-05-14 7:10 UTC (permalink / raw) To: linux-kernel, syzkaller-bugs For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9f35e33144ae5377d6a8de86dd3bd4d995c6ac65 Author: dmantipov@yandex.ru #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9f35e33144ae5377d6a8de86dd3bd4d995c6ac65 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a5806cd506af5a7c19bcd596e4708b5c464bfd21 2025-05-14 4:27 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3) syzbot 2025-05-14 7:10 ` [syzbot] #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9f35e33144ae5377d6a8de86dd3bd4d995c6ac65 syzbot @ 2025-05-20 13:30 ` syzbot 2025-05-23 8:20 ` [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac syzbot ` (4 subsequent siblings) 6 siblings, 0 replies; 10+ messages in thread From: syzbot @ 2025-05-20 13:30 UTC (permalink / raw) To: linux-kernel, syzkaller-bugs For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a5806cd506af5a7c19bcd596e4708b5c464bfd21 Author: dmantipov@yandex.ru #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a5806cd506af5a7c19bcd596e4708b5c464bfd21 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac 2025-05-14 4:27 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3) syzbot 2025-05-14 7:10 ` [syzbot] #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9f35e33144ae5377d6a8de86dd3bd4d995c6ac65 syzbot 2025-05-20 13:30 ` [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a5806cd506af5a7c19bcd596e4708b5c464bfd21 syzbot @ 2025-05-23 8:20 ` syzbot 2025-05-23 8:20 ` syzbot ` (3 subsequent siblings) 6 siblings, 0 replies; 10+ messages in thread From: syzbot @ 2025-05-23 8:20 UTC (permalink / raw) To: linux-kernel, syzkaller-bugs For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac Author: dmantipov@yandex.ru #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac 2025-05-14 4:27 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3) syzbot ` (2 preceding siblings ...) 2025-05-23 8:20 ` [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac syzbot @ 2025-05-23 8:20 ` syzbot 2025-05-28 19:03 ` [syzbot] Re: [PATCH v1] Bluetooth: MGMT: Use RCU-protected in mgmt_pending list syzbot ` (2 subsequent siblings) 6 siblings, 0 replies; 10+ messages in thread From: syzbot @ 2025-05-23 8:20 UTC (permalink / raw) To: linux-kernel, syzkaller-bugs For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac Author: dmantipov@yandex.ru #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [syzbot] Re: [PATCH v1] Bluetooth: MGMT: Use RCU-protected in mgmt_pending list 2025-05-14 4:27 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3) syzbot ` (3 preceding siblings ...) 2025-05-23 8:20 ` syzbot @ 2025-05-28 19:03 ` syzbot 2025-06-02 18:00 ` [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock syzbot 2025-06-03 20:30 ` [syzbot] Re: [PATCH v4 1/2] Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete syzbot 6 siblings, 0 replies; 10+ messages in thread From: syzbot @ 2025-05-28 19:03 UTC (permalink / raw) To: linux-kernel, syzkaller-bugs For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: Re: [PATCH v1] Bluetooth: MGMT: Use RCU-protected in mgmt_pending list Author: luiz.dentz@gmail.com #syz test On Wed, May 28, 2025 at 2:44 PM Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > This uses RCU procedures to protect from concurrent access of > mgmt_pending list which can cause crashes like: > > ================================================================== > BUG: KASAN: slab-use-after-free in mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405 > Read of size 8 at addr ffff888048891a18 by task kworker/u5:8/5333 > > CPU: 0 UID: 0 PID: 5333 Comm: kworker/u5:8 Not tainted 6.15.0-rc5-syzkaller-00197-gea34704d6ad7 #0 PREEMPT(full) > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 > Workqueue: hci0 hci_cmd_sync_work > Call Trace: > <TASK> > dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 > print_address_description mm/kasan/report.c:408 [inline] > print_report+0xb4/0x290 mm/kasan/report.c:521 > kasan_report+0x118/0x150 mm/kasan/report.c:634 > mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405 > hci_cmd_sync_work+0x25e/0x3a0 net/bluetooth/hci_sync.c:334 > process_one_work kernel/workqueue.c:3238 [inline] > process_scheduled_works+0xadb/0x17a0 kernel/workqueue.c:3319 > worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400 > kthread+0x70e/0x8a0 kernel/kthread.c:464 > ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:153 > ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 > </TASK> > > Allocated by task 5702: > kasan_save_stack mm/kasan/common.c:47 [inline] > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > poison_kmalloc_redzone mm/kasan/common.c:377 [inline] > __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394 > kasan_kmalloc include/linux/kasan.h:260 [inline] > __kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4358 > kmalloc_noprof include/linux/slab.h:905 [inline] > kzalloc_noprof include/linux/slab.h:1039 [inline] > mgmt_pending_new+0x65/0x240 net/bluetooth/mgmt_util.c:252 > mgmt_pending_add+0x34/0x120 net/bluetooth/mgmt_util.c:279 > remove_adv_monitor+0x103/0x1b0 net/bluetooth/mgmt.c:5453 > hci_mgmt_cmd+0x9c6/0xef0 net/bluetooth/hci_sock.c:1712 > hci_sock_sendmsg+0x6ca/0xee0 net/bluetooth/hci_sock.c:1832 > sock_sendmsg_nosec net/socket.c:712 [inline] > __sock_sendmsg+0x219/0x270 net/socket.c:727 > sock_write_iter+0x258/0x330 net/socket.c:1131 > new_sync_write fs/read_write.c:591 [inline] > vfs_write+0x548/0xa90 fs/read_write.c:684 > ksys_write+0x145/0x250 fs/read_write.c:736 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Freed by task 5700: > kasan_save_stack mm/kasan/common.c:47 [inline] > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576 > poison_slab_object mm/kasan/common.c:247 [inline] > __kasan_slab_free+0x62/0x70 mm/kasan/common.c:264 > kasan_slab_free include/linux/kasan.h:233 [inline] > slab_free_hook mm/slub.c:2380 [inline] > slab_free mm/slub.c:4642 [inline] > kfree+0x193/0x440 mm/slub.c:4841 > mgmt_pending_foreach+0xc9/0x120 net/bluetooth/mgmt_util.c:242 > mgmt_index_removed+0x10d/0x2f0 net/bluetooth/mgmt.c:9362 > hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1307 > __sys_bind_socket net/socket.c:1810 [inline] > __sys_bind+0x2c3/0x3e0 net/socket.c:1841 > __do_sys_bind net/socket.c:1846 [inline] > __se_sys_bind net/socket.c:1844 [inline] > __x64_sys_bind+0x7a/0x90 net/socket.c:1844 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Fixes: a380b6cff1a2 ("Bluetooth: Add generic mgmt helper API") > Closes: https://syzkaller.appspot.com/bug?extid=feb0dc579bbe30a13190 > Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru> > Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > --- > net/bluetooth/mgmt_util.c | 25 +++++++++++++++---------- > 1 file changed, 15 insertions(+), 10 deletions(-) > > diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c > index 3713ff490c65..c2dc8ddf5f78 100644 > --- a/net/bluetooth/mgmt_util.c > +++ b/net/bluetooth/mgmt_util.c > @@ -219,13 +219,20 @@ struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, > { > struct mgmt_pending_cmd *cmd; > > - list_for_each_entry(cmd, &hdev->mgmt_pending, list) { > + rcu_read_lock(); > + > + list_for_each_entry_rcu(cmd, &hdev->mgmt_pending, list) { > if (hci_sock_get_channel(cmd->sk) != channel) > continue; > - if (cmd->opcode == opcode) > + > + if (cmd->opcode == opcode) { > + rcu_read_unlock(); > return cmd; > + } > } > > + rcu_read_unlock(); > + > return NULL; > } > > @@ -233,14 +240,11 @@ void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, > void (*cb)(struct mgmt_pending_cmd *cmd, void *data), > void *data) > { > - struct mgmt_pending_cmd *cmd, *tmp; > - > - list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { > - if (opcode > 0 && cmd->opcode != opcode) > - continue; > + struct mgmt_pending_cmd *cmd; > > + cmd = mgmt_pending_find(HCI_CHANNEL_CONTROL, opcode, hdev); > + if (cmd) > cb(cmd, data); > - } > } > > struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, > @@ -280,7 +284,7 @@ struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, > if (!cmd) > return NULL; > > - list_add_tail(&cmd->list, &hdev->mgmt_pending); > + list_add_tail_rcu(&cmd->list, &hdev->mgmt_pending); > > return cmd; > } > @@ -294,7 +298,8 @@ void mgmt_pending_free(struct mgmt_pending_cmd *cmd) > > void mgmt_pending_remove(struct mgmt_pending_cmd *cmd) > { > - list_del(&cmd->list); > + list_del_rcu(&cmd->list); > + synchronize_rcu(); > mgmt_pending_free(cmd); > } > > -- > 2.49.0 > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock 2025-05-14 4:27 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3) syzbot ` (4 preceding siblings ...) 2025-05-28 19:03 ` [syzbot] Re: [PATCH v1] Bluetooth: MGMT: Use RCU-protected in mgmt_pending list syzbot @ 2025-06-02 18:00 ` syzbot 2025-06-03 20:30 ` [syzbot] Re: [PATCH v4 1/2] Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete syzbot 6 siblings, 0 replies; 10+ messages in thread From: syzbot @ 2025-06-02 18:00 UTC (permalink / raw) To: linux-kernel, syzkaller-bugs For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock Author: luiz.dentz@gmail.com #syz test On Mon, Jun 2, 2025 at 1:46 PM Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > This uses a mutex to protect from concurrent access of mgmt_pending > list which can cause crashes like: > > ================================================================== > BUG: KASAN: slab-use-after-free in mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405 > Read of size 8 at addr ffff888048891a18 by task kworker/u5:8/5333 > > CPU: 0 UID: 0 PID: 5333 Comm: kworker/u5:8 Not tainted 6.15.0-rc5-syzkaller-00197-gea34704d6ad7 #0 PREEMPT(full) > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 > Workqueue: hci0 hci_cmd_sync_work > Call Trace: > <TASK> > dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 > print_address_description mm/kasan/report.c:408 [inline] > print_report+0xb4/0x290 mm/kasan/report.c:521 > kasan_report+0x118/0x150 mm/kasan/report.c:634 > mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405 > hci_cmd_sync_work+0x25e/0x3a0 net/bluetooth/hci_sync.c:334 > process_one_work kernel/workqueue.c:3238 [inline] > process_scheduled_works+0xadb/0x17a0 kernel/workqueue.c:3319 > worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400 > kthread+0x70e/0x8a0 kernel/kthread.c:464 > ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:153 > ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 > </TASK> > > Allocated by task 5702: > kasan_save_stack mm/kasan/common.c:47 [inline] > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > poison_kmalloc_redzone mm/kasan/common.c:377 [inline] > __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394 > kasan_kmalloc include/linux/kasan.h:260 [inline] > __kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4358 > kmalloc_noprof include/linux/slab.h:905 [inline] > kzalloc_noprof include/linux/slab.h:1039 [inline] > mgmt_pending_new+0x65/0x240 net/bluetooth/mgmt_util.c:252 > mgmt_pending_add+0x34/0x120 net/bluetooth/mgmt_util.c:279 > remove_adv_monitor+0x103/0x1b0 net/bluetooth/mgmt.c:5453 > hci_mgmt_cmd+0x9c6/0xef0 net/bluetooth/hci_sock.c:1712 > hci_sock_sendmsg+0x6ca/0xee0 net/bluetooth/hci_sock.c:1832 > sock_sendmsg_nosec net/socket.c:712 [inline] > __sock_sendmsg+0x219/0x270 net/socket.c:727 > sock_write_iter+0x258/0x330 net/socket.c:1131 > new_sync_write fs/read_write.c:591 [inline] > vfs_write+0x548/0xa90 fs/read_write.c:684 > ksys_write+0x145/0x250 fs/read_write.c:736 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Freed by task 5700: > kasan_save_stack mm/kasan/common.c:47 [inline] > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576 > poison_slab_object mm/kasan/common.c:247 [inline] > __kasan_slab_free+0x62/0x70 mm/kasan/common.c:264 > kasan_slab_free include/linux/kasan.h:233 [inline] > slab_free_hook mm/slub.c:2380 [inline] > slab_free mm/slub.c:4642 [inline] > kfree+0x193/0x440 mm/slub.c:4841 > mgmt_pending_foreach+0xc9/0x120 net/bluetooth/mgmt_util.c:242 > mgmt_index_removed+0x10d/0x2f0 net/bluetooth/mgmt.c:9362 > hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1307 > __sys_bind_socket net/socket.c:1810 [inline] > __sys_bind+0x2c3/0x3e0 net/socket.c:1841 > __do_sys_bind net/socket.c:1846 [inline] > __se_sys_bind net/socket.c:1844 [inline] > __x64_sys_bind+0x7a/0x90 net/socket.c:1844 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Fixes: a380b6cff1a2 ("Bluetooth: Add generic mgmt helper API") > Closes: https://syzkaller.appspot.com/bug?extid=feb0dc579bbe30a13190 > Closes: https://syzkaller.appspot.com/bug?extid=0a7039d5d9986ff4ececi > Closes: https://syzkaller.appspot.com/bug?extid=cc0cc52e7f43dc9e6df1 > Reported-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com > Tested-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com > Tested-by: syzbot+0a7039d5d9986ff4ecec@syzkaller.appspotmail.com > Tested-by: syzbot+cc0cc52e7f43dc9e6df1@syzkaller.appspotmail.com > Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru> > Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > --- > include/net/bluetooth/hci_core.h | 1 + > net/bluetooth/hci_core.c | 1 + > net/bluetooth/mgmt.c | 101 +++++++++++++++---------------- > net/bluetooth/mgmt_util.c | 32 ++++++++-- > net/bluetooth/mgmt_util.h | 4 +- > 5 files changed, 80 insertions(+), 59 deletions(-) > > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h > index 2b261e74e2c4..b9ff0e825071 100644 > --- a/include/net/bluetooth/hci_core.h > +++ b/include/net/bluetooth/hci_core.h > @@ -546,6 +546,7 @@ struct hci_dev { > struct hci_conn_hash conn_hash; > > struct list_head mesh_pending; > + struct mutex mgmt_pending_lock; > struct list_head mgmt_pending; > struct list_head reject_list; > struct list_head accept_list; > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c > index 04845ff3ad57..f197f5497043 100644 > --- a/net/bluetooth/hci_core.c > +++ b/net/bluetooth/hci_core.c > @@ -2487,6 +2487,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) > > mutex_init(&hdev->lock); > mutex_init(&hdev->req_lock); > + mutex_init(&hdev->mgmt_pending_lock); > > ida_init(&hdev->unset_handle_ida); > > diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c > index 14a9462fced5..7d9ed7db377f 100644 > --- a/net/bluetooth/mgmt.c > +++ b/net/bluetooth/mgmt.c > @@ -1447,22 +1447,17 @@ static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data) > > send_settings_rsp(cmd->sk, cmd->opcode, match->hdev); > > - list_del(&cmd->list); > - > if (match->sk == NULL) { > match->sk = cmd->sk; > sock_hold(match->sk); > } > - > - mgmt_pending_free(cmd); > } > > static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data) > { > u8 *status = data; > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status); > - mgmt_pending_remove(cmd); > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status); > } > > static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) > @@ -1476,8 +1471,6 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) > > if (cmd->cmd_complete) { > cmd->cmd_complete(cmd, match->mgmt_status); > - mgmt_pending_remove(cmd); > - > return; > } > > @@ -1486,13 +1479,13 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) > > static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) > { > - return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, > + return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, > cmd->param, cmd->param_len); > } > > static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) > { > - return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, > + return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, > cmd->param, sizeof(struct mgmt_addr_info)); > } > > @@ -1532,7 +1525,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data, > > if (err) { > u8 mgmt_err = mgmt_status(err); > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); > goto done; > } > @@ -1707,7 +1700,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data, > > if (err) { > u8 mgmt_err = mgmt_status(err); > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > goto done; > } > > @@ -1943,8 +1936,8 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) > new_settings(hdev, NULL); > } > > - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp, > - &mgmt_err); > + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, > + cmd_status_rsp, &mgmt_err); > return; > } > > @@ -1954,7 +1947,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) > changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED); > } > > - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match); > + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, settings_rsp, &match); > > if (changed) > new_settings(hdev, match.sk); > @@ -2074,12 +2067,12 @@ static void set_le_complete(struct hci_dev *hdev, void *data, int err) > bt_dev_dbg(hdev, "err %d", err); > > if (status) { > - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp, > - &status); > + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, cmd_status_rsp, > + &status); > return; > } > > - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match); > + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, settings_rsp, &match); > > new_settings(hdev, match.sk); > > @@ -2138,7 +2131,7 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err) > struct sock *sk = cmd->sk; > > if (status) { > - mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, > + mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true, > cmd_status_rsp, &status); > return; > } > @@ -2638,7 +2631,7 @@ static void mgmt_class_complete(struct hci_dev *hdev, void *data, int err) > > bt_dev_dbg(hdev, "err %d", err); > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(err), hdev->dev_class, 3); > > mgmt_pending_free(cmd); > @@ -3427,7 +3420,7 @@ static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status) > bacpy(&rp.addr.bdaddr, &conn->dst); > rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); > > - err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, > + err = mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_PAIR_DEVICE, > status, &rp, sizeof(rp)); > > /* So we don't get further callbacks for this connection */ > @@ -5196,7 +5189,7 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, > hci_update_passive_scan(hdev); > } > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(status), &rp, sizeof(rp)); > mgmt_pending_remove(cmd); > > @@ -5411,7 +5404,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, > if (!status) > hci_update_passive_scan(hdev); > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(status), &rp, sizeof(rp)); > mgmt_pending_remove(cmd); > > @@ -5792,7 +5785,7 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err) > cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev)) > return; > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), > cmd->param, 1); > mgmt_pending_remove(cmd); > > @@ -6013,7 +6006,7 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err) > > bt_dev_dbg(hdev, "err %d", err); > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), > cmd->param, 1); > mgmt_pending_remove(cmd); > > @@ -6238,7 +6231,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) > u8 status = mgmt_status(err); > > if (status) { > - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, > + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, > cmd_status_rsp, &status); > return; > } > @@ -6248,7 +6241,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) > else > hci_dev_clear_flag(hdev, HCI_ADVERTISING); > > - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp, > + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, settings_rsp, > &match); > > new_settings(hdev, match.sk); > @@ -6592,7 +6585,7 @@ static void set_bredr_complete(struct hci_dev *hdev, void *data, int err) > */ > hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED); > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > } else { > send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev); > new_settings(hdev, cmd->sk); > @@ -6729,7 +6722,7 @@ static void set_secure_conn_complete(struct hci_dev *hdev, void *data, int err) > if (err) { > u8 mgmt_err = mgmt_status(err); > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > goto done; > } > > @@ -7176,7 +7169,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err) > rp.max_tx_power = HCI_TX_POWER_INVALID; > } > > - mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status, > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status, > &rp, sizeof(rp)); > > mgmt_pending_free(cmd); > @@ -7336,7 +7329,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err) > } > > complete: > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp, > sizeof(rp)); > > mgmt_pending_free(cmd); > @@ -8586,10 +8579,10 @@ static void add_advertising_complete(struct hci_dev *hdev, void *data, int err) > rp.instance = cp->instance; > > if (err) > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(err)); > else > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(err), &rp, sizeof(rp)); > > add_adv_complete(hdev, cmd->sk, cp->instance, err); > @@ -8777,10 +8770,10 @@ static void add_ext_adv_params_complete(struct hci_dev *hdev, void *data, > > hci_remove_adv_instance(hdev, cp->instance); > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(err)); > } else { > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(err), &rp, sizeof(rp)); > } > > @@ -8927,10 +8920,10 @@ static void add_ext_adv_data_complete(struct hci_dev *hdev, void *data, int err) > rp.instance = cp->instance; > > if (err) > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(err)); > else > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(err), &rp, sizeof(rp)); > > mgmt_pending_free(cmd); > @@ -9089,10 +9082,10 @@ static void remove_advertising_complete(struct hci_dev *hdev, void *data, > rp.instance = cp->instance; > > if (err) > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > mgmt_status(err)); > else > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); > > mgmt_pending_free(cmd); > @@ -9364,7 +9357,7 @@ void mgmt_index_removed(struct hci_dev *hdev) > if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) > return; > > - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); > + mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); > > if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { > mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, > @@ -9402,7 +9395,8 @@ void mgmt_power_on(struct hci_dev *hdev, int err) > hci_update_passive_scan(hdev); > } > > - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); > + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, > + &match); > > new_settings(hdev, match.sk); > > @@ -9417,7 +9411,8 @@ void __mgmt_power_off(struct hci_dev *hdev) > struct cmd_lookup match = { NULL, hdev }; > u8 zero_cod[] = { 0, 0, 0 }; > > - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); > + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, > + &match); > > /* If the power off is because of hdev unregistration let > * use the appropriate INVALID_INDEX status. Otherwise use > @@ -9431,7 +9426,7 @@ void __mgmt_power_off(struct hci_dev *hdev) > else > match.mgmt_status = MGMT_STATUS_NOT_POWERED; > > - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); > + mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); > > if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) { > mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, > @@ -9672,7 +9667,6 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data) > device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk); > > cmd->cmd_complete(cmd, 0); > - mgmt_pending_remove(cmd); > } > > bool mgmt_powering_down(struct hci_dev *hdev) > @@ -9728,8 +9722,8 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, > struct mgmt_cp_disconnect *cp; > struct mgmt_pending_cmd *cmd; > > - mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, > - hdev); > + mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, true, > + unpair_device_rsp, hdev); > > cmd = pending_find(MGMT_OP_DISCONNECT, hdev); > if (!cmd) > @@ -9922,7 +9916,7 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) > > if (status) { > u8 mgmt_err = mgmt_status(status); > - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, > + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, > cmd_status_rsp, &mgmt_err); > return; > } > @@ -9932,8 +9926,8 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) > else > changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY); > > - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp, > - &match); > + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, > + settings_rsp, &match); > > if (changed) > new_settings(hdev, match.sk); > @@ -9957,9 +9951,12 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, > { > struct cmd_lookup match = { NULL, hdev, mgmt_status(status) }; > > - mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match); > - mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match); > - mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match); > + mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, false, sk_lookup, > + &match); > + mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, false, sk_lookup, > + &match); > + mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, false, sk_lookup, > + &match); > > if (!status) { > mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, > diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c > index 3713ff490c65..a88a07da3947 100644 > --- a/net/bluetooth/mgmt_util.c > +++ b/net/bluetooth/mgmt_util.c > @@ -217,30 +217,47 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, > struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, > struct hci_dev *hdev) > { > - struct mgmt_pending_cmd *cmd; > + struct mgmt_pending_cmd *cmd, *tmp; > > - list_for_each_entry(cmd, &hdev->mgmt_pending, list) { > + mutex_lock(&hdev->mgmt_pending_lock); > + > + list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { > if (hci_sock_get_channel(cmd->sk) != channel) > continue; > - if (cmd->opcode == opcode) > + > + if (cmd->opcode == opcode) { > + mutex_unlock(&hdev->mgmt_pending_lock); > return cmd; > + } > } > > + mutex_unlock(&hdev->mgmt_pending_lock); > + > return NULL; > } > > -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, > +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, > void (*cb)(struct mgmt_pending_cmd *cmd, void *data), > void *data) > { > struct mgmt_pending_cmd *cmd, *tmp; > > + mutex_lock(&hdev->mgmt_pending_lock); > + > list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { > if (opcode > 0 && cmd->opcode != opcode) > continue; > > + if (remove) > + list_del(&cmd->list); > + > cb(cmd, data); > + > + if (remove) > + mgmt_pending_free(cmd); > } > + > + mutex_unlock(&hdev->mgmt_pending_lock); > } > > struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, > @@ -254,7 +271,7 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, > return NULL; > > cmd->opcode = opcode; > - cmd->index = hdev->id; > + cmd->hdev = hdev; > > cmd->param = kmemdup(data, len, GFP_KERNEL); > if (!cmd->param) { > @@ -280,7 +297,9 @@ struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, > if (!cmd) > return NULL; > > + mutex_lock(&hdev->mgmt_pending_lock); > list_add_tail(&cmd->list, &hdev->mgmt_pending); > + mutex_unlock(&hdev->mgmt_pending_lock); > > return cmd; > } > @@ -294,7 +313,10 @@ void mgmt_pending_free(struct mgmt_pending_cmd *cmd) > > void mgmt_pending_remove(struct mgmt_pending_cmd *cmd) > { > + mutex_lock(&cmd->hdev->mgmt_pending_lock); > list_del(&cmd->list); > + mutex_unlock(&cmd->hdev->mgmt_pending_lock); > + > mgmt_pending_free(cmd); > } > > diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h > index f2ba994ab1d8..024e51dd6937 100644 > --- a/net/bluetooth/mgmt_util.h > +++ b/net/bluetooth/mgmt_util.h > @@ -33,7 +33,7 @@ struct mgmt_mesh_tx { > struct mgmt_pending_cmd { > struct list_head list; > u16 opcode; > - int index; > + struct hci_dev *hdev; > void *param; > size_t param_len; > struct sock *sk; > @@ -54,7 +54,7 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, > > struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, > struct hci_dev *hdev); > -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, > +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, > void (*cb)(struct mgmt_pending_cmd *cmd, void *data), > void *data); > struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, > -- > 2.49.0 > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [syzbot] Re: [PATCH v4 1/2] Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete 2025-05-14 4:27 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3) syzbot ` (5 preceding siblings ...) 2025-06-02 18:00 ` [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock syzbot @ 2025-06-03 20:30 ` syzbot 6 siblings, 0 replies; 10+ messages in thread From: syzbot @ 2025-06-03 20:30 UTC (permalink / raw) To: linux-kernel, syzkaller-bugs For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: Re: [PATCH v4 1/2] Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete Author: luiz.dentz@gmail.com #syz test On Tue, Jun 3, 2025 at 4:29 PM Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > This reworks MGMT_OP_REMOVE_ADV_MONITOR to not use mgmt_pending_add to > avoid crashes like bellow: > > ================================================================== > BUG: KASAN: slab-use-after-free in mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5406 > Read of size 8 at addr ffff88801c53f318 by task kworker/u5:5/5341 > > CPU: 0 UID: 0 PID: 5341 Comm: kworker/u5:5 Not tainted 6.15.0-syzkaller-10402-g4cb6c8af8591 #0 PREEMPT(full) > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 > Workqueue: hci0 hci_cmd_sync_work > Call Trace: > <TASK> > dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 > print_address_description mm/kasan/report.c:408 [inline] > print_report+0xd2/0x2b0 mm/kasan/report.c:521 > kasan_report+0x118/0x150 mm/kasan/report.c:634 > mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5406 > hci_cmd_sync_work+0x261/0x3a0 net/bluetooth/hci_sync.c:334 > process_one_work kernel/workqueue.c:3238 [inline] > process_scheduled_works+0xade/0x17b0 kernel/workqueue.c:3321 > worker_thread+0x8a0/0xda0 kernel/workqueue.c:3402 > kthread+0x711/0x8a0 kernel/kthread.c:464 > ret_from_fork+0x3fc/0x770 arch/x86/kernel/process.c:148 > ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 > </TASK> > > Allocated by task 5987: > kasan_save_stack mm/kasan/common.c:47 [inline] > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > poison_kmalloc_redzone mm/kasan/common.c:377 [inline] > __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394 > kasan_kmalloc include/linux/kasan.h:260 [inline] > __kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4358 > kmalloc_noprof include/linux/slab.h:905 [inline] > kzalloc_noprof include/linux/slab.h:1039 [inline] > mgmt_pending_new+0x65/0x240 net/bluetooth/mgmt_util.c:252 > mgmt_pending_add+0x34/0x120 net/bluetooth/mgmt_util.c:279 > remove_adv_monitor+0x103/0x1b0 net/bluetooth/mgmt.c:5454 > hci_mgmt_cmd+0x9c9/0xef0 net/bluetooth/hci_sock.c:1719 > hci_sock_sendmsg+0x6ca/0xef0 net/bluetooth/hci_sock.c:1839 > sock_sendmsg_nosec net/socket.c:712 [inline] > __sock_sendmsg+0x219/0x270 net/socket.c:727 > sock_write_iter+0x258/0x330 net/socket.c:1131 > new_sync_write fs/read_write.c:593 [inline] > vfs_write+0x548/0xa90 fs/read_write.c:686 > ksys_write+0x145/0x250 fs/read_write.c:738 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Freed by task 5989: > kasan_save_stack mm/kasan/common.c:47 [inline] > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576 > poison_slab_object mm/kasan/common.c:247 [inline] > __kasan_slab_free+0x62/0x70 mm/kasan/common.c:264 > kasan_slab_free include/linux/kasan.h:233 [inline] > slab_free_hook mm/slub.c:2380 [inline] > slab_free mm/slub.c:4642 [inline] > kfree+0x18e/0x440 mm/slub.c:4841 > mgmt_pending_foreach+0xc9/0x120 net/bluetooth/mgmt_util.c:242 > mgmt_index_removed+0x10d/0x2f0 net/bluetooth/mgmt.c:9366 > hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1314 > __sys_bind_socket net/socket.c:1810 [inline] > __sys_bind+0x2c3/0x3e0 net/socket.c:1841 > __do_sys_bind net/socket.c:1846 [inline] > __se_sys_bind net/socket.c:1844 [inline] > __x64_sys_bind+0x7a/0x90 net/socket.c:1844 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > Fixes: 66bd095ab5d4 ("Bluetooth: advmon offload MSFT remove monitor") > Closes: https://syzkaller.appspot.com/bug?extid=feb0dc579bbe30a13190 > Reported-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com > Tested-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com > Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > --- > include/net/bluetooth/hci_core.h | 1 - > net/bluetooth/hci_core.c | 4 +--- > net/bluetooth/mgmt.c | 37 ++++++++++---------------------- > 3 files changed, 12 insertions(+), 30 deletions(-) > > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h > index 2b261e74e2c4..93fcb659f0d4 100644 > --- a/include/net/bluetooth/hci_core.h > +++ b/include/net/bluetooth/hci_core.h > @@ -2400,7 +2400,6 @@ void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev, > u8 instance); > void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev, > u8 instance); > -void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle); > int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip); > void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle, > bdaddr_t *bdaddr, u8 addr_type); > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c > index 04845ff3ad57..aeda2e4557d5 100644 > --- a/net/bluetooth/hci_core.c > +++ b/net/bluetooth/hci_core.c > @@ -1877,10 +1877,8 @@ void hci_free_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor) > if (monitor->handle) > idr_remove(&hdev->adv_monitors_idr, monitor->handle); > > - if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) { > + if (monitor->state != ADV_MONITOR_STATE_NOT_REGISTERED) > hdev->adv_monitors_cnt--; > - mgmt_adv_monitor_removed(hdev, monitor->handle); > - } > > kfree(monitor); > } > diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c > index 14a9462fced5..feaeec2423ae 100644 > --- a/net/bluetooth/mgmt.c > +++ b/net/bluetooth/mgmt.c > @@ -5108,24 +5108,14 @@ static void mgmt_adv_monitor_added(struct sock *sk, struct hci_dev *hdev, > mgmt_event(MGMT_EV_ADV_MONITOR_ADDED, hdev, &ev, sizeof(ev), sk); > } > > -void mgmt_adv_monitor_removed(struct hci_dev *hdev, u16 handle) > +static void mgmt_adv_monitor_removed(struct sock *sk, struct hci_dev *hdev, > + u16 handle) > { > struct mgmt_ev_adv_monitor_removed ev; > - struct mgmt_pending_cmd *cmd; > - struct sock *sk_skip = NULL; > - struct mgmt_cp_remove_adv_monitor *cp; > - > - cmd = pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev); > - if (cmd) { > - cp = cmd->param; > - > - if (cp->monitor_handle) > - sk_skip = cmd->sk; > - } > > ev.monitor_handle = cpu_to_le16(handle); > > - mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk_skip); > + mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk); > } > > static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev, > @@ -5227,8 +5217,7 @@ static int __add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, > > if (pending_find(MGMT_OP_SET_LE, hdev) || > pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) || > - pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev) || > - pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) { > + pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) { > status = MGMT_STATUS_BUSY; > goto unlock; > } > @@ -5398,8 +5387,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, > struct mgmt_pending_cmd *cmd = data; > struct mgmt_cp_remove_adv_monitor *cp; > > - if (status == -ECANCELED || > - cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) > + if (status == -ECANCELED) > return; > > hci_dev_lock(hdev); > @@ -5408,12 +5396,14 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, > > rp.monitor_handle = cp->monitor_handle; > > - if (!status) > + if (!status) { > + mgmt_adv_monitor_removed(cmd->sk, hdev, cp->monitor_handle); > hci_update_passive_scan(hdev); > + } > > mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > mgmt_status(status), &rp, sizeof(rp)); > - mgmt_pending_remove(cmd); > + mgmt_pending_free(cmd); > > hci_dev_unlock(hdev); > bt_dev_dbg(hdev, "remove monitor %d complete, status %d", > @@ -5423,10 +5413,6 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, > static int mgmt_remove_adv_monitor_sync(struct hci_dev *hdev, void *data) > { > struct mgmt_pending_cmd *cmd = data; > - > - if (cmd != pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev)) > - return -ECANCELED; > - > struct mgmt_cp_remove_adv_monitor *cp = cmd->param; > u16 handle = __le16_to_cpu(cp->monitor_handle); > > @@ -5445,14 +5431,13 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev, > hci_dev_lock(hdev); > > if (pending_find(MGMT_OP_SET_LE, hdev) || > - pending_find(MGMT_OP_REMOVE_ADV_MONITOR, hdev) || > pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR, hdev) || > pending_find(MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI, hdev)) { > status = MGMT_STATUS_BUSY; > goto unlock; > } > > - cmd = mgmt_pending_add(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len); > + cmd = mgmt_pending_new(sk, MGMT_OP_REMOVE_ADV_MONITOR, hdev, data, len); > if (!cmd) { > status = MGMT_STATUS_NO_RESOURCES; > goto unlock; > @@ -5462,7 +5447,7 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev, > mgmt_remove_adv_monitor_complete); > > if (err) { > - mgmt_pending_remove(cmd); > + mgmt_pending_free(cmd); > > if (err == -ENOMEM) > status = MGMT_STATUS_NO_RESOURCES; > -- > 2.49.0 > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
* [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_sock_get_channel
@ 2025-05-25 7:44 syzbot
2025-06-02 18:01 ` [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock syzbot
0 siblings, 1 reply; 10+ messages in thread
From: syzbot @ 2025-05-25 7:44 UTC (permalink / raw)
To: johan.hedberg, linux-bluetooth, linux-kernel, luiz.dentz, marcel,
syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: 187899f4124a Merge branch 'for-next/core' into for-kernelci
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-kernelci
console output: https://syzkaller.appspot.com/x/log.txt?x=14e5a0e8580000
kernel config: https://syzkaller.appspot.com/x/.config?x=770ccfad24d7220
dashboard link: https://syzkaller.appspot.com/bug?extid=0a7039d5d9986ff4ecec
compiler: Debian clang version 20.1.2 (++20250402124445+58df0ef89dd6-1~exp1~20250402004600.97), Debian LLD 20.1.2
userspace arch: arm64
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1648fe70580000
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/d14028020c58/disk-187899f4.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/5416eb354254/vmlinux-187899f4.xz
kernel image: https://storage.googleapis.com/syzbot-assets/02cbbb8d7877/Image-187899f4.gz.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+0a7039d5d9986ff4ecec@syzkaller.appspotmail.com
===================================
==================================================================
BUG: KASAN: slab-use-after-free in hci_sock_get_channel+0x60/0x68 net/bluetooth/hci_sock.c:91
Read of size 2 at addr ffff0000c48885b2 by task syz.4.334/7318
CPU: 0 UID: 0 PID: 7318 Comm: syz.4.334 Not tainted 6.15.0-rc7-syzkaller-g187899f4124a #0 PREEMPT
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
Call trace:
show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:466 (C)
__dump_stack+0x30/0x40 lib/dump_stack.c:94
dump_stack_lvl+0xd8/0x12c lib/dump_stack.c:120
print_address_description+0xa8/0x254 mm/kasan/report.c:408
print_report+0x68/0x84 mm/kasan/report.c:521
kasan_report+0xb0/0x110 mm/kasan/report.c:634
__asan_report_load2_noabort+0x20/0x2c mm/kasan/report_generic.c:379
hci_sock_get_channel+0x60/0x68 net/bluetooth/hci_sock.c:91
mgmt_pending_find+0x7c/0x140 net/bluetooth/mgmt_util.c:223
pending_find net/bluetooth/mgmt.c:947 [inline]
remove_adv_monitor+0x44/0x1a4 net/bluetooth/mgmt.c:5445
hci_mgmt_cmd+0x780/0xc00 net/bluetooth/hci_sock.c:1712
hci_sock_sendmsg+0x544/0xbb0 net/bluetooth/hci_sock.c:1832
sock_sendmsg_nosec net/socket.c:712 [inline]
__sock_sendmsg net/socket.c:727 [inline]
sock_write_iter+0x25c/0x378 net/socket.c:1131
new_sync_write fs/read_write.c:591 [inline]
vfs_write+0x62c/0x97c fs/read_write.c:684
ksys_write+0x120/0x210 fs/read_write.c:736
__do_sys_write fs/read_write.c:747 [inline]
__se_sys_write fs/read_write.c:744 [inline]
__arm64_sys_write+0x7c/0x90 fs/read_write.c:744
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x98/0x2b8 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+0x58/0x17c arch/arm64/kernel/entry-common.c:767
el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:786
el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600
Allocated by task 7037:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x40/0x78 mm/kasan/common.c:68
kasan_save_alloc_info+0x44/0x54 mm/kasan/generic.c:562
poison_kmalloc_redzone mm/kasan/common.c:377 [inline]
__kasan_kmalloc+0x9c/0xb4 mm/kasan/common.c:394
kasan_kmalloc include/linux/kasan.h:260 [inline]
__do_kmalloc_node mm/slub.c:4327 [inline]
__kmalloc_noprof+0x2fc/0x4c8 mm/slub.c:4339
kmalloc_noprof include/linux/slab.h:909 [inline]
sk_prot_alloc+0xc4/0x1f0 net/core/sock.c:2198
sk_alloc+0x44/0x3ac net/core/sock.c:2254
bt_sock_alloc+0x4c/0x300 net/bluetooth/af_bluetooth.c:148
hci_sock_create+0xa8/0x194 net/bluetooth/hci_sock.c:2202
bt_sock_create+0x14c/0x24c net/bluetooth/af_bluetooth.c:132
__sock_create+0x43c/0x91c net/socket.c:1541
sock_create net/socket.c:1599 [inline]
__sys_socket_create net/socket.c:1636 [inline]
__sys_socket+0xd4/0x1c0 net/socket.c:1683
__do_sys_socket net/socket.c:1697 [inline]
__se_sys_socket net/socket.c:1695 [inline]
__arm64_sys_socket+0x7c/0x94 net/socket.c:1695
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x98/0x2b8 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+0x58/0x17c arch/arm64/kernel/entry-common.c:767
el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:786
el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600
Freed by task 6607:
kasan_save_stack mm/kasan/common.c:47 [inline]
kasan_save_track+0x40/0x78 mm/kasan/common.c:68
kasan_save_free_info+0x58/0x70 mm/kasan/generic.c:576
poison_slab_object mm/kasan/common.c:247 [inline]
__kasan_slab_free+0x68/0x88 mm/kasan/common.c:264
kasan_slab_free include/linux/kasan.h:233 [inline]
slab_free_hook mm/slub.c:2380 [inline]
slab_free mm/slub.c:4642 [inline]
kfree+0x17c/0x474 mm/slub.c:4841
sk_prot_free net/core/sock.c:2237 [inline]
__sk_destruct+0x4f4/0x760 net/core/sock.c:2332
sk_destruct net/core/sock.c:2360 [inline]
__sk_free+0x320/0x430 net/core/sock.c:2371
sk_free+0x60/0xc8 net/core/sock.c:2382
sock_put include/net/sock.h:1944 [inline]
mgmt_pending_free+0x88/0x118 net/bluetooth/mgmt_util.c:290
mgmt_pending_remove+0xec/0x104 net/bluetooth/mgmt_util.c:298
mgmt_set_powered_complete+0x418/0x5cc net/bluetooth/mgmt.c:1355
hci_cmd_sync_work+0x204/0x33c net/bluetooth/hci_sync.c:334
process_one_work+0x7e8/0x156c kernel/workqueue.c:3238
process_scheduled_works kernel/workqueue.c:3319 [inline]
worker_thread+0x958/0xed8 kernel/workqueue.c:3400
kthread+0x5fc/0x75c kernel/kthread.c:464
ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:847
The buggy address belongs to the object at ffff0000c4888000
which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 1458 bytes inside of
freed 2048-byte region [ffff0000c4888000, ffff0000c4888800)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x104888
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x5ffc00000000040(head|node=0|zone=2|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 05ffc00000000040 ffff0000c0002000 fffffdffc3279400 0000000000000002
raw: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000
head: 05ffc00000000040 ffff0000c0002000 fffffdffc3279400 0000000000000002
head: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000
head: 05ffc00000000003 fffffdffc3122201 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff0000c4888480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff0000c4888500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff0000c4888580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff0000c4888600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff0000c4888680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
Unable to handle kernel paging request at virtual address dfff8000000000b6
KASAN: null-ptr-deref in range [0x00000000000005b0-0x00000000000005b7]
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[dfff8000000000b6] address between user and kernel address ranges
Internal error: Oops: 0000000096000005 [#1] SMP
Modules linked in:
CPU: 0 UID: 0 PID: 7318 Comm: syz.4.334 Tainted: G B 6.15.0-rc7-syzkaller-g187899f4124a #0 PREEMPT
Tainted: [B]=BAD_PAGE
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025
pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : hci_sock_get_channel+0x28/0x68 net/bluetooth/hci_sock.c:91
lr : hci_sock_get_channel+0x18/0x68 net/bluetooth/hci_sock.c:90
sp : ffff80009f3477a0
x29: ffff80009f3477a0 x28: 0000000000000000 x27: ffff80008d84e588
x26: ffff0000d7944000 x25: 0000000000000002 x24: dfff800000000000
x23: ffff0000c2586528 x22: 000000000000000d x21: 0000000000000003
x20: ffff0000c2586500 x19: 0000000000000000 x18: 1fffe0003386aa76
x17: 0000000000000000 x16: ffff80008ad27e48 x15: 0000000000000001
x14: 1ffff00012553cfc x13: 0000000000000000 x12: 0000000000000000
x11: ffff700012553cfd x10: dfff800000000000 x9 : 00000000000000b6
x8 : 00000000000005b2 x7 : 0000000000000001 x6 : 0000000000000001
x5 : ffff80009f347018 x4 : ffff80008f415ba0 x3 : ffff80008a076e80
x2 : 0000000000000000 x1 : 0000000000000008 x0 : 0000000000000000
Call trace:
hci_sock_get_channel+0x28/0x68 net/bluetooth/hci_sock.c:91 (P)
mgmt_pending_find+0x7c/0x140 net/bluetooth/mgmt_util.c:223
pending_find net/bluetooth/mgmt.c:947 [inline]
remove_adv_monitor+0x44/0x1a4 net/bluetooth/mgmt.c:5445
hci_mgmt_cmd+0x780/0xc00 net/bluetooth/hci_sock.c:1712
hci_sock_sendmsg+0x544/0xbb0 net/bluetooth/hci_sock.c:1832
sock_sendmsg_nosec net/socket.c:712 [inline]
__sock_sendmsg net/socket.c:727 [inline]
sock_write_iter+0x25c/0x378 net/socket.c:1131
new_sync_write fs/read_write.c:591 [inline]
vfs_write+0x62c/0x97c fs/read_write.c:684
ksys_write+0x120/0x210 fs/read_write.c:736
__do_sys_write fs/read_write.c:747 [inline]
__se_sys_write fs/read_write.c:744 [inline]
__arm64_sys_write+0x7c/0x90 fs/read_write.c:744
__invoke_syscall arch/arm64/kernel/syscall.c:35 [inline]
invoke_syscall+0x98/0x2b8 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+0x58/0x17c arch/arm64/kernel/entry-common.c:767
el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:786
el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600
Code: 9116ca68 d2d0000a d343fd09 f2fbffea (38ea6929)
---[ end trace 0000000000000000 ]---
----------------
Code disassembly (best guess):
0: 9116ca68 add x8, x19, #0x5b2
4: d2d0000a mov x10, #0x800000000000 // #140737488355328
8: d343fd09 lsr x9, x8, #3
c: f2fbffea movk x10, #0xdfff, lsl #48
* 10: 38ea6929 ldrsb w9, [x9, x10] <-- trapping instruction
---
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] 10+ messages in thread* Re: [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock 2025-05-25 7:44 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_sock_get_channel syzbot @ 2025-06-02 18:01 ` syzbot 0 siblings, 0 replies; 10+ messages in thread From: syzbot @ 2025-06-02 18:01 UTC (permalink / raw) To: linux-kernel, syzkaller-bugs For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock Author: luiz.dentz@gmail.com #syz test On Mon, Jun 2, 2025 at 2:00 PM Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > > #syz test > > On Mon, Jun 2, 2025 at 1:46 PM Luiz Augusto von Dentz > <luiz.dentz@gmail.com> wrote: > > > > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > > > This uses a mutex to protect from concurrent access of mgmt_pending > > list which can cause crashes like: > > > > ================================================================== > > BUG: KASAN: slab-use-after-free in mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405 > > Read of size 8 at addr ffff888048891a18 by task kworker/u5:8/5333 > > > > CPU: 0 UID: 0 PID: 5333 Comm: kworker/u5:8 Not tainted 6.15.0-rc5-syzkaller-00197-gea34704d6ad7 #0 PREEMPT(full) > > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 > > Workqueue: hci0 hci_cmd_sync_work > > Call Trace: > > <TASK> > > dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 > > print_address_description mm/kasan/report.c:408 [inline] > > print_report+0xb4/0x290 mm/kasan/report.c:521 > > kasan_report+0x118/0x150 mm/kasan/report.c:634 > > mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405 > > hci_cmd_sync_work+0x25e/0x3a0 net/bluetooth/hci_sync.c:334 > > process_one_work kernel/workqueue.c:3238 [inline] > > process_scheduled_works+0xadb/0x17a0 kernel/workqueue.c:3319 > > worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400 > > kthread+0x70e/0x8a0 kernel/kthread.c:464 > > ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:153 > > ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 > > </TASK> > > > > Allocated by task 5702: > > kasan_save_stack mm/kasan/common.c:47 [inline] > > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > > poison_kmalloc_redzone mm/kasan/common.c:377 [inline] > > __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394 > > kasan_kmalloc include/linux/kasan.h:260 [inline] > > __kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4358 > > kmalloc_noprof include/linux/slab.h:905 [inline] > > kzalloc_noprof include/linux/slab.h:1039 [inline] > > mgmt_pending_new+0x65/0x240 net/bluetooth/mgmt_util.c:252 > > mgmt_pending_add+0x34/0x120 net/bluetooth/mgmt_util.c:279 > > remove_adv_monitor+0x103/0x1b0 net/bluetooth/mgmt.c:5453 > > hci_mgmt_cmd+0x9c6/0xef0 net/bluetooth/hci_sock.c:1712 > > hci_sock_sendmsg+0x6ca/0xee0 net/bluetooth/hci_sock.c:1832 > > sock_sendmsg_nosec net/socket.c:712 [inline] > > __sock_sendmsg+0x219/0x270 net/socket.c:727 > > sock_write_iter+0x258/0x330 net/socket.c:1131 > > new_sync_write fs/read_write.c:591 [inline] > > vfs_write+0x548/0xa90 fs/read_write.c:684 > > ksys_write+0x145/0x250 fs/read_write.c:736 > > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > > do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94 > > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > > > Freed by task 5700: > > kasan_save_stack mm/kasan/common.c:47 [inline] > > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > > kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576 > > poison_slab_object mm/kasan/common.c:247 [inline] > > __kasan_slab_free+0x62/0x70 mm/kasan/common.c:264 > > kasan_slab_free include/linux/kasan.h:233 [inline] > > slab_free_hook mm/slub.c:2380 [inline] > > slab_free mm/slub.c:4642 [inline] > > kfree+0x193/0x440 mm/slub.c:4841 > > mgmt_pending_foreach+0xc9/0x120 net/bluetooth/mgmt_util.c:242 > > mgmt_index_removed+0x10d/0x2f0 net/bluetooth/mgmt.c:9362 > > hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1307 > > __sys_bind_socket net/socket.c:1810 [inline] > > __sys_bind+0x2c3/0x3e0 net/socket.c:1841 > > __do_sys_bind net/socket.c:1846 [inline] > > __se_sys_bind net/socket.c:1844 [inline] > > __x64_sys_bind+0x7a/0x90 net/socket.c:1844 > > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > > do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94 > > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > > > Fixes: a380b6cff1a2 ("Bluetooth: Add generic mgmt helper API") > > Closes: https://syzkaller.appspot.com/bug?extid=feb0dc579bbe30a13190 > > Closes: https://syzkaller.appspot.com/bug?extid=0a7039d5d9986ff4ececi > > Closes: https://syzkaller.appspot.com/bug?extid=cc0cc52e7f43dc9e6df1 > > Reported-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com > > Tested-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com > > Tested-by: syzbot+0a7039d5d9986ff4ecec@syzkaller.appspotmail.com > > Tested-by: syzbot+cc0cc52e7f43dc9e6df1@syzkaller.appspotmail.com > > Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru> > > Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > --- > > include/net/bluetooth/hci_core.h | 1 + > > net/bluetooth/hci_core.c | 1 + > > net/bluetooth/mgmt.c | 101 +++++++++++++++---------------- > > net/bluetooth/mgmt_util.c | 32 ++++++++-- > > net/bluetooth/mgmt_util.h | 4 +- > > 5 files changed, 80 insertions(+), 59 deletions(-) > > > > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h > > index 2b261e74e2c4..b9ff0e825071 100644 > > --- a/include/net/bluetooth/hci_core.h > > +++ b/include/net/bluetooth/hci_core.h > > @@ -546,6 +546,7 @@ struct hci_dev { > > struct hci_conn_hash conn_hash; > > > > struct list_head mesh_pending; > > + struct mutex mgmt_pending_lock; > > struct list_head mgmt_pending; > > struct list_head reject_list; > > struct list_head accept_list; > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c > > index 04845ff3ad57..f197f5497043 100644 > > --- a/net/bluetooth/hci_core.c > > +++ b/net/bluetooth/hci_core.c > > @@ -2487,6 +2487,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) > > > > mutex_init(&hdev->lock); > > mutex_init(&hdev->req_lock); > > + mutex_init(&hdev->mgmt_pending_lock); > > > > ida_init(&hdev->unset_handle_ida); > > > > diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c > > index 14a9462fced5..7d9ed7db377f 100644 > > --- a/net/bluetooth/mgmt.c > > +++ b/net/bluetooth/mgmt.c > > @@ -1447,22 +1447,17 @@ static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data) > > > > send_settings_rsp(cmd->sk, cmd->opcode, match->hdev); > > > > - list_del(&cmd->list); > > - > > if (match->sk == NULL) { > > match->sk = cmd->sk; > > sock_hold(match->sk); > > } > > - > > - mgmt_pending_free(cmd); > > } > > > > static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data) > > { > > u8 *status = data; > > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status); > > - mgmt_pending_remove(cmd); > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status); > > } > > > > static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) > > @@ -1476,8 +1471,6 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) > > > > if (cmd->cmd_complete) { > > cmd->cmd_complete(cmd, match->mgmt_status); > > - mgmt_pending_remove(cmd); > > - > > return; > > } > > > > @@ -1486,13 +1479,13 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) > > > > static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) > > { > > - return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, > > + return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, > > cmd->param, cmd->param_len); > > } > > > > static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) > > { > > - return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, > > + return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, > > cmd->param, sizeof(struct mgmt_addr_info)); > > } > > > > @@ -1532,7 +1525,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data, > > > > if (err) { > > u8 mgmt_err = mgmt_status(err); > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > > hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); > > goto done; > > } > > @@ -1707,7 +1700,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data, > > > > if (err) { > > u8 mgmt_err = mgmt_status(err); > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > > goto done; > > } > > > > @@ -1943,8 +1936,8 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) > > new_settings(hdev, NULL); > > } > > > > - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp, > > - &mgmt_err); > > + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, > > + cmd_status_rsp, &mgmt_err); > > return; > > } > > > > @@ -1954,7 +1947,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) > > changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED); > > } > > > > - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match); > > + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, settings_rsp, &match); > > > > if (changed) > > new_settings(hdev, match.sk); > > @@ -2074,12 +2067,12 @@ static void set_le_complete(struct hci_dev *hdev, void *data, int err) > > bt_dev_dbg(hdev, "err %d", err); > > > > if (status) { > > - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp, > > - &status); > > + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, cmd_status_rsp, > > + &status); > > return; > > } > > > > - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match); > > + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, settings_rsp, &match); > > > > new_settings(hdev, match.sk); > > > > @@ -2138,7 +2131,7 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err) > > struct sock *sk = cmd->sk; > > > > if (status) { > > - mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, > > + mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true, > > cmd_status_rsp, &status); > > return; > > } > > @@ -2638,7 +2631,7 @@ static void mgmt_class_complete(struct hci_dev *hdev, void *data, int err) > > > > bt_dev_dbg(hdev, "err %d", err); > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(err), hdev->dev_class, 3); > > > > mgmt_pending_free(cmd); > > @@ -3427,7 +3420,7 @@ static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status) > > bacpy(&rp.addr.bdaddr, &conn->dst); > > rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); > > > > - err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, > > + err = mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_PAIR_DEVICE, > > status, &rp, sizeof(rp)); > > > > /* So we don't get further callbacks for this connection */ > > @@ -5196,7 +5189,7 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, > > hci_update_passive_scan(hdev); > > } > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(status), &rp, sizeof(rp)); > > mgmt_pending_remove(cmd); > > > > @@ -5411,7 +5404,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, > > if (!status) > > hci_update_passive_scan(hdev); > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(status), &rp, sizeof(rp)); > > mgmt_pending_remove(cmd); > > > > @@ -5792,7 +5785,7 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err) > > cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev)) > > return; > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), > > cmd->param, 1); > > mgmt_pending_remove(cmd); > > > > @@ -6013,7 +6006,7 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err) > > > > bt_dev_dbg(hdev, "err %d", err); > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), > > cmd->param, 1); > > mgmt_pending_remove(cmd); > > > > @@ -6238,7 +6231,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) > > u8 status = mgmt_status(err); > > > > if (status) { > > - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, > > + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, > > cmd_status_rsp, &status); > > return; > > } > > @@ -6248,7 +6241,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) > > else > > hci_dev_clear_flag(hdev, HCI_ADVERTISING); > > > > - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp, > > + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, settings_rsp, > > &match); > > > > new_settings(hdev, match.sk); > > @@ -6592,7 +6585,7 @@ static void set_bredr_complete(struct hci_dev *hdev, void *data, int err) > > */ > > hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED); > > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > > } else { > > send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev); > > new_settings(hdev, cmd->sk); > > @@ -6729,7 +6722,7 @@ static void set_secure_conn_complete(struct hci_dev *hdev, void *data, int err) > > if (err) { > > u8 mgmt_err = mgmt_status(err); > > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > > goto done; > > } > > > > @@ -7176,7 +7169,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err) > > rp.max_tx_power = HCI_TX_POWER_INVALID; > > } > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status, > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status, > > &rp, sizeof(rp)); > > > > mgmt_pending_free(cmd); > > @@ -7336,7 +7329,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err) > > } > > > > complete: > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp, > > sizeof(rp)); > > > > mgmt_pending_free(cmd); > > @@ -8586,10 +8579,10 @@ static void add_advertising_complete(struct hci_dev *hdev, void *data, int err) > > rp.instance = cp->instance; > > > > if (err) > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(err)); > > else > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(err), &rp, sizeof(rp)); > > > > add_adv_complete(hdev, cmd->sk, cp->instance, err); > > @@ -8777,10 +8770,10 @@ static void add_ext_adv_params_complete(struct hci_dev *hdev, void *data, > > > > hci_remove_adv_instance(hdev, cp->instance); > > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(err)); > > } else { > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(err), &rp, sizeof(rp)); > > } > > > > @@ -8927,10 +8920,10 @@ static void add_ext_adv_data_complete(struct hci_dev *hdev, void *data, int err) > > rp.instance = cp->instance; > > > > if (err) > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(err)); > > else > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(err), &rp, sizeof(rp)); > > > > mgmt_pending_free(cmd); > > @@ -9089,10 +9082,10 @@ static void remove_advertising_complete(struct hci_dev *hdev, void *data, > > rp.instance = cp->instance; > > > > if (err) > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > > mgmt_status(err)); > > else > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); > > > > mgmt_pending_free(cmd); > > @@ -9364,7 +9357,7 @@ void mgmt_index_removed(struct hci_dev *hdev) > > if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) > > return; > > > > - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); > > + mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); > > > > if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { > > mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, > > @@ -9402,7 +9395,8 @@ void mgmt_power_on(struct hci_dev *hdev, int err) > > hci_update_passive_scan(hdev); > > } > > > > - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); > > + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, > > + &match); > > > > new_settings(hdev, match.sk); > > > > @@ -9417,7 +9411,8 @@ void __mgmt_power_off(struct hci_dev *hdev) > > struct cmd_lookup match = { NULL, hdev }; > > u8 zero_cod[] = { 0, 0, 0 }; > > > > - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); > > + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, > > + &match); > > > > /* If the power off is because of hdev unregistration let > > * use the appropriate INVALID_INDEX status. Otherwise use > > @@ -9431,7 +9426,7 @@ void __mgmt_power_off(struct hci_dev *hdev) > > else > > match.mgmt_status = MGMT_STATUS_NOT_POWERED; > > > > - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); > > + mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); > > > > if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) { > > mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, > > @@ -9672,7 +9667,6 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data) > > device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk); > > > > cmd->cmd_complete(cmd, 0); > > - mgmt_pending_remove(cmd); > > } > > > > bool mgmt_powering_down(struct hci_dev *hdev) > > @@ -9728,8 +9722,8 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, > > struct mgmt_cp_disconnect *cp; > > struct mgmt_pending_cmd *cmd; > > > > - mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, > > - hdev); > > + mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, true, > > + unpair_device_rsp, hdev); > > > > cmd = pending_find(MGMT_OP_DISCONNECT, hdev); > > if (!cmd) > > @@ -9922,7 +9916,7 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) > > > > if (status) { > > u8 mgmt_err = mgmt_status(status); > > - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, > > + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, > > cmd_status_rsp, &mgmt_err); > > return; > > } > > @@ -9932,8 +9926,8 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) > > else > > changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY); > > > > - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp, > > - &match); > > + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, > > + settings_rsp, &match); > > > > if (changed) > > new_settings(hdev, match.sk); > > @@ -9957,9 +9951,12 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, > > { > > struct cmd_lookup match = { NULL, hdev, mgmt_status(status) }; > > > > - mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match); > > - mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match); > > - mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match); > > + mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, false, sk_lookup, > > + &match); > > + mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, false, sk_lookup, > > + &match); > > + mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, false, sk_lookup, > > + &match); > > > > if (!status) { > > mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, > > diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c > > index 3713ff490c65..a88a07da3947 100644 > > --- a/net/bluetooth/mgmt_util.c > > +++ b/net/bluetooth/mgmt_util.c > > @@ -217,30 +217,47 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, > > struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, > > struct hci_dev *hdev) > > { > > - struct mgmt_pending_cmd *cmd; > > + struct mgmt_pending_cmd *cmd, *tmp; > > > > - list_for_each_entry(cmd, &hdev->mgmt_pending, list) { > > + mutex_lock(&hdev->mgmt_pending_lock); > > + > > + list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { > > if (hci_sock_get_channel(cmd->sk) != channel) > > continue; > > - if (cmd->opcode == opcode) > > + > > + if (cmd->opcode == opcode) { > > + mutex_unlock(&hdev->mgmt_pending_lock); > > return cmd; > > + } > > } > > > > + mutex_unlock(&hdev->mgmt_pending_lock); > > + > > return NULL; > > } > > > > -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, > > +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, > > void (*cb)(struct mgmt_pending_cmd *cmd, void *data), > > void *data) > > { > > struct mgmt_pending_cmd *cmd, *tmp; > > > > + mutex_lock(&hdev->mgmt_pending_lock); > > + > > list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { > > if (opcode > 0 && cmd->opcode != opcode) > > continue; > > > > + if (remove) > > + list_del(&cmd->list); > > + > > cb(cmd, data); > > + > > + if (remove) > > + mgmt_pending_free(cmd); > > } > > + > > + mutex_unlock(&hdev->mgmt_pending_lock); > > } > > > > struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, > > @@ -254,7 +271,7 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, > > return NULL; > > > > cmd->opcode = opcode; > > - cmd->index = hdev->id; > > + cmd->hdev = hdev; > > > > cmd->param = kmemdup(data, len, GFP_KERNEL); > > if (!cmd->param) { > > @@ -280,7 +297,9 @@ struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, > > if (!cmd) > > return NULL; > > > > + mutex_lock(&hdev->mgmt_pending_lock); > > list_add_tail(&cmd->list, &hdev->mgmt_pending); > > + mutex_unlock(&hdev->mgmt_pending_lock); > > > > return cmd; > > } > > @@ -294,7 +313,10 @@ void mgmt_pending_free(struct mgmt_pending_cmd *cmd) > > > > void mgmt_pending_remove(struct mgmt_pending_cmd *cmd) > > { > > + mutex_lock(&cmd->hdev->mgmt_pending_lock); > > list_del(&cmd->list); > > + mutex_unlock(&cmd->hdev->mgmt_pending_lock); > > + > > mgmt_pending_free(cmd); > > } > > > > diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h > > index f2ba994ab1d8..024e51dd6937 100644 > > --- a/net/bluetooth/mgmt_util.h > > +++ b/net/bluetooth/mgmt_util.h > > @@ -33,7 +33,7 @@ struct mgmt_mesh_tx { > > struct mgmt_pending_cmd { > > struct list_head list; > > u16 opcode; > > - int index; > > + struct hci_dev *hdev; > > void *param; > > size_t param_len; > > struct sock *sk; > > @@ -54,7 +54,7 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, > > > > struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, > > struct hci_dev *hdev); > > -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, > > +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, > > void (*cb)(struct mgmt_pending_cmd *cmd, void *data), > > void *data); > > struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, > > -- > > 2.49.0 > > > > > -- > Luiz Augusto von Dentz -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
* [syzbot] [bluetooth?] BUG: corrupted list in mgmt_pending_remove @ 2024-09-01 8:24 syzbot 2025-06-02 18:02 ` [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock syzbot 0 siblings, 1 reply; 10+ messages in thread From: syzbot @ 2024-09-01 8:24 UTC (permalink / raw) To: johan.hedberg, linux-bluetooth, linux-kernel, luiz.dentz, marcel, netdev, syzkaller-bugs Hello, syzbot found the following issue on: HEAD commit: fe1910f9337b tcp_bpf: fix return value of tcp_bpf_sendmsg() git tree: net console output: https://syzkaller.appspot.com/x/log.txt?x=171d6f7b980000 kernel config: https://syzkaller.appspot.com/x/.config?x=996585887acdadb3 dashboard link: https://syzkaller.appspot.com/bug?extid=cc0cc52e7f43dc9e6df1 compiler: Debian clang version 15.0.6, GNU ld (GNU Binutils for Debian) 2.40 Unfortunately, I don't have any reproducer for this issue yet. Downloadable assets: disk image: https://storage.googleapis.com/syzbot-assets/cb37d16e2860/disk-fe1910f9.raw.xz vmlinux: https://storage.googleapis.com/syzbot-assets/315198aa296e/vmlinux-fe1910f9.xz kernel image: https://storage.googleapis.com/syzbot-assets/b3e6fb9fa8a4/bzImage-fe1910f9.xz IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+cc0cc52e7f43dc9e6df1@syzkaller.appspotmail.com list_del corruption, ffff88802943da00->next is LIST_POISON1 (dead000000000100) ------------[ cut here ]------------ kernel BUG at lib/list_debug.c:58! Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI CPU: 1 UID: 0 PID: 7763 Comm: syz.0.694 Not tainted 6.11.0-rc5-syzkaller-00151-gfe1910f9337b #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024 RIP: 0010:__list_del_entry_valid_or_report+0xf4/0x140 lib/list_debug.c:56 Code: e8 71 64 fc 06 90 0f 0b 48 c7 c7 c0 90 60 8c 4c 89 fe e8 5f 64 fc 06 90 0f 0b 48 c7 c7 20 91 60 8c 4c 89 fe e8 4d 64 fc 06 90 <0f> 0b 48 c7 c7 80 91 60 8c 4c 89 fe e8 3b 64 fc 06 90 0f 0b 48 c7 RSP: 0018:ffffc9000492fb58 EFLAGS: 00010246 RAX: 000000000000004e RBX: dead000000000122 RCX: 5f038e50b22bff00 RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000 RBP: dffffc0000000000 R08: ffffffff8174013c R09: 1ffff92000925f0c R10: dffffc0000000000 R11: fffff52000925f0d R12: dffffc0000000000 R13: dffffc0000000000 R14: dead000000000100 R15: ffff88802943da00 FS: 00007fb7679de6c0(0000) GS:ffff8880b8900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffc967a2fc0 CR3: 00000000437dc000 CR4: 00000000003506f0 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 include/linux/list.h:229 [inline] mgmt_pending_remove+0x26/0x1a0 net/bluetooth/mgmt_util.c:314 mgmt_pending_foreach+0xd1/0x130 net/bluetooth/mgmt_util.c:259 mgmt_index_removed+0xe6/0x340 net/bluetooth/mgmt.c:9395 hci_sock_bind+0xcce/0x1150 net/bluetooth/hci_sock.c:1307 __sys_bind_socket net/socket.c:1833 [inline] __sys_bind+0x23d/0x2f0 net/socket.c:1857 __do_sys_bind net/socket.c:1865 [inline] __se_sys_bind net/socket.c:1863 [inline] __x64_sys_bind+0x7a/0x90 net/socket.c:1863 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fb767f79eb9 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 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 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fb7679de038 EFLAGS: 00000246 ORIG_RAX: 0000000000000031 RAX: ffffffffffffffda RBX: 00007fb768116058 RCX: 00007fb767f79eb9 RDX: 0000000000000006 RSI: 0000000020000040 RDI: 0000000000000004 RBP: 00007fb767fe793e R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000001 R14: 00007fb768116058 R15: 00007fffd1ff2828 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:__list_del_entry_valid_or_report+0xf4/0x140 lib/list_debug.c:56 Code: e8 71 64 fc 06 90 0f 0b 48 c7 c7 c0 90 60 8c 4c 89 fe e8 5f 64 fc 06 90 0f 0b 48 c7 c7 20 91 60 8c 4c 89 fe e8 4d 64 fc 06 90 <0f> 0b 48 c7 c7 80 91 60 8c 4c 89 fe e8 3b 64 fc 06 90 0f 0b 48 c7 RSP: 0018:ffffc9000492fb58 EFLAGS: 00010246 RAX: 000000000000004e RBX: dead000000000122 RCX: 5f038e50b22bff00 RDX: 0000000000000000 RSI: 0000000080000000 RDI: 0000000000000000 RBP: dffffc0000000000 R08: ffffffff8174013c R09: 1ffff92000925f0c R10: dffffc0000000000 R11: fffff52000925f0d R12: dffffc0000000000 R13: dffffc0000000000 R14: dead000000000100 R15: ffff88802943da00 FS: 00007fb7679de6c0(0000) GS:ffff8880b8900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f773e8e8178 CR3: 00000000437dc000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 --- 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 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] 10+ messages in thread
* Re: [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock 2024-09-01 8:24 [syzbot] [bluetooth?] BUG: corrupted list in mgmt_pending_remove syzbot @ 2025-06-02 18:02 ` syzbot 0 siblings, 0 replies; 10+ messages in thread From: syzbot @ 2025-06-02 18:02 UTC (permalink / raw) To: linux-kernel, syzkaller-bugs For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock Author: luiz.dentz@gmail.com #syz test On Mon, Jun 2, 2025 at 2:01 PM Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > > #syz test > > On Mon, Jun 2, 2025 at 2:00 PM Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > > > > #syz test > > > > On Mon, Jun 2, 2025 at 1:46 PM Luiz Augusto von Dentz > > <luiz.dentz@gmail.com> wrote: > > > > > > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > > > > > This uses a mutex to protect from concurrent access of mgmt_pending > > > list which can cause crashes like: > > > > > > ================================================================== > > > BUG: KASAN: slab-use-after-free in mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405 > > > Read of size 8 at addr ffff888048891a18 by task kworker/u5:8/5333 > > > > > > CPU: 0 UID: 0 PID: 5333 Comm: kworker/u5:8 Not tainted 6.15.0-rc5-syzkaller-00197-gea34704d6ad7 #0 PREEMPT(full) > > > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 > > > Workqueue: hci0 hci_cmd_sync_work > > > Call Trace: > > > <TASK> > > > dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 > > > print_address_description mm/kasan/report.c:408 [inline] > > > print_report+0xb4/0x290 mm/kasan/report.c:521 > > > kasan_report+0x118/0x150 mm/kasan/report.c:634 > > > mgmt_remove_adv_monitor_complete+0xe5/0x540 net/bluetooth/mgmt.c:5405 > > > hci_cmd_sync_work+0x25e/0x3a0 net/bluetooth/hci_sync.c:334 > > > process_one_work kernel/workqueue.c:3238 [inline] > > > process_scheduled_works+0xadb/0x17a0 kernel/workqueue.c:3319 > > > worker_thread+0x8a0/0xda0 kernel/workqueue.c:3400 > > > kthread+0x70e/0x8a0 kernel/kthread.c:464 > > > ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:153 > > > ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 > > > </TASK> > > > > > > Allocated by task 5702: > > > kasan_save_stack mm/kasan/common.c:47 [inline] > > > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > > > poison_kmalloc_redzone mm/kasan/common.c:377 [inline] > > > __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394 > > > kasan_kmalloc include/linux/kasan.h:260 [inline] > > > __kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4358 > > > kmalloc_noprof include/linux/slab.h:905 [inline] > > > kzalloc_noprof include/linux/slab.h:1039 [inline] > > > mgmt_pending_new+0x65/0x240 net/bluetooth/mgmt_util.c:252 > > > mgmt_pending_add+0x34/0x120 net/bluetooth/mgmt_util.c:279 > > > remove_adv_monitor+0x103/0x1b0 net/bluetooth/mgmt.c:5453 > > > hci_mgmt_cmd+0x9c6/0xef0 net/bluetooth/hci_sock.c:1712 > > > hci_sock_sendmsg+0x6ca/0xee0 net/bluetooth/hci_sock.c:1832 > > > sock_sendmsg_nosec net/socket.c:712 [inline] > > > __sock_sendmsg+0x219/0x270 net/socket.c:727 > > > sock_write_iter+0x258/0x330 net/socket.c:1131 > > > new_sync_write fs/read_write.c:591 [inline] > > > vfs_write+0x548/0xa90 fs/read_write.c:684 > > > ksys_write+0x145/0x250 fs/read_write.c:736 > > > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > > > do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94 > > > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > > > > > Freed by task 5700: > > > kasan_save_stack mm/kasan/common.c:47 [inline] > > > kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 > > > kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576 > > > poison_slab_object mm/kasan/common.c:247 [inline] > > > __kasan_slab_free+0x62/0x70 mm/kasan/common.c:264 > > > kasan_slab_free include/linux/kasan.h:233 [inline] > > > slab_free_hook mm/slub.c:2380 [inline] > > > slab_free mm/slub.c:4642 [inline] > > > kfree+0x193/0x440 mm/slub.c:4841 > > > mgmt_pending_foreach+0xc9/0x120 net/bluetooth/mgmt_util.c:242 > > > mgmt_index_removed+0x10d/0x2f0 net/bluetooth/mgmt.c:9362 > > > hci_sock_bind+0xbe9/0x1000 net/bluetooth/hci_sock.c:1307 > > > __sys_bind_socket net/socket.c:1810 [inline] > > > __sys_bind+0x2c3/0x3e0 net/socket.c:1841 > > > __do_sys_bind net/socket.c:1846 [inline] > > > __se_sys_bind net/socket.c:1844 [inline] > > > __x64_sys_bind+0x7a/0x90 net/socket.c:1844 > > > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > > > do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94 > > > entry_SYSCALL_64_after_hwframe+0x77/0x7f > > > > > > Fixes: a380b6cff1a2 ("Bluetooth: Add generic mgmt helper API") > > > Closes: https://syzkaller.appspot.com/bug?extid=feb0dc579bbe30a13190 > > > Closes: https://syzkaller.appspot.com/bug?extid=0a7039d5d9986ff4ececi > > > Closes: https://syzkaller.appspot.com/bug?extid=cc0cc52e7f43dc9e6df1 > > > Reported-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com > > > Tested-by: syzbot+feb0dc579bbe30a13190@syzkaller.appspotmail.com > > > Tested-by: syzbot+0a7039d5d9986ff4ecec@syzkaller.appspotmail.com > > > Tested-by: syzbot+cc0cc52e7f43dc9e6df1@syzkaller.appspotmail.com > > > Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru> > > > Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > > --- > > > include/net/bluetooth/hci_core.h | 1 + > > > net/bluetooth/hci_core.c | 1 + > > > net/bluetooth/mgmt.c | 101 +++++++++++++++---------------- > > > net/bluetooth/mgmt_util.c | 32 ++++++++-- > > > net/bluetooth/mgmt_util.h | 4 +- > > > 5 files changed, 80 insertions(+), 59 deletions(-) > > > > > > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h > > > index 2b261e74e2c4..b9ff0e825071 100644 > > > --- a/include/net/bluetooth/hci_core.h > > > +++ b/include/net/bluetooth/hci_core.h > > > @@ -546,6 +546,7 @@ struct hci_dev { > > > struct hci_conn_hash conn_hash; > > > > > > struct list_head mesh_pending; > > > + struct mutex mgmt_pending_lock; > > > struct list_head mgmt_pending; > > > struct list_head reject_list; > > > struct list_head accept_list; > > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c > > > index 04845ff3ad57..f197f5497043 100644 > > > --- a/net/bluetooth/hci_core.c > > > +++ b/net/bluetooth/hci_core.c > > > @@ -2487,6 +2487,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) > > > > > > mutex_init(&hdev->lock); > > > mutex_init(&hdev->req_lock); > > > + mutex_init(&hdev->mgmt_pending_lock); > > > > > > ida_init(&hdev->unset_handle_ida); > > > > > > diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c > > > index 14a9462fced5..7d9ed7db377f 100644 > > > --- a/net/bluetooth/mgmt.c > > > +++ b/net/bluetooth/mgmt.c > > > @@ -1447,22 +1447,17 @@ static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data) > > > > > > send_settings_rsp(cmd->sk, cmd->opcode, match->hdev); > > > > > > - list_del(&cmd->list); > > > - > > > if (match->sk == NULL) { > > > match->sk = cmd->sk; > > > sock_hold(match->sk); > > > } > > > - > > > - mgmt_pending_free(cmd); > > > } > > > > > > static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data) > > > { > > > u8 *status = data; > > > > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status); > > > - mgmt_pending_remove(cmd); > > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status); > > > } > > > > > > static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) > > > @@ -1476,8 +1471,6 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) > > > > > > if (cmd->cmd_complete) { > > > cmd->cmd_complete(cmd, match->mgmt_status); > > > - mgmt_pending_remove(cmd); > > > - > > > return; > > > } > > > > > > @@ -1486,13 +1479,13 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data) > > > > > > static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) > > > { > > > - return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, > > > + return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, > > > cmd->param, cmd->param_len); > > > } > > > > > > static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status) > > > { > > > - return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, > > > + return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, > > > cmd->param, sizeof(struct mgmt_addr_info)); > > > } > > > > > > @@ -1532,7 +1525,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data, > > > > > > if (err) { > > > u8 mgmt_err = mgmt_status(err); > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > > > hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE); > > > goto done; > > > } > > > @@ -1707,7 +1700,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data, > > > > > > if (err) { > > > u8 mgmt_err = mgmt_status(err); > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > > > goto done; > > > } > > > > > > @@ -1943,8 +1936,8 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) > > > new_settings(hdev, NULL); > > > } > > > > > > - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp, > > > - &mgmt_err); > > > + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, > > > + cmd_status_rsp, &mgmt_err); > > > return; > > > } > > > > > > @@ -1954,7 +1947,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err) > > > changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED); > > > } > > > > > > - mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match); > > > + mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, settings_rsp, &match); > > > > > > if (changed) > > > new_settings(hdev, match.sk); > > > @@ -2074,12 +2067,12 @@ static void set_le_complete(struct hci_dev *hdev, void *data, int err) > > > bt_dev_dbg(hdev, "err %d", err); > > > > > > if (status) { > > > - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp, > > > - &status); > > > + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, cmd_status_rsp, > > > + &status); > > > return; > > > } > > > > > > - mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match); > > > + mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, settings_rsp, &match); > > > > > > new_settings(hdev, match.sk); > > > > > > @@ -2138,7 +2131,7 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err) > > > struct sock *sk = cmd->sk; > > > > > > if (status) { > > > - mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, > > > + mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true, > > > cmd_status_rsp, &status); > > > return; > > > } > > > @@ -2638,7 +2631,7 @@ static void mgmt_class_complete(struct hci_dev *hdev, void *data, int err) > > > > > > bt_dev_dbg(hdev, "err %d", err); > > > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(err), hdev->dev_class, 3); > > > > > > mgmt_pending_free(cmd); > > > @@ -3427,7 +3420,7 @@ static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status) > > > bacpy(&rp.addr.bdaddr, &conn->dst); > > > rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type); > > > > > > - err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE, > > > + err = mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_PAIR_DEVICE, > > > status, &rp, sizeof(rp)); > > > > > > /* So we don't get further callbacks for this connection */ > > > @@ -5196,7 +5189,7 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev, > > > hci_update_passive_scan(hdev); > > > } > > > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(status), &rp, sizeof(rp)); > > > mgmt_pending_remove(cmd); > > > > > > @@ -5411,7 +5404,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev, > > > if (!status) > > > hci_update_passive_scan(hdev); > > > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(status), &rp, sizeof(rp)); > > > mgmt_pending_remove(cmd); > > > > > > @@ -5792,7 +5785,7 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err) > > > cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev)) > > > return; > > > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), > > > cmd->param, 1); > > > mgmt_pending_remove(cmd); > > > > > > @@ -6013,7 +6006,7 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err) > > > > > > bt_dev_dbg(hdev, "err %d", err); > > > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err), > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err), > > > cmd->param, 1); > > > mgmt_pending_remove(cmd); > > > > > > @@ -6238,7 +6231,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) > > > u8 status = mgmt_status(err); > > > > > > if (status) { > > > - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, > > > + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, > > > cmd_status_rsp, &status); > > > return; > > > } > > > @@ -6248,7 +6241,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err) > > > else > > > hci_dev_clear_flag(hdev, HCI_ADVERTISING); > > > > > > - mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp, > > > + mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, settings_rsp, > > > &match); > > > > > > new_settings(hdev, match.sk); > > > @@ -6592,7 +6585,7 @@ static void set_bredr_complete(struct hci_dev *hdev, void *data, int err) > > > */ > > > hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED); > > > > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > > > } else { > > > send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev); > > > new_settings(hdev, cmd->sk); > > > @@ -6729,7 +6722,7 @@ static void set_secure_conn_complete(struct hci_dev *hdev, void *data, int err) > > > if (err) { > > > u8 mgmt_err = mgmt_status(err); > > > > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err); > > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err); > > > goto done; > > > } > > > > > > @@ -7176,7 +7169,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err) > > > rp.max_tx_power = HCI_TX_POWER_INVALID; > > > } > > > > > > - mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status, > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status, > > > &rp, sizeof(rp)); > > > > > > mgmt_pending_free(cmd); > > > @@ -7336,7 +7329,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err) > > > } > > > > > > complete: > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp, > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp, > > > sizeof(rp)); > > > > > > mgmt_pending_free(cmd); > > > @@ -8586,10 +8579,10 @@ static void add_advertising_complete(struct hci_dev *hdev, void *data, int err) > > > rp.instance = cp->instance; > > > > > > if (err) > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(err)); > > > else > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(err), &rp, sizeof(rp)); > > > > > > add_adv_complete(hdev, cmd->sk, cp->instance, err); > > > @@ -8777,10 +8770,10 @@ static void add_ext_adv_params_complete(struct hci_dev *hdev, void *data, > > > > > > hci_remove_adv_instance(hdev, cp->instance); > > > > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(err)); > > > } else { > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(err), &rp, sizeof(rp)); > > > } > > > > > > @@ -8927,10 +8920,10 @@ static void add_ext_adv_data_complete(struct hci_dev *hdev, void *data, int err) > > > rp.instance = cp->instance; > > > > > > if (err) > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(err)); > > > else > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(err), &rp, sizeof(rp)); > > > > > > mgmt_pending_free(cmd); > > > @@ -9089,10 +9082,10 @@ static void remove_advertising_complete(struct hci_dev *hdev, void *data, > > > rp.instance = cp->instance; > > > > > > if (err) > > > - mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, > > > mgmt_status(err)); > > > else > > > - mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, > > > + mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, > > > MGMT_STATUS_SUCCESS, &rp, sizeof(rp)); > > > > > > mgmt_pending_free(cmd); > > > @@ -9364,7 +9357,7 @@ void mgmt_index_removed(struct hci_dev *hdev) > > > if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) > > > return; > > > > > > - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); > > > + mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); > > > > > > if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) { > > > mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0, > > > @@ -9402,7 +9395,8 @@ void mgmt_power_on(struct hci_dev *hdev, int err) > > > hci_update_passive_scan(hdev); > > > } > > > > > > - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); > > > + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, > > > + &match); > > > > > > new_settings(hdev, match.sk); > > > > > > @@ -9417,7 +9411,8 @@ void __mgmt_power_off(struct hci_dev *hdev) > > > struct cmd_lookup match = { NULL, hdev }; > > > u8 zero_cod[] = { 0, 0, 0 }; > > > > > > - mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); > > > + mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp, > > > + &match); > > > > > > /* If the power off is because of hdev unregistration let > > > * use the appropriate INVALID_INDEX status. Otherwise use > > > @@ -9431,7 +9426,7 @@ void __mgmt_power_off(struct hci_dev *hdev) > > > else > > > match.mgmt_status = MGMT_STATUS_NOT_POWERED; > > > > > > - mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match); > > > + mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match); > > > > > > if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) { > > > mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, > > > @@ -9672,7 +9667,6 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data) > > > device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk); > > > > > > cmd->cmd_complete(cmd, 0); > > > - mgmt_pending_remove(cmd); > > > } > > > > > > bool mgmt_powering_down(struct hci_dev *hdev) > > > @@ -9728,8 +9722,8 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, > > > struct mgmt_cp_disconnect *cp; > > > struct mgmt_pending_cmd *cmd; > > > > > > - mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, > > > - hdev); > > > + mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, true, > > > + unpair_device_rsp, hdev); > > > > > > cmd = pending_find(MGMT_OP_DISCONNECT, hdev); > > > if (!cmd) > > > @@ -9922,7 +9916,7 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) > > > > > > if (status) { > > > u8 mgmt_err = mgmt_status(status); > > > - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, > > > + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, > > > cmd_status_rsp, &mgmt_err); > > > return; > > > } > > > @@ -9932,8 +9926,8 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) > > > else > > > changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY); > > > > > > - mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp, > > > - &match); > > > + mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true, > > > + settings_rsp, &match); > > > > > > if (changed) > > > new_settings(hdev, match.sk); > > > @@ -9957,9 +9951,12 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class, > > > { > > > struct cmd_lookup match = { NULL, hdev, mgmt_status(status) }; > > > > > > - mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match); > > > - mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match); > > > - mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match); > > > + mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, false, sk_lookup, > > > + &match); > > > + mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, false, sk_lookup, > > > + &match); > > > + mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, false, sk_lookup, > > > + &match); > > > > > > if (!status) { > > > mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class, > > > diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c > > > index 3713ff490c65..a88a07da3947 100644 > > > --- a/net/bluetooth/mgmt_util.c > > > +++ b/net/bluetooth/mgmt_util.c > > > @@ -217,30 +217,47 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, > > > struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, > > > struct hci_dev *hdev) > > > { > > > - struct mgmt_pending_cmd *cmd; > > > + struct mgmt_pending_cmd *cmd, *tmp; > > > > > > - list_for_each_entry(cmd, &hdev->mgmt_pending, list) { > > > + mutex_lock(&hdev->mgmt_pending_lock); > > > + > > > + list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { > > > if (hci_sock_get_channel(cmd->sk) != channel) > > > continue; > > > - if (cmd->opcode == opcode) > > > + > > > + if (cmd->opcode == opcode) { > > > + mutex_unlock(&hdev->mgmt_pending_lock); > > > return cmd; > > > + } > > > } > > > > > > + mutex_unlock(&hdev->mgmt_pending_lock); > > > + > > > return NULL; > > > } > > > > > > -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, > > > +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, > > > void (*cb)(struct mgmt_pending_cmd *cmd, void *data), > > > void *data) > > > { > > > struct mgmt_pending_cmd *cmd, *tmp; > > > > > > + mutex_lock(&hdev->mgmt_pending_lock); > > > + > > > list_for_each_entry_safe(cmd, tmp, &hdev->mgmt_pending, list) { > > > if (opcode > 0 && cmd->opcode != opcode) > > > continue; > > > > > > + if (remove) > > > + list_del(&cmd->list); > > > + > > > cb(cmd, data); > > > + > > > + if (remove) > > > + mgmt_pending_free(cmd); > > > } > > > + > > > + mutex_unlock(&hdev->mgmt_pending_lock); > > > } > > > > > > struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, > > > @@ -254,7 +271,7 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, > > > return NULL; > > > > > > cmd->opcode = opcode; > > > - cmd->index = hdev->id; > > > + cmd->hdev = hdev; > > > > > > cmd->param = kmemdup(data, len, GFP_KERNEL); > > > if (!cmd->param) { > > > @@ -280,7 +297,9 @@ struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, > > > if (!cmd) > > > return NULL; > > > > > > + mutex_lock(&hdev->mgmt_pending_lock); > > > list_add_tail(&cmd->list, &hdev->mgmt_pending); > > > + mutex_unlock(&hdev->mgmt_pending_lock); > > > > > > return cmd; > > > } > > > @@ -294,7 +313,10 @@ void mgmt_pending_free(struct mgmt_pending_cmd *cmd) > > > > > > void mgmt_pending_remove(struct mgmt_pending_cmd *cmd) > > > { > > > + mutex_lock(&cmd->hdev->mgmt_pending_lock); > > > list_del(&cmd->list); > > > + mutex_unlock(&cmd->hdev->mgmt_pending_lock); > > > + > > > mgmt_pending_free(cmd); > > > } > > > > > > diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h > > > index f2ba994ab1d8..024e51dd6937 100644 > > > --- a/net/bluetooth/mgmt_util.h > > > +++ b/net/bluetooth/mgmt_util.h > > > @@ -33,7 +33,7 @@ struct mgmt_mesh_tx { > > > struct mgmt_pending_cmd { > > > struct list_head list; > > > u16 opcode; > > > - int index; > > > + struct hci_dev *hdev; > > > void *param; > > > size_t param_len; > > > struct sock *sk; > > > @@ -54,7 +54,7 @@ int mgmt_cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, > > > > > > struct mgmt_pending_cmd *mgmt_pending_find(unsigned short channel, u16 opcode, > > > struct hci_dev *hdev); > > > -void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, > > > +void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, bool remove, > > > void (*cb)(struct mgmt_pending_cmd *cmd, void *data), > > > void *data); > > > struct mgmt_pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, > > > -- > > > 2.49.0 > > > > > > > > > -- > > Luiz Augusto von Dentz > > > > -- > Luiz Augusto von Dentz -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-06-03 20:30 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-05-14 4:27 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in mgmt_remove_adv_monitor_complete (3) syzbot 2025-05-14 7:10 ` [syzbot] #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9f35e33144ae5377d6a8de86dd3bd4d995c6ac65 syzbot 2025-05-20 13:30 ` [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a5806cd506af5a7c19bcd596e4708b5c464bfd21 syzbot 2025-05-23 8:20 ` [syzbot] #syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 94305e83eccb3120c921cd3a015cd74731140bac syzbot 2025-05-23 8:20 ` syzbot 2025-05-28 19:03 ` [syzbot] Re: [PATCH v1] Bluetooth: MGMT: Use RCU-protected in mgmt_pending list syzbot 2025-06-02 18:00 ` [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock syzbot 2025-06-03 20:30 ` [syzbot] Re: [PATCH v4 1/2] Bluetooth: MGMT: Fix UAF on mgmt_remove_adv_monitor_complete syzbot -- strict thread matches above, loose matches on Subject: below -- 2025-05-25 7:44 [syzbot] [bluetooth?] KASAN: slab-use-after-free Read in hci_sock_get_channel syzbot 2025-06-02 18:01 ` [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock syzbot 2024-09-01 8:24 [syzbot] [bluetooth?] BUG: corrupted list in mgmt_pending_remove syzbot 2025-06-02 18:02 ` [syzbot] Re: [PATCH v3] Bluetooth: MGMT: Protect mgmt_pending list with its own lock syzbot
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.