* [syzbot] [usb?] KASAN: slab-use-after-free Read in attach_store
@ 2026-08-14 9:32 syzbot
2026-08-15 12:47 ` Forwarded: [PATCH] usbip: vhci_hcd: fix UAF in attach_store() during unbind syzbot
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: syzbot @ 2026-08-14 9:32 UTC (permalink / raw)
To: linux-kernel, linux-usb, syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: 2f1baf1fc892 Merge tag 'trace-v7.2-rc7' of git://git.kerne..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=13a98a25580000
kernel config: https://syzkaller.appspot.com/x/.config?x=c44651ea7dd2f307
dashboard link: https://syzkaller.appspot.com/bug?extid=8753715f05759f1a10de
compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=12de5279580000
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+8753715f05759f1a10de@syzkaller.appspotmail.com
==================================================================
BUG: KASAN: slab-use-after-free in __mutex_lock_common kernel/locking/mutex.c:728 [inline]
BUG: KASAN: slab-use-after-free in __mutex_lock+0x18bb/0x1bd0 kernel/locking/mutex.c:821
Read of size 8 at addr ffff8880265c84f0 by task syz-executor396/6022
CPU: 0 UID: 0 PID: 6022 Comm: syz-executor396 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:94 [inline]
dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
print_address_description mm/kasan/report.c:378 [inline]
print_report+0x13d/0x4b0 mm/kasan/report.c:482
kasan_report+0xdf/0x1c0 mm/kasan/report.c:595
__mutex_lock_common kernel/locking/mutex.c:728 [inline]
__mutex_lock+0x18bb/0x1bd0 kernel/locking/mutex.c:821
attach_store+0x333/0x8f0 drivers/usb/usbip/vhci_sysfs.c:364
dev_attr_store+0x58/0x80 drivers/base/core.c:2505
sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
new_sync_write fs/read_write.c:595 [inline]
vfs_write+0x6ac/0x1050 fs/read_write.c:687
ksys_write+0x12a/0x250 fs/read_write.c:739
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x115/0x870 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f5f9e9f6bde
Code: 08 0f 85 f5 e2 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 90 41 57 41 56 4d 89 c6 41 55 4d 89 cd 41 54 55 53 48 83 ec 08
RSP: 002b:00007f5f9e1a0098 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007f5f9e1a06c0 RCX: 00007f5f9e9f6bde
RDX: 0000000000000009 RSI: 00007f5f9e1a0100 RDI: 0000000000000008
RBP: 00007f5f9ea420b0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: ffffffffffffffd0
R13: 0000000000000009 R14: 00007ffc89c49e90 R15: 00007ffc89c49f78
</TASK>
Allocated by task 1:
kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
kasan_save_track+0x14/0x30 mm/kasan/common.c:78
poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
__kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:415
kasan_kmalloc include/linux/kasan.h:263 [inline]
__do_kmalloc_node mm/slub.c:5334 [inline]
__kmalloc_noprof+0x322/0x820 mm/slub.c:5359
_kmalloc_noprof include/linux/slab.h:992 [inline]
_kzalloc_noprof include/linux/slab.h:1309 [inline]
__usb_create_hcd+0x5e/0xac0 drivers/usb/core/hcd.c:2566
vhci_hcd_probe+0x1a5/0x4e0 drivers/usb/usbip/vhci_hcd.c:1394
platform_probe+0x106/0x1d0 drivers/base/platform.c:1439
call_driver_probe drivers/base/dd.c:628 [inline]
really_probe+0x241/0xa60 drivers/base/dd.c:706
__driver_probe_device+0x20e/0x450 drivers/base/dd.c:868
driver_probe_device+0x4a/0x140 drivers/base/dd.c:898
__device_attach_driver+0x1df/0x320 drivers/base/dd.c:1026
bus_for_each_drv+0x159/0x1e0 drivers/base/bus.c:500
__device_attach+0x1e4/0x4d0 drivers/base/dd.c:1098
device_initial_probe+0xaf/0xd0 drivers/base/dd.c:1153
bus_probe_device+0x64/0x160 drivers/base/bus.c:620
device_add+0x121d/0x1970 drivers/base/core.c:3772
platform_device_add+0x35a/0x800 drivers/base/platform.c:762
platform_device_register_full+0x5cf/0x830 drivers/base/platform.c:902
vhci_hcd_init+0x1a1/0x2f0 drivers/usb/usbip/vhci_hcd.c:1557
do_one_initcall+0x11d/0x700 init/main.c:1347
do_initcall_level init/main.c:1409 [inline]
do_initcalls init/main.c:1425 [inline]
do_basic_setup init/main.c:1445 [inline]
kernel_init_freeable+0x6ea/0x7b0 init/main.c:1658
kernel_init+0x1f/0x1e0 init/main.c:1548
ret_from_fork+0x72b/0xd50 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
Freed by task 6021:
kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
kasan_save_track+0x14/0x30 mm/kasan/common.c:78
kasan_save_free_info+0x3b/0x70 mm/kasan/generic.c:584
poison_slab_object mm/kasan/common.c:253 [inline]
__kasan_slab_free+0x5f/0x80 mm/kasan/common.c:285
kasan_slab_free include/linux/kasan.h:235 [inline]
slab_free_hook mm/slub.c:2677 [inline]
slab_free mm/slub.c:6377 [inline]
kfree+0x22b/0x6c0 mm/slub.c:6692
hcd_release drivers/usb/core/hcd.c:2690 [inline]
kref_put include/linux/kref.h:65 [inline]
usb_put_hcd drivers/usb/core/hcd.c:2704 [inline]
usb_put_hcd+0x149/0x1f0 drivers/usb/core/hcd.c:2701
vhci_hcd_remove+0xb5/0x1b0 drivers/usb/usbip/vhci_hcd.c:1431
platform_remove+0x5f/0x80 drivers/base/platform.c:1456
device_remove+0xcb/0x180 drivers/base/dd.c:616
__device_release_driver drivers/base/dd.c:1349 [inline]
device_release_driver_internal+0x44e/0x620 drivers/base/dd.c:1372
unbind_store+0xf8/0x110 drivers/base/bus.c:244
drv_attr_store+0x74/0xb0 drivers/base/bus.c:125
sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
new_sync_write fs/read_write.c:595 [inline]
vfs_write+0x6ac/0x1050 fs/read_write.c:687
ksys_write+0x12a/0x250 fs/read_write.c:739
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x115/0x870 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Last potentially related work creation:
kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
kasan_record_aux_stack+0xa7/0xc0 mm/kasan/generic.c:556
insert_work+0x36/0x230 kernel/workqueue.c:2226
__queue_work+0x9bc/0x12b0 kernel/workqueue.c:2401
queue_work_on+0x1a9/0x1e0 kernel/workqueue.c:2452
queue_work include/linux/workqueue.h:699 [inline]
usb_hcd_giveback_urb+0x330/0x4a0 drivers/usb/core/hcd.c:1758
usb_rh_urb_dequeue drivers/usb/core/hcd.c:845 [inline]
unlink1+0x418/0x510 drivers/usb/core/hcd.c:1580
usb_hcd_unlink_urb+0x131/0x210 drivers/usb/core/hcd.c:1617
usb_kill_urb drivers/usb/core/urb.c:716 [inline]
usb_kill_urb+0x121/0x320 drivers/usb/core/urb.c:703
hub_quiesce+0x1e9/0x320 drivers/usb/core/hub.c:1412
hub_suspend+0x4ab/0x9e0 drivers/usb/core/hub.c:4016
usb_suspend_interface drivers/usb/core/driver.c:1323 [inline]
usb_suspend_both+0x288/0x950 drivers/usb/core/driver.c:1446
usb_runtime_suspend+0x49/0x120 drivers/usb/core/driver.c:2000
__rpm_callback+0xc8/0x620 drivers/base/power/runtime.c:406
rpm_callback+0x16a/0x1b0 drivers/base/power/runtime.c:460
rpm_suspend+0x2f4/0x11a0 drivers/base/power/runtime.c:698
__pm_runtime_suspend+0xba/0x1a0 drivers/base/power/runtime.c:1167
pm_runtime_put_sync_autosuspend include/linux/pm_runtime.h:740 [inline]
usb_new_device.part.0+0x1653/0x1686 drivers/usb/core/hub.c:2735
register_root_hub+0x4e6/0x639 drivers/usb/core/hcd.c:990
usb_add_hcd.cold+0xccd/0x1158 drivers/usb/core/hcd.c:2987
vhci_hcd_probe+0x1c2/0x4e0 drivers/usb/usbip/vhci_hcd.c:1401
platform_probe+0x106/0x1d0 drivers/base/platform.c:1439
call_driver_probe drivers/base/dd.c:628 [inline]
really_probe+0x241/0xa60 drivers/base/dd.c:706
__driver_probe_device+0x20e/0x450 drivers/base/dd.c:868
driver_probe_device+0x4a/0x140 drivers/base/dd.c:898
__device_attach_driver+0x1df/0x320 drivers/base/dd.c:1026
bus_for_each_drv+0x159/0x1e0 drivers/base/bus.c:500
__device_attach+0x1e4/0x4d0 drivers/base/dd.c:1098
device_initial_probe+0xaf/0xd0 drivers/base/dd.c:1153
bus_probe_device+0x64/0x160 drivers/base/bus.c:620
device_add+0x121d/0x1970 drivers/base/core.c:3772
platform_device_add+0x35a/0x800 drivers/base/platform.c:762
platform_device_register_full+0x5cf/0x830 drivers/base/platform.c:902
vhci_hcd_init+0x1a1/0x2f0 drivers/usb/usbip/vhci_hcd.c:1557
do_one_initcall+0x11d/0x700 init/main.c:1347
do_initcall_level init/main.c:1409 [inline]
do_initcalls init/main.c:1425 [inline]
do_basic_setup init/main.c:1445 [inline]
kernel_init_freeable+0x6ea/0x7b0 init/main.c:1658
kernel_init+0x1f/0x1e0 init/main.c:1548
ret_from_fork+0x72b/0xd50 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
Second to last potentially related work creation:
kasan_save_stack+0x30/0x50 mm/kasan/common.c:57
kasan_record_aux_stack+0xa7/0xc0 mm/kasan/generic.c:556
insert_work+0x36/0x230 kernel/workqueue.c:2226
__queue_work+0x9bc/0x12b0 kernel/workqueue.c:2401
queue_work_on+0x1a9/0x1e0 kernel/workqueue.c:2452
queue_work include/linux/workqueue.h:699 [inline]
usb_hcd_giveback_urb+0x3b8/0x4a0 drivers/usb/core/hcd.c:1760
rh_call_control drivers/usb/core/hcd.c:706 [inline]
rh_urb_enqueue drivers/usb/core/hcd.c:817 [inline]
usb_hcd_submit_urb+0xab7/0x2150 drivers/usb/core/hcd.c:1538
usb_submit_urb+0x827/0x19b0 drivers/usb/core/urb.c:586
usb_start_wait_urb+0x10e/0x580 drivers/usb/core/message.c:62
usb_internal_control_msg drivers/usb/core/message.c:117 [inline]
usb_control_msg+0x328/0x4b0 drivers/usb/core/message.c:167
set_port_feature drivers/usb/core/hub.c:466 [inline]
hub_suspend+0x826/0x9e0 drivers/usb/core/hub.c:4004
usb_suspend_interface drivers/usb/core/driver.c:1323 [inline]
usb_suspend_both+0x288/0x950 drivers/usb/core/driver.c:1446
usb_runtime_suspend+0x49/0x120 drivers/usb/core/driver.c:2000
__rpm_callback+0xc8/0x620 drivers/base/power/runtime.c:406
rpm_callback+0x16a/0x1b0 drivers/base/power/runtime.c:460
rpm_suspend+0x2f4/0x11a0 drivers/base/power/runtime.c:698
__pm_runtime_suspend+0xba/0x1a0 drivers/base/power/runtime.c:1167
pm_runtime_put_sync_autosuspend include/linux/pm_runtime.h:740 [inline]
usb_new_device.part.0+0x1653/0x1686 drivers/usb/core/hub.c:2735
register_root_hub+0x4e6/0x639 drivers/usb/core/hcd.c:990
usb_add_hcd.cold+0xccd/0x1158 drivers/usb/core/hcd.c:2987
vhci_hcd_probe+0x1c2/0x4e0 drivers/usb/usbip/vhci_hcd.c:1401
platform_probe+0x106/0x1d0 drivers/base/platform.c:1439
call_driver_probe drivers/base/dd.c:628 [inline]
really_probe+0x241/0xa60 drivers/base/dd.c:706
__driver_probe_device+0x20e/0x450 drivers/base/dd.c:868
driver_probe_device+0x4a/0x140 drivers/base/dd.c:898
__device_attach_driver+0x1df/0x320 drivers/base/dd.c:1026
bus_for_each_drv+0x159/0x1e0 drivers/base/bus.c:500
__device_attach+0x1e4/0x4d0 drivers/base/dd.c:1098
device_initial_probe+0xaf/0xd0 drivers/base/dd.c:1153
bus_probe_device+0x64/0x160 drivers/base/bus.c:620
device_add+0x121d/0x1970 drivers/base/core.c:3772
platform_device_add+0x35a/0x800 drivers/base/platform.c:762
platform_device_register_full+0x5cf/0x830 drivers/base/platform.c:902
vhci_hcd_init+0x1a1/0x2f0 drivers/usb/usbip/vhci_hcd.c:1557
do_one_initcall+0x11d/0x700 init/main.c:1347
do_initcall_level init/main.c:1409 [inline]
do_initcalls init/main.c:1425 [inline]
do_basic_setup init/main.c:1445 [inline]
kernel_init_freeable+0x6ea/0x7b0 init/main.c:1658
kernel_init+0x1f/0x1e0 init/main.c:1548
ret_from_fork+0x72b/0xd50 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
The buggy address belongs to the object at ffff8880265c8000
which belongs to the cache kmalloc-8k of size 8192
The buggy address is located 1264 bytes inside of
freed 8192-byte region [ffff8880265c8000, ffff8880265ca000)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x265c8
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0xfff00000000040(head|node=0|zone=1|lastcpupid=0x7ff)
page_type: f5(slab)
raw: 00fff00000000040 ffff88801bc43180 dead000000000122 0000000000000000
raw: 0000000000000000 0000000800020002 00000000f5000000 0000000000000000
head: 00fff00000000040 ffff88801bc43180 dead000000000122 0000000000000000
head: 0000000000000000 0000000800020002 00000000f5000000 0000000000000000
head: 00fff00000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 1, tgid 1 (swapper/0), ts 11610115084, free_ts 6038226833
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0xfd/0x120 mm/page_alloc.c:1859
prep_new_page mm/page_alloc.c:1867 [inline]
get_page_from_freelist+0xf48/0x3530 mm/page_alloc.c:3946
__alloc_frozen_pages_noprof+0x299/0x2dc0 mm/page_alloc.c:5304
alloc_slab_page mm/slub.c:3266 [inline]
allocate_slab mm/slub.c:3380 [inline]
new_slab+0xa2/0x640 mm/slub.c:3426
refill_objects+0xe3/0x410 mm/slub.c:7310
refill_sheaf mm/slub.c:2804 [inline]
__pcs_replace_empty_main+0x376/0x680 mm/slub.c:4675
alloc_from_pcs mm/slub.c:4773 [inline]
slab_alloc_node mm/slub.c:4905 [inline]
__do_kmalloc_node mm/slub.c:5333 [inline]
__kmalloc_noprof+0x66d/0x820 mm/slub.c:5359
_kmalloc_noprof include/linux/slab.h:992 [inline]
_kzalloc_noprof include/linux/slab.h:1309 [inline]
__usb_create_hcd+0x5e/0xac0 drivers/usb/core/hcd.c:2566
vhci_hcd_probe+0xf3/0x4e0 drivers/usb/usbip/vhci_hcd.c:1378
platform_probe+0x106/0x1d0 drivers/base/platform.c:1439
call_driver_probe drivers/base/dd.c:628 [inline]
really_probe+0x241/0xa60 drivers/base/dd.c:706
__driver_probe_device+0x20e/0x450 drivers/base/dd.c:868
driver_probe_device+0x4a/0x140 drivers/base/dd.c:898
__device_attach_driver+0x1df/0x320 drivers/base/dd.c:1026
bus_for_each_drv+0x159/0x1e0 drivers/base/bus.c:500
__device_attach+0x1e4/0x4d0 drivers/base/dd.c:1098
page last free pid 34 tgid 34 stack trace:
reset_page_owner include/linux/page_owner.h:25 [inline]
__free_pages_prepare mm/page_alloc.c:1406 [inline]
free_pages_prepare+0x586/0xd80 mm/page_alloc.c:1451
__free_contig_range_common+0x14f/0x250 mm/page_alloc.c:6897
__free_contig_range mm/page_alloc.c:6942 [inline]
free_pages_bulk+0x12a/0x200 mm/page_alloc.c:5257
vm_area_free_pages+0xad/0x2b0 mm/vmalloc.c:3461
vfree mm/vmalloc.c:3510 [inline]
vfree+0x107/0x750 mm/vmalloc.c:3484
delayed_vfree_work+0x56/0x80 mm/vmalloc.c:3414
process_one_work+0xa23/0x1940 kernel/workqueue.c:3322
process_scheduled_works kernel/workqueue.c:3405 [inline]
worker_thread+0x5ef/0xe50 kernel/workqueue.c:3486
kthread+0x370/0x450 kernel/kthread.c:436
ret_from_fork+0x72b/0xd50 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
Memory state around the buggy address:
ffff8880265c8380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880265c8400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff8880265c8480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8880265c8500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880265c8580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
---
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] 4+ messages in thread
* Forwarded: [PATCH] usbip: vhci_hcd: fix UAF in attach_store() during unbind
2026-08-14 9:32 [syzbot] [usb?] KASAN: slab-use-after-free Read in attach_store syzbot
@ 2026-08-15 12:47 ` syzbot
2026-08-15 14:04 ` Forwarded: [PATCH] usbip: vhci_hcd: move sysfs attribute setup into probe/remove syzbot
2026-08-16 1:16 ` Forwarded: [PATCH] usbip: vhci_hcd: let the driver core manage the sysfs attributes syzbot
2 siblings, 0 replies; 4+ messages in thread
From: syzbot @ 2026-08-15 12:47 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: [PATCH] usbip: vhci_hcd: fix UAF in attach_store() during unbind
Author: kartikey406@gmail.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
vhci_hcd_remove() frees the SS hcd via usb_put_hcd() before the HS hcd's
vhci_stop() removes the sysfs attribute group, since the group removal is
guarded by usb_hcd_is_primary_hcd(). A concurrent write to the attach
attribute can therefore reach vhci->vhci_hcd_ss after it has been freed.
Remove the attribute group at the start of vhci_hcd_remove(), before
either hcd reference is dropped. sysfs_remove_group() drains in-flight
store callbacks, so no writer can be inside attach_store() once it
returns.
Reported-by: syzbot+8753715f05759f1a10de@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=8753715f05759f1a10de
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
drivers/usb/usbip/vhci_hcd.c | 39 +++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
index 39e8faf4c18c..3ce8893729b1 100644
--- a/drivers/usb/usbip/vhci_hcd.c
+++ b/drivers/usb/usbip/vhci_hcd.c
@@ -1252,18 +1252,11 @@ static int vhci_start(struct usb_hcd *hcd)
static void vhci_stop(struct usb_hcd *hcd)
{
struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
- int id, rhport;
+ int rhport;
usbip_dbg_vhci_hc("stop VHCI controller\n");
- /* 1. remove the userland interface of vhci_hcd */
- id = hcd_name_to_id(hcd_name(hcd));
- if (id == 0 && usb_hcd_is_primary_hcd(hcd)) {
- sysfs_remove_group(&hcd_dev(hcd)->kobj, &vhci_attr_group);
- vhci_finish_attr_group();
- }
-
- /* 2. shutdown all the ports of vhci_hcd */
+ /* shutdown all the ports of vhci_hcd */
for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) {
struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
@@ -1421,20 +1414,34 @@ static int vhci_hcd_probe(struct platform_device *pdev)
static void vhci_hcd_remove(struct platform_device *pdev)
{
struct vhci *vhci = *((void **)dev_get_platdata(&pdev->dev));
+ struct usb_hcd *hcd_hs = vhci_hcd_to_hcd(vhci->vhci_hcd_hs);
+ struct usb_hcd *hcd_ss = vhci_hcd_to_hcd(vhci->vhci_hcd_ss);
+
+ /*
+ * Remove the userland interface before dropping the hcd references.
+ * sysfs_remove_group() waits for in-flight attach_store()/detach_store()
+ * callers to return and rejects new ones, so neither hcd can be reached
+ * from sysfs by the time it is freed below.
+ */
+ if (pdev->id == 0) {
+ sysfs_remove_group(&pdev->dev.kobj, &vhci_attr_group);
+ vhci_finish_attr_group();
+ }
+
+ vhci->vhci_hcd_hs = NULL;
+ vhci->vhci_hcd_ss = NULL;
+
/*
* Disconnects the root hub,
* then reverses the effects of usb_add_hcd(),
* invoking the HCD's stop() methods.
*/
- usb_remove_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_ss));
- usb_put_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_ss));
-
- usb_remove_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_hs));
- usb_put_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_hs));
+ usb_remove_hcd(hcd_ss);
+ usb_put_hcd(hcd_ss);
- vhci->vhci_hcd_hs = NULL;
- vhci->vhci_hcd_ss = NULL;
+ usb_remove_hcd(hcd_hs);
+ usb_put_hcd(hcd_hs);
}
#ifdef CONFIG_PM
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Forwarded: [PATCH] usbip: vhci_hcd: move sysfs attribute setup into probe/remove
2026-08-14 9:32 [syzbot] [usb?] KASAN: slab-use-after-free Read in attach_store syzbot
2026-08-15 12:47 ` Forwarded: [PATCH] usbip: vhci_hcd: fix UAF in attach_store() during unbind syzbot
@ 2026-08-15 14:04 ` syzbot
2026-08-16 1:16 ` Forwarded: [PATCH] usbip: vhci_hcd: let the driver core manage the sysfs attributes syzbot
2 siblings, 0 replies; 4+ messages in thread
From: syzbot @ 2026-08-15 14:04 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: [PATCH] usbip: vhci_hcd: move sysfs attribute setup into probe/remove
Author: kartikey406@gmail.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
The vhci sysfs attribute group is created in vhci_start() and removed in
vhci_stop(), guarded by usb_hcd_is_primary_hcd(). Since vhci_start() and
vhci_stop() run from usb_add_hcd()/usb_remove_hcd(), which are each called
twice, the attach attribute is live while only one of the two hcds exists:
it is created during the first usb_add_hcd() before vhci_hcd_ss is set,
and it survives the first usb_put_hcd() during removal. A concurrent write
to attach can therefore reach a NULL or freed vhci_hcd_ss.
Create the group at the end of vhci_hcd_probe(), after both hcds are
added, and remove it at the start of vhci_hcd_remove(), before either
reference is dropped. sysfs_remove_group() drains in-flight store
callbacks, so no writer can be inside attach_store() once it returns.
Reported-by: syzbot+8753715f05759f1a10de@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=8753715f05759f1a10de
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
drivers/usb/usbip/vhci_hcd.c | 66 ++++++++++++++++++++----------------
1 file changed, 36 insertions(+), 30 deletions(-)
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
index 39e8faf4c18c..90f166f3ae96 100644
--- a/drivers/usb/usbip/vhci_hcd.c
+++ b/drivers/usb/usbip/vhci_hcd.c
@@ -1199,7 +1199,6 @@ static int vhci_start(struct usb_hcd *hcd)
{
struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
int id, rhport;
- int err;
usbip_dbg_vhci_hc("enter vhci_start\n");
@@ -1230,40 +1229,17 @@ static int vhci_start(struct usb_hcd *hcd)
return -EINVAL;
}
- /* vhci_hcd is now ready to be controlled through sysfs */
- if (id == 0 && usb_hcd_is_primary_hcd(hcd)) {
- err = vhci_init_attr_group();
- if (err) {
- dev_err(hcd_dev(hcd), "init attr group failed, err = %d\n", err);
- return err;
- }
- err = sysfs_create_group(&hcd_dev(hcd)->kobj, &vhci_attr_group);
- if (err) {
- dev_err(hcd_dev(hcd), "create sysfs files failed, err = %d\n", err);
- vhci_finish_attr_group();
- return err;
- }
- dev_info(hcd_dev(hcd), "created sysfs %s\n", hcd_name(hcd));
- }
-
return 0;
}
static void vhci_stop(struct usb_hcd *hcd)
{
struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
- int id, rhport;
+ int rhport;
usbip_dbg_vhci_hc("stop VHCI controller\n");
- /* 1. remove the userland interface of vhci_hcd */
- id = hcd_name_to_id(hcd_name(hcd));
- if (id == 0 && usb_hcd_is_primary_hcd(hcd)) {
- sysfs_remove_group(&hcd_dev(hcd)->kobj, &vhci_attr_group);
- vhci_finish_attr_group();
- }
-
- /* 2. shutdown all the ports of vhci_hcd */
+ /* shutdown all the ports of vhci_hcd */
for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) {
struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
@@ -1405,8 +1381,25 @@ static int vhci_hcd_probe(struct platform_device *pdev)
}
usbip_dbg_vhci_hc("bye\n");
+
+ if (pdev->id == 0) {
+ ret = vhci_init_attr_group();
+ if (ret) {
+ dev_err_probe(&pdev->dev, ret, "init attr group failed\n");
+ goto remove_usb3_hcd;
+ }
+ ret = sysfs_create_group(&pdev->dev.kobj, &vhci_attr_group);
+ if (ret) {
+ dev_err_probe(&pdev->dev, ret, "create sysfs files failed\n");
+ vhci_finish_attr_group();
+ goto remove_usb3_hcd;
+ }
+ }
+
return 0;
+remove_usb3_hcd:
+ usb_remove_hcd(hcd_ss);
put_usb3_hcd:
usb_put_hcd(hcd_ss);
remove_usb2_hcd:
@@ -1421,17 +1414,30 @@ static int vhci_hcd_probe(struct platform_device *pdev)
static void vhci_hcd_remove(struct platform_device *pdev)
{
struct vhci *vhci = *((void **)dev_get_platdata(&pdev->dev));
+ struct usb_hcd *hcd_hs = vhci_hcd_to_hcd(vhci->vhci_hcd_hs);
+ struct usb_hcd *hcd_ss = vhci_hcd_to_hcd(vhci->vhci_hcd_ss);
+
+ /*
+ * Remove the userland interface before dropping the hcd references.
+ * sysfs_remove_group() waits for in-flight attach_store()/detach_store()
+ * callers to return and rejects new ones, so neither hcd can be reached
+ * from sysfs by the time it is freed below.
+ */
+ if (pdev->id == 0) {
+ sysfs_remove_group(&pdev->dev.kobj, &vhci_attr_group);
+ vhci_finish_attr_group();
+ }
/*
* Disconnects the root hub,
* then reverses the effects of usb_add_hcd(),
* invoking the HCD's stop() methods.
*/
- usb_remove_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_ss));
- usb_put_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_ss));
+ usb_remove_hcd(hcd_ss);
+ usb_put_hcd(hcd_ss);
- usb_remove_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_hs));
- usb_put_hcd(vhci_hcd_to_hcd(vhci->vhci_hcd_hs));
+ usb_remove_hcd(hcd_hs);
+ usb_put_hcd(hcd_hs);
vhci->vhci_hcd_hs = NULL;
vhci->vhci_hcd_ss = NULL;
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Forwarded: [PATCH] usbip: vhci_hcd: let the driver core manage the sysfs attributes
2026-08-14 9:32 [syzbot] [usb?] KASAN: slab-use-after-free Read in attach_store syzbot
2026-08-15 12:47 ` Forwarded: [PATCH] usbip: vhci_hcd: fix UAF in attach_store() during unbind syzbot
2026-08-15 14:04 ` Forwarded: [PATCH] usbip: vhci_hcd: move sysfs attribute setup into probe/remove syzbot
@ 2026-08-16 1:16 ` syzbot
2 siblings, 0 replies; 4+ messages in thread
From: syzbot @ 2026-08-16 1:16 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: [PATCH] usbip: vhci_hcd: let the driver core manage the sysfs attributes
Author: kartikey406@gmail.com
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
The vhci attribute group is created in vhci_start() and removed in
vhci_stop(), guarded by usb_hcd_is_primary_hcd(). Both run from
usb_add_hcd()/usb_remove_hcd(), which are called once per hcd, so the
attach attribute is live while only one of the two hcds exists: it is
created during the first usb_add_hcd() before vhci_hcd_ss is set, and it
survives the first usb_put_hcd() on removal. A concurrent write to attach
can therefore reach a NULL or freed vhci_hcd_ss.
Register the group as dev_groups on the platform driver instead, so the
driver core creates the files before probe and removes them after remove
returns, and drop the sysfs_create_group()/sysfs_remove_group() calls from
the driver. The attributes have always been created only on vhci_hcd.0;
an is_visible() callback keeps them there.
vhci_init_attr_group() is moved into vhci_hcd_init() ahead of
platform_driver_register() so the group is populated before the core
reads it. The attribute array is still built at runtime because the
number of status attributes comes from CONFIG_USBIP_VHCI_NR_HCS and the
preprocessor cannot emit a variable number of __ATTR() declarations. If
statically declaring all 32 and hiding the unused ones with is_visible()
is preferred, I can respin that way.
Reported-by: syzbot+8753715f05759f1a10de@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=8753715f05759f1a10de
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
---
v2:
- use dev_groups instead of moving sysfs_create_group() into probe (Greg)
- add is_visible() to keep the attributes on vhci_hcd.0 only
- move vhci_init_attr_group() into vhci_hcd_init()
---
drivers/usb/usbip/vhci.h | 1 +
drivers/usb/usbip/vhci_hcd.c | 37 ++++++++++------------------------
drivers/usb/usbip/vhci_sysfs.c | 19 +++++++++++++++++
3 files changed, 31 insertions(+), 26 deletions(-)
diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h
index 5659dce1526e..844500e3b0ea 100644
--- a/drivers/usb/usbip/vhci.h
+++ b/drivers/usb/usbip/vhci.h
@@ -121,6 +121,7 @@ struct vhci_hcd {
extern int vhci_num_controllers;
extern struct vhci *vhcis;
extern struct attribute_group vhci_attr_group;
+extern const struct attribute_group *vhci_groups[];
/* vhci_hcd.c */
void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed);
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
index 39e8faf4c18c..4bace5b8b879 100644
--- a/drivers/usb/usbip/vhci_hcd.c
+++ b/drivers/usb/usbip/vhci_hcd.c
@@ -1199,7 +1199,6 @@ static int vhci_start(struct usb_hcd *hcd)
{
struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
int id, rhport;
- int err;
usbip_dbg_vhci_hc("enter vhci_start\n");
@@ -1230,40 +1229,17 @@ static int vhci_start(struct usb_hcd *hcd)
return -EINVAL;
}
- /* vhci_hcd is now ready to be controlled through sysfs */
- if (id == 0 && usb_hcd_is_primary_hcd(hcd)) {
- err = vhci_init_attr_group();
- if (err) {
- dev_err(hcd_dev(hcd), "init attr group failed, err = %d\n", err);
- return err;
- }
- err = sysfs_create_group(&hcd_dev(hcd)->kobj, &vhci_attr_group);
- if (err) {
- dev_err(hcd_dev(hcd), "create sysfs files failed, err = %d\n", err);
- vhci_finish_attr_group();
- return err;
- }
- dev_info(hcd_dev(hcd), "created sysfs %s\n", hcd_name(hcd));
- }
-
return 0;
}
static void vhci_stop(struct usb_hcd *hcd)
{
struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
- int id, rhport;
+ int rhport;
usbip_dbg_vhci_hc("stop VHCI controller\n");
- /* 1. remove the userland interface of vhci_hcd */
- id = hcd_name_to_id(hcd_name(hcd));
- if (id == 0 && usb_hcd_is_primary_hcd(hcd)) {
- sysfs_remove_group(&hcd_dev(hcd)->kobj, &vhci_attr_group);
- vhci_finish_attr_group();
- }
-
- /* 2. shutdown all the ports of vhci_hcd */
+ /* shutdown all the ports of vhci_hcd */
for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) {
struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
@@ -1513,6 +1489,7 @@ static struct platform_driver vhci_driver = {
.resume = vhci_hcd_resume,
.driver = {
.name = driver_name,
+ .dev_groups = vhci_groups,
},
};
@@ -1541,6 +1518,10 @@ static int __init vhci_hcd_init(void)
if (vhcis == NULL)
return -ENOMEM;
+ ret = vhci_init_attr_group();
+ if (ret)
+ goto err_init_attr_group;
+
ret = platform_driver_register(&vhci_driver);
if (ret)
goto err_driver_register;
@@ -1565,9 +1546,12 @@ static int __init vhci_hcd_init(void)
return 0;
+
err_add_hcd:
platform_driver_unregister(&vhci_driver);
err_driver_register:
+ vhci_finish_attr_group();
+err_init_attr_group:
kfree(vhcis);
return ret;
}
@@ -1576,6 +1560,7 @@ static void __exit vhci_hcd_exit(void)
{
del_platform_devices();
platform_driver_unregister(&vhci_driver);
+ vhci_finish_attr_group();
kfree(vhcis);
}
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index a7ede6fb3da9..8c0bff2ddabb 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -497,8 +497,27 @@ static void finish_status_attrs(void)
kfree(status_attrs);
}
+static umode_t vhci_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ struct platform_device *pdev = to_platform_device(kobj_to_dev(kobj));
+ /*
+ * The attributes control every controller and have always lived on
+ * vhci_hcd.0 only. Keep them there now that the driver core creates
+ * the group for each device.
+ */
+ return pdev->id == 0 ? attr->mode : 0;
+}
+
+
struct attribute_group vhci_attr_group = {
.attrs = NULL,
+ .is_visible = vhci_attr_is_visible,
+};
+
+const struct attribute_group *vhci_groups[] = {
+ &vhci_attr_group,
+ NULL,
};
int vhci_init_attr_group(void)
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-16 1:16 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-14 9:32 [syzbot] [usb?] KASAN: slab-use-after-free Read in attach_store syzbot
2026-08-15 12:47 ` Forwarded: [PATCH] usbip: vhci_hcd: fix UAF in attach_store() during unbind syzbot
2026-08-15 14:04 ` Forwarded: [PATCH] usbip: vhci_hcd: move sysfs attribute setup into probe/remove syzbot
2026-08-16 1:16 ` Forwarded: [PATCH] usbip: vhci_hcd: let the driver core manage the sysfs attributes 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.