[BUG] UBSAN: Array-Index-Out-of-Bounds in usbhid_parse (HID) on 6.14.0-rc4

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear Maintainers, When using our customized Syzkaller to fuzz the
latest Linux kernel, the following crash was triggered.

Kernel commit: v6.14-rc4 (Commits on Feb 24, 2025)
Kernel Config : https://github.com/Strforexc/LinuxKernelbug/blob/main/.config
Kernel Log:  https://github.com/Strforexc/LinuxKernelbug/blob/main/array-index-out-of-bounds_usbhid_parse/log0
Reproduce C: https://github.com/Strforexc/LinuxKernelbug/blob/main/array-index-out-of-bounds_usbhid_parse/repro.cprog

I’ve encountered a UBSAN-reported array-index-out-of-bounds issue in
the USB HID driver on Linux 6.14.0-rc4 during device probing, likely
triggered by a malformed USB descriptor. Here are the details:

UBSAN detects an out-of-bounds access at
drivers/hid/usbhid/hid-core.c:1025:18 in usbhid_parse, where index 1
exceeds the bounds of hid_class_descriptor [1] in struct
hid_descriptor. This occurs when parsing a HID device descriptor
during USB probing.

Location: The fault occurs in a loop: for (n = 0; n < num_descriptors;
n++) if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT), accessing
hdesc->desc[n].

Cause: struct hid_descriptor defines desc as a fixed-size array [1],
but the loop iterates up to num_descriptors (based on
hdesc->bNumDescriptors). UBSAN flags n=1 as out-of-bounds, though the
underlying descriptor buffer may be larger.

Context: Preceded by a USB descriptor error (-22), suggesting a
malformed HID device (likely Syzkaller-crafted), triggering the loop
with bNumDescriptors > 1.

Impact: No immediate crash, but a code hygiene issue flagged by UBSAN.
Runtime safety depends on descriptor buffer allocation, but it’s a
potential source of confusion or future bugs.

Could HID maintainers investigate? Suggested fixes:
1. Use a flexible array member (desc[]) in struct hid_descriptor and
adjust parsing to rely on runtime buffer size.
2. Add stricter validation of hdesc->bNumDescriptors against bLength
to reject malformed descriptors earlier.

Our knowledge of the kernel is somewhat limited, and we'd appreciate
it if you could determine if there is such an issue. If this issue
doesn't have an impact, please ignore it ☺.
If you fix this issue, please add the following tag to the commit:
Reported-by: Zhizhuo Tang <strforexctzzchange@xxxxxxxxxxx>, Jianzhou
Zhao <xnxc22xnxc22@xxxxxx>, Haoran Liu <cherest_san@xxxxxxx>

======================================================================
usb 1-1: string descriptor 0 read error: -22
usb 1-1: New USB device found, idVendor=080e, idProduct=4eb9, bcdDevice=d7.f6
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
------------[ cut here ]------------
UBSAN: array-index-out-of-bounds in drivers/hid/usbhid/hid-core.c:1025:18
index 1 is out of range for type 'hid_class_descriptor [1]'
CPU: 1 UID: 0 PID: 11382 Comm: kworker/1:5 Not tainted 6.14.0-rc4 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
Workqueue: usb_hub_wq hub_event
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x180/0x1b0 lib/dump_stack.c:120
 ubsan_epilogue lib/ubsan.c:231 [inline]
 __ubsan_handle_out_of_bounds+0xdb/0x120 lib/ubsan.c:429
 usbhid_parse+0x9a4/0xa70 drivers/hid/usbhid/hid-core.c:1025
 hid_add_device+0x193/0xa90 drivers/hid/hid-core.c:2870
 usbhid_probe+0xf43/0x1440 drivers/hid/usbhid/hid-core.c:1431
 usb_probe_interface+0x30b/0x9e0 drivers/usb/core/driver.c:396
 call_driver_probe drivers/base/dd.c:579 [inline]
 really_probe+0x252/0xaa0 drivers/base/dd.c:658
 __driver_probe_device+0x1df/0x460 drivers/base/dd.c:800
 driver_probe_device+0x49/0x120 drivers/base/dd.c:830
 __device_attach_driver+0x1e3/0x2f0 drivers/base/dd.c:958
 bus_for_each_drv+0x14c/0x1e0 drivers/base/bus.c:462
 __device_attach+0x1f2/0x4d0 drivers/base/dd.c:1030
 bus_probe_device+0x17f/0x1c0 drivers/base/bus.c:537
 device_add+0xc5e/0x1490 drivers/base/core.c:3665
 usb_set_configuration+0x11a5/0x1c50 drivers/usb/core/message.c:2210
 usb_generic_driver_probe+0xbf/0x120 drivers/usb/core/generic.c:250
 usb_probe_device+0xed/0x3e0 drivers/usb/core/driver.c:291
 call_driver_probe drivers/base/dd.c:579 [inline]
 really_probe+0x252/0xaa0 drivers/base/dd.c:658
 __driver_probe_device+0x1df/0x460 drivers/base/dd.c:800
 driver_probe_device+0x49/0x120 drivers/base/dd.c:830
 __device_attach_driver+0x1e3/0x2f0 drivers/base/dd.c:958
 bus_for_each_drv+0x14c/0x1e0 drivers/base/bus.c:462
 __device_attach+0x1f2/0x4d0 drivers/base/dd.c:1030
 bus_probe_device+0x17f/0x1c0 drivers/base/bus.c:537
 device_add+0xc5e/0x1490 drivers/base/core.c:3665
 usb_new_device+0x8f4/0x1430 drivers/usb/core/hub.c:2663
 hub_port_connect+0x1122/0x2730 drivers/usb/core/hub.c:5533
 hub_port_connect_change+0x27c/0x7f0 drivers/usb/core/hub.c:5673
 port_event+0xe3d/0x1220 drivers/usb/core/hub.c:5833
 hub_event+0x517/0xca0 drivers/usb/core/hub.c:5915
 process_one_work+0x109d/0x18c0 kernel/workqueue.c:3236
 process_scheduled_works kernel/workqueue.c:3317 [inline]
 worker_thread+0x677/0xe90 kernel/workqueue.c:3398
 kthread+0x3b3/0x760 kernel/kthread.c:464
 ret_from_fork+0x48/0x80 arch/x86/kernel/process.c:148
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
 </TASK>
---[ end trace ]---





[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux