Hello,
Came across this while investigating this bug for libusb0.sys: https://github.com/mcuee/libusb-win32/issues/51
The problem is this:
If IOCTL_INTERNAL_USB_SUBMIT_URB is submitted for a bulk endpoint and the transmission size is larger than permitted, at some sizes the USBD driver below triggers a BSOD, with BAD_POOL_HEADER or KERNEL_MODE_HEAP_CORRUPTION.
It starts to starts to occur at 16-32MB for a full-speed device.
I would expect the USBD driver to either reject or cap the transfer if the value was too high, but I would not expect it to BSOD.
Has anyone observed this problem as well?
is this just a trivial bug in USBD.sys? Or do you have to call the driver differently when reaching those sizes?
Currently the work-around is to just cap the transfer before calling USBD.
Thanks,
/pedro
People don’t remember the “bad old days”, but it used to be that the maximum transfer was different for each speed, and in some cases was limited to a few dozen KILOBYTES.
You need to remember that the host controller driver has to chop that buffer up into packet-sized chunks, and for a full-size bulk endpoint, that means 64 bytes each. You’re talking about half a million packets, which would span 20 or 30 seconds. It’s not a reasonable design.
Hi Tim,
People don’t remember the “bad old days”, but it used to be that the maximum transfer was different for each speed, and in some cases was limited >>to a few dozen KILOBYTES.
No, of course i would never start such a transfer in a sane setup. After working with USB since version 1.0 I am well aware of the limitations in the various versions, packet types and controller limitations. I would never do this deliberately. I only came upon it during the libusb0 investigation into a BSOD.
And total transfer sizes are still limited for each speed (at least on windows):
https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-bandwidth-allocation
I was more worried about an actual bug in the USBD, that could be triggered by an app to trigger a BSOD.
The bug triggers immediately when calling, and not after a while.
I am guessing its just a trivial length check missing in USBD.
For now I have worked around by chopping up the transfer into smaller pieces for the user, avoiding the BSOD.
It’s not a reasonable design.
For USB 3.2 or 4.0 32MB is not unreasonable in any way (the last test I did just happened to be full-speed, but high-speed and super-speed crash the same way).
Thanks,
/pedro