mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [BUG] KASAN: slab-use-after-free in usb_control_msg / kobject_put (vhci_hcd)
@ 2026-09-09  1:54 Amir Mohammad Jahangirzad
  2026-09-09  7:36 ` Greg Kroah-Hartman
  0 siblings, 1 reply; 2+ messages in thread
From: Amir Mohammad Jahangirzad @ 2026-09-09  1:54 UTC (permalink / raw)
  To: Valentina Manea, Shuah Khan, Hongren Zheng, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, syzkaller, Amir Mohammad Jahangirzad,
	Mohammad Mahdi Anbaraki

We have found two related KASAN slab-use-after-free bugs in the USB
subsystem (specifically involving vhci_hcd and usbip) using syzkaller.

Exact kernel branch and revision: upstream torvalds/linux master tree,
commit 893e11787f78e43b534e252249ac3fff4d1333f8.
Kernel config: https://gist.github.com/Reodus/dd06d0efddc483bc5f6e17dd392376d8

Note: Because this bug relies on a race condition, it may not trigger on the
very first run. The reproducer needs to be executed concurrently in a loop.
For example, using syzkaller's syz-execprog utility inside a QEMU VM, we
run it with multiple processes:

./syz-execprog -executor=./syz-executor -os=linux -arch=amd64 \  -threaded=true -repeat=0 -procs=16 -sandbox=none \
  -enable=usb,net_dev,net_reset,cgroups,binfmt_misc,close_fds,sysctl,swap \
  ./repro.prog

Alternatively, you can compile the provided syz programs into C reproducers
and run them in a loop with multiple threads.


Crash 1:

[   98.877298] BUG: KASAN: slab-use-after-free in usb_control_msg+0x417/0x490
[   98.877321] Read of size 4 at addr ffff8881082bc51c by task kworker/0:4/8296
[   98.877333] 
[   98.877342] CPU: 0 UID: 0 PID: 8296 Comm: kworker/0:4 Not tainted 7.3.0-rc2-g893e11787f78 #7 PREEMPT(lazy) 
[   98.877360] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Arch Linux 1.17.0-2-2 04/01/2014
[   98.877371] Workqueue: usb_hub_wq hub_event
[   98.877392] Call Trace:
[   98.877398]  <TASK>
[   98.877427]  dump_stack_lvl+0x70/0xa0
[   98.877450]  print_report+0x14b/0x4b0
[   98.877471]  ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[   98.877493]  kasan_report+0xfa/0x120
[   98.877513]  ? usb_control_msg+0x417/0x490
[   98.877528]  ? usb_control_msg+0x417/0x490
[   98.877546]  usb_control_msg+0x417/0x490
[   98.877560]  ? __pfx_usb_control_msg+0x10/0x10
[   98.877575]  ? __pfx__dev_info+0x10/0x10
[   98.877591]  ? __pfx_hub_port_reset+0x10/0x10
[   98.877608]  get_bMaxPacketSize0+0xef/0x260
[   98.877624]  hub_port_init+0x5b9/0x3200
[   98.877641]  ? device_set_wakeup_capable+0x11c/0x170
[   98.877662]  hub_event+0x24c0/0x39f0
[   98.877684]  ? __pfx_hub_event+0x10/0x10
[   98.877701]  ? pwq_dec_nr_in_flight+0x157/0xd30
[   98.877720]  ? remove_waiter+0x571/0xd40
[   98.877733]  ? _raw_spin_lock_irqsave+0x85/0xe0
[   98.877752]  ? mutex_unlock+0x7f/0xd0
[   98.877771]  ? __pfx_pwq_dec_nr_in_flight+0x10/0x10
[   98.877789]  ? _raw_spin_lock_irq+0x80/0xe0
[   98.877806]  ? __pfx__raw_spin_lock_irq+0x10/0x10
[   98.877824]  ? kick_pool_pick+0x208/0x660
[   98.877840]  ? __pm_runtime_suspend+0xae/0x260
[   98.877860]  process_one_work+0x6fc/0x1110
[   98.877879]  ? __pfx___schedule+0x10/0x10
[   98.877896]  ? move_linked_works+0x1af/0x290
[   98.877918]  ? __pfx_process_one_work+0x10/0x10
[   98.877936]  ? __pfx_hub_event+0x10/0x10
[   98.877953]  worker_thread+0x49a/0xb80
[   98.877972]  ? __kthread_parkme+0x113/0x190
[   98.877994]  ? __pfx_worker_thread+0x10/0x10
[   98.878011]  kthread+0x361/0x460
[   98.878025]  ? __pfx_kthread+0x10/0x10
[   98.878040]  ret_from_fork+0x3e6/0x670
[   98.878058]  ? __pfx_ret_from_fork+0x10/0x10
[   98.878075]  ? __switch_to+0x74b/0xf90
[   98.878089]  ? __pfx_kthread+0x10/0x10
[   98.878104]  ret_from_fork_asm+0x1a/0x30
[   98.878127]  </TASK>
[   98.878133] 
[   98.878136] Allocated by task 8296:
[   98.878145]  kasan_save_stack+0x2f/0x50
[   98.878166]  kasan_save_track+0x14/0x30
[   98.878182]  __kasan_kmalloc+0x7f/0x90
[   98.878197]  __kmalloc_cache_noprof+0x181/0x3b0
[   98.878210]  usb_alloc_dev+0x5f/0xef0
[   98.878221]  hub_event+0x21e0/0x39f0
[   98.878237]  process_one_work+0x6fc/0x1110
[   98.878252]  worker_thread+0x49a/0xb80
[   98.878268]  kthread+0x361/0x460
[   98.878280]  ret_from_fork+0x3e6/0x670
[   98.878294]  ret_from_fork_asm+0x1a/0x30
[   98.878313] 
[   98.878316] Freed by task 72:
[   98.878323]  kasan_save_stack+0x2f/0x50
[   98.878338]  kasan_save_track+0x14/0x30
[   98.878353]  kasan_save_free_info+0x3b/0x70
[   98.878366]  __kasan_slab_free+0x47/0x70
[   98.878382]  kfree+0x216/0x450
[   98.878393]  device_release+0xd6/0x3b0
[   98.878417]  kobject_put+0x1a6/0x360
[   98.878435]  put_device+0x1f/0x30
[   98.878448]  usb_put_dev+0x23/0x30
[   98.878469]  vhci_device_reset+0xd6/0x220
[   98.878487]  event_handler+0x1f4/0x3f0
[   98.878502]  process_one_work+0x6fc/0x1110
[   98.878518]  worker_thread+0x49a/0xb80
[   98.878533]  kthread+0x361/0x460
[   98.878545]  ret_from_fork+0x3e6/0x670
[   98.878560]  ret_from_fork_asm+0x1a/0x30
[   98.878579] 
[   98.878582] The buggy address belongs to the object at ffff8881082bc000
[   98.878582]  which belongs to the cache kmalloc-2k of size 2048
[   98.878594] The buggy address is located 1308 bytes inside of
[   98.878594]  freed 2048-byte region [ffff8881082bc000, ffff8881082bc800)
[   98.878609] 
[   98.878612] The buggy address belongs to the physical page:
[   98.878619] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1082b8
[   98.878633] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[   98.878644] flags: 0x200000000000040(head|node=0|zone=2)
[   98.878657] page_type: f5(slab)
[   98.878671] raw: 0200000000000040 ffff888100042000 dead000000000100 dead000000000122
[   98.878684] raw: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000
[   98.878697] head: 0200000000000040 ffff888100042000 dead000000000100 dead000000000122
[   98.878709] head: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000
[   98.878721] head: 0200000000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
[   98.878733] head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
[   98.878741] page dumped because: kasan: bad access detected
[   98.878746] 
[   98.878749] Memory state around the buggy address:
[   98.878756]  ffff8881082bc400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   98.878765]  ffff8881082bc480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   98.878775] >ffff8881082bc500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   98.878782]                             ^
[   98.878789]  ffff8881082bc580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   98.878798]  ffff8881082bc600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   98.878806] ==================================================================


The syz reproducer:


# {Threaded:true Repeat:true RepeatTimes:0 Procs:16 Slowdown:1 Sandbox:none SandboxArg:0 Leak:false NetInjection:false NetDevices:true NetReset:true Cgroups:true BinfmtMisc:true CloseFDs:true KCSAN:false DevlinkPCI:false NicVF:false USB:true VhciInjection:false Wifi:false IEEE802154:false Sysctl:true Swap:true UseTmpDir:true HandleSegv:true Trace:false CallComments:true LegacyOptions:{Collide:false Fault:false FaultCall:0 FaultNth:0}}
syz_usb_connect$midi(0x0, 0x24, &(0x7f0000000300)={{0x12, 0x1, 0x300, 0x0, 0x0, 0x0, 0x20, 0x194f, 0x10c, 0x40, 0x1, 0x2, 0x3, 0x1, [{{0x9, 0x2, 0x12, 0x1, 0x1, 0x4, 0x80, 0xe, "", {{{0x9, 0x4, 0x0, 0x0, 0x0, 0x1, 0x3, 0x0, 0x4}}}}}]}}, 0x0)
syz_open_dev$usbfs(&(0x7f0000000380), 0x1ff, 0x2)
syz_usbip_server_init(0x1)



Crash 2:

[   96.159481] BUG: KASAN: slab-use-after-free in kobject_put+0x2da/0x360
[   96.159490] Read of size 1 at addr ffff888102e160ec by task kworker/0:11/8637
[   96.159494] 
[   96.159498] CPU: 0 UID: 0 PID: 8637 Comm: kworker/0:11 Not tainted 7.3.0-rc2-g893e11787f78 #7 PREEMPT(lazy) 
[   96.159503] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS Arch Linux 1.17.0-2-2 04/01/2014
[   96.159507] Workqueue: usb_hub_wq hub_event
[   96.159516] Call Trace:
[   96.159518]  <TASK>
[   96.159519]  dump_stack_lvl+0x70/0xa0
[   96.159527]  print_report+0x14b/0x4b0
[   96.159534]  ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[   96.159541]  kasan_report+0xfa/0x120
[   96.159548]  ? kobject_put+0x2da/0x360
[   96.159554]  ? kobject_put+0x2da/0x360
[   96.159559]  kobject_put+0x2da/0x360
[   96.159565]  ? get_device+0x2a/0x40
[   96.159569]  put_device+0x1f/0x30
[   96.159573]  usb_put_dev+0x23/0x30
[   96.159579]  vhci_urb_enqueue+0x42e/0x9b0
[   96.159586]  usb_hcd_submit_urb+0x24b/0x1e00
[   96.159593]  usb_submit_urb+0x71f/0x1550
[   96.159598]  usb_start_wait_urb+0x138/0x340
[   96.159602]  ? __pfx_usb_start_wait_urb+0x10/0x10
[   96.159606]  ? kasan_save_track+0x14/0x30
[   96.159612]  ? __kmalloc_noprof+0x1cc/0x480
[   96.159616]  ? usb_alloc_urb+0x53/0x180
[   96.159620]  ? __asan_memset+0x27/0x50
[   96.159624]  usb_control_msg+0x321/0x490
[   96.159628]  ? __pfx_usb_control_msg+0x10/0x10
[   96.159632]  ? __pfx__dev_info+0x10/0x10
[   96.159637]  ? __pfx_hub_port_reset+0x10/0x10
[   96.159642]  get_bMaxPacketSize0+0xef/0x260
[   96.159647]  hub_port_init+0x5b9/0x3200
[   96.159652]  ? device_set_wakeup_capable+0x11c/0x170
[   96.159658]  hub_event+0x24c0/0x39f0
[   96.159664]  ? __pfx_hub_event+0x10/0x10
[   96.159669]  ? pwq_dec_nr_in_flight+0x157/0xd30
[   96.159675]  ? remove_waiter+0x371/0xd40
[   96.159679]  ? _raw_spin_lock_irqsave+0x85/0xe0
[   96.159684]  ? mutex_unlock+0x7f/0xd0
[   96.159690]  ? __pfx_pwq_dec_nr_in_flight+0x10/0x10
[   96.159695]  ? _raw_spin_lock_irq+0x80/0xe0
[   96.159700]  ? __pfx__raw_spin_lock_irq+0x10/0x10
[   96.159705]  ? kick_pool_pick+0x208/0x660
[   96.159710]  ? __pm_runtime_suspend+0xae/0x260
[   96.159716]  process_one_work+0x6fc/0x1110
[   96.159721]  ? __pfx___schedule+0x10/0x10
[   96.159726]  ? move_linked_works+0x1af/0x290
[   96.159732]  ? __pfx_process_one_work+0x10/0x10
[   96.159738]  ? __pfx_hub_event+0x10/0x10
[   96.159743]  worker_thread+0x49a/0xb80
[   96.159748]  ? __kthread_parkme+0x113/0x190
[   96.159755]  ? __pfx_worker_thread+0x10/0x10
[   96.159760]  kthread+0x361/0x460
[   96.159765]  ? __pfx_kthread+0x10/0x10
[   96.159769]  ret_from_fork+0x3e6/0x670
[   96.159776]  ? __pfx_ret_from_fork+0x10/0x10
[   96.159780]  ? __switch_to+0x74b/0xf90
[   96.159785]  ? __pfx_kthread+0x10/0x10
[   96.159789]  ret_from_fork_asm+0x1a/0x30
[   96.159796]  </TASK>
[   96.159797] 
[   96.159798] Allocated by task 8287:
[   96.159801]  kasan_save_stack+0x2f/0x50
[   96.159806]  kasan_save_track+0x14/0x30
[   96.159810]  __kasan_kmalloc+0x7f/0x90
[   96.159815]  __kmalloc_cache_noprof+0x181/0x3b0
[   96.159818]  usb_alloc_dev+0x5f/0xef0
[   96.159821]  hub_event+0x21e0/0x39f0
[   96.159826]  process_one_work+0x6fc/0x1110
[   96.159830]  worker_thread+0x49a/0xb80
[   96.159835]  kthread+0x361/0x460
[   96.159838]  ret_from_fork+0x3e6/0x670
[   96.159842]  ret_from_fork_asm+0x1a/0x30
[   96.159848] 
[   96.159849] Freed by task 8287:
[   96.159851]  kasan_save_stack+0x2f/0x50
[   96.159855]  kasan_save_track+0x14/0x30
[   96.159860]  kasan_save_free_info+0x3b/0x70
[   96.159867]  __kasan_slab_free+0x47/0x70
[   96.159872]  kfree+0x216/0x450
[   96.159875]  device_release+0xd6/0x3b0
[   96.159880]  kobject_put+0x1a6/0x360
[   96.159885]  put_device+0x1f/0x30
[   96.159888]  usb_put_dev+0x23/0x30
[   96.159893]  hub_event+0x288c/0x39f0
[   96.159898]  process_one_work+0x6fc/0x1110
[   96.159902]  worker_thread+0x49a/0xb80
[   96.159907]  kthread+0x361/0x460
[   96.159911]  ret_from_fork+0x3e6/0x670
[   96.159916]  ret_from_fork_asm+0x1a/0x30
[   96.159921] 
[   96.159922] The buggy address belongs to the object at ffff888102e16000
[   96.159922]  which belongs to the cache kmalloc-2k of size 2048
[   96.159933] The buggy address is located 236 bytes inside of
[   96.159933]  freed 2048-byte region [ffff888102e16000, ffff888102e16800)
[   96.159937] 
[   96.159938] The buggy address belongs to the physical page:
[   96.159941] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x102e10
[   96.159945] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[   96.159948] flags: 0x200000000000040(head|node=0|zone=2)
[   96.159952] page_type: f5(slab)
[   96.159966] raw: 0200000000000040 ffff888100042000 dead000000000100 dead000000000122
[   96.159970] raw: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000
[   96.159974] head: 0200000000000040 ffff888100042000 dead000000000100 dead000000000122
[   96.159977] head: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000
[   96.159981] head: 0200000000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
[   96.159985] head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
[   96.159987] page dumped because: kasan: bad access detected
[   96.159988] 
[   96.159989] Memory state around the buggy address:
[   96.159991]  ffff888102e15f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[   96.159994]  ffff888102e16000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   96.159997] >ffff888102e16080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   96.159999]                                                           ^
[   96.160002]  ffff888102e16100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[   96.160004]  ffff888102e16180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb



The syz reproducer:

# {Threaded:true Repeat:true RepeatTimes:0 Procs:16 Slowdown:1 Sandbox:none SandboxArg:0 Leak:false NetInjection:false NetDevices:true NetReset:true Cgroups:true BinfmtMisc:true CloseFDs:true KCSAN:false DevlinkPCI:false NicVF:false USB:true VhciInjection:false Wifi:false IEEE802154:false Sysctl:true Swap:true UseTmpDir:true HandleSegv:true Trace:false CallComments:true LegacyOptions:{Collide:false Fault:false FaultCall:0 FaultNth:0}}
r0 = syz_open_dev$usbfs(&(0x7f0000000000), 0xffffffffffffffff, 0x0)
read$usbfs(r0, 0x0, 0x0)
syz_usbip_server_init(0x2)
r1 = syz_open_dev$usbmon(0x0, 0x6, 0x21c101)
ioctl$MON_IOCX_MFETCH(r1, 0xc0109207, 0x0)
read$usbmon(r1, &(0x7f00000000c0)=""/46, 0x2e)
ioctl$MON_IOCH_MFLUSH(r1, 0x9208, 0xfffffffffffffffb)
r2 = syz_open_dev$evdev(&(0x7f00000000c0), 0x1, 0x20202)
ioctl$EVIOCGKEYCODE_V2(r2, 0x80284504, 0x0)
ioctl$EVIOCSKEYCODE_V2(r2, 0x40284504, &(0x7f0000000940)={0x5b, 0x1b, 0x9, 0x2, "1db770ad90b40f4c0ec86113b4925fb80fe792c1e3c6484977b162a138445e84"})
r3 = syz_usbip_server_init(0x3)
write$usbip_server(r3, 0x0, 0x41)
mmap$usbmon(&(0x7f0000ffd000/0x3000)=nil, 0x3000, 0x2, 0x11, 0xffffffffffffffff, 0x8000000000000000)
syz_open_dev$evdev(&(0x7f0000001340), 0xfffffffffffffbff, 0x440)
syz_open_dev$evdev(&(0x7f0000000300), 0x83, 0x0)
r4 = syz_usb_connect$sierra_net(0x0, 0x3f, &(0x7f0000000080)={{0x12, 0x1, 0x200, 0xff, 0xff, 0xff, 0x40, 0x1199, 0x68a3, 0x0, 0x1, 0x2, 0x3, 0x1, [{{0x9, 0x2, 0x2d, 0x1, 0x1, 0x0, 0x80, 0xfa, "", {{0x9, 0x4, 0x7, 0x0, 0x3, 0xff, 0x0, 0x0, 0x0, "", {{0x9, 0x5, 0x43978451d8f6fedb, 0x2, 0x40, 0x2, 0x1b, 0xfe}, {0x9, 0x5, 0x7, 0x2, 0x200, 0xc, 0x77, 0x3}, {0x9, 0x5, 0x81, 0x3, 0x20, 0x0, 0xfd, 0x32}}}}}}]}}, 0x0)
syz_usb_control_io$sierra_net(r4, 0x0, 0x0)
r5 = syz_usb_connect$cdc_ncm(0x0, 0x0, 0x0, 0x0)
syz_usb_control_io$cdc_ncm(r5, 0x0, 0x0)
syz_usb_control_io$cdc_ncm(r5, 0x0, 0x0)
syz_usb_control_io$cdc_ncm(r5, 0x0, 0x0)
syz_open_dev$usbmon(&(0x7f0000000100), 0x6, 0x2)
ioctl$MON_IOCQ_URB_LEN(r1, 0x9201)
read$usbmon(r1, &(0x7f0000000100)=""/231, 0xe7)


Reported-by: Amir Mohammad Jahangirzad <a.jahangirzad@gmail.com>
Reported-by: Mohammad Mahdi Anbaraki <m.mahdianbaraki@gmail.com>

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

end of thread, other threads:[~2026-09-09  7:36 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-09  1:54 [BUG] KASAN: slab-use-after-free in usb_control_msg / kobject_put (vhci_hcd) Amir Mohammad Jahangirzad
2026-09-09  7:36 ` Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®