Ticket #20726 (closed defect: fixed)

Opened 5 months ago

Last modified 4 weeks ago

VirtualBox EHCI-controller doesn’t return host URB result when input length buffer is less than 0x4000 bytes

Reported by: lo1ol Owned by:
Component: USB Version: VirtualBox 6.1.30
Keywords: EHCI usb 2.0 Cc:
Guest type: Linux Host type: Linux



I have noticed some problems with USB 2.0 devices under VirtualBox (Beta 6.1.92 is also affected). Firstly, I’ve noticed problems with my smart card USB 2.0 reader. According to a log, each operation of reading data with input buffer more than 16*1024 bytes fails by timeout

opensc-tool --send-apdu “80:40:00:00
lo1ol@lo1ol-VirtualBox:~/Desktop$ opensc-tool --send-apdu "80:40:00:00:00"
Using reader with a card: Aktiv Rutoken ECP 00 00
Sending: 80 40 00 00 00 
APDU transmit failed: Card removed

VM’s usbmon output:

ffff96d8f3308000 3398494430 S Bi:1:005:2 -115 43 <
ffff96d8f3308000 3398496771 C Bi:1:005:2 0 25 = 800f0000 00000e00 00003b8b 01527574 6f6b656e 20445320 c1
ffff96d8f3308000 3398508627 S Bo:1:005:2 -115 15 = 6f050000 00000f00 00008040 000000
ffff96d8f3308000 3398510000 C Bo:1:005:2 0 15 >
ffff96d8f3308000 3398510386 S Bi:1:005:2 -115 65556 <
ffff96d8f3308000 3401515182 C Bi:1:005:2 -2 10 = 80000000 00000f80 0000
ffff96d9138d86c0 3401517591 S Bo:1:005:2 -115 10 = 65000000 00001000 0000

Host’s usbmon output:

ffff933d38f10600 1786904293 S Bi:3:008:2 -115 43 <
ffff933d38f10600 1786904357 C Bi:3:008:2 0 25 = 800f0000 00000e00 00003b8b 01527574 6f6b656e 20445320 c1
ffff933ce4e7a600 1786917684 S Bo:3:008:2 -115 15 = 6f050000 00000f00 00008040 000000
ffff933ce4e7a600 1786917732 C Bo:3:008:2 0 15 >
ffff933c8eae6600 1786920019 S Bi:3:008:2 -115 16384 <
ffff933c8eae6600 1786920065 C Bi:3:008:2 0 10 = 80000000 00000f80 0000
ffff933e4096c900 1789929753 S Bo:3:008:2 -115 10 = 65000000 00001000 0000
ffff933e4096c900 1789929820 C Bo:3:008:2 0 10 >

As you can see, the VM’s usbmon log has status=-2, but host log is not.

Also, I noticed that the input buffer length was changed. So I decided to reduce the maximal used input ccid buffer length to 0x4000(16384). This workaround helps me to resolve the problem.

So I tried to reproduce the problem via a usb 2.0 flash drive and wrote the following test program, which is affected by the same bug. sources: main.c


gcc main.c -lusb-1.0

Before run: Unmount/eject flash drive Unload uas and usb-storage modules: `bash sudo modprobe -r uas usb-storage ` Get idVend and idProd of device via lsusb You can also specify Bulk Endpoint addresses of your flash (you can get it via lsusb -v $idVend:$idProd). Defaults are 0x02 and 0x81

To run:

sudo LIBUSB_DEBUG=4 ./a.out {idVend} {idProd} [{epOut} {epIn}]

My usbmon output was the same as for the smart card bug:

ffff96d8e0037a80 676937289 S Bo:1:006:2 -115 31 = 55534243 01000000 24000000 80000612 00000024 00000000 00000000 000000
ffff96d8e0037a80 676972987 C Bo:1:006:2 0 31 >
ffff96d8e0037a80 676973082 S Bi:1:006:1 -115 16385 <
ffff96d8e0037a80 679977237 C Bi:1:006:1 -2 36 = 00800402 1f736d69 55464420 322e3020 53696c69 636f6e2d 506f7765 72313647

I think there is some problem with your EHCI-controller driver implementation. May you reproduce the bug by yourself, confirm and fix it?

Waiting for your response! Thanks!


main.c Download (2.3 KB) - added by lo1ol 5 months ago.
Program to reproduce the bug

Change History

comment:1 Changed 5 months ago by klaus

You forgot to attach your test program. I doubt that any main.c file will do.

Changed 5 months ago by lo1ol

Program to reproduce the bug

comment:2 Changed 5 months ago by lo1ol

Sorry. I attach it.

May you please move this bug to USB section? I forgot to specify it when create the bug…

comment:3 Changed 4 months ago by michaln

  • Component changed from other to USB

What is the host and guest Linux kernel version? Or have you tested it widely enough that you're confident the versions do not matter?

comment:4 Changed 4 months ago by lo1ol

I use Ubuntu 21.04 with kernel 5.11.0-41 as host and guest, but I think that distro and kernel version doesn't matter

comment:5 Changed 4 months ago by michaln

I can reproduce the problem (on a Windows host even). I believe your description of the problem is significantly incomplete, but the testcase you provided is great and shows the bug clearly.

The problematic case seems to be triggered by an IN URB larger than 16K on guest EHCI if the device returns less than 16K. I haven't looked but it looks like Linux splits EHCI transfers to 16K chunks because that's the about maximum one EHCI qTD can always cover.

I'll let you know once I find out more, but I have an idea where the problem might be.

comment:6 Changed 4 months ago by michaln

It looks like this bug is actually very straightforward. The emulated HC does not signal interrupts on short packets, only if the IOC bit is set. The catch here is that if your URB is 16K or less, the corresponding EHCI qTD will always have the IOC bit set and it won't matter if the transfer is short or not.

The problem will probably only trigger if you queue an IN URB that is larger than 16K, will be split in multiple qTDs, and the device sends back an amount data such that the transfer ends on a qTD that does not have the IOC bit set. Depending on the guest USB stack/EHCI driver, that might never happen or not cause obvious problems. With many USB device classes it will also never happen.

comment:7 Changed 4 months ago by lo1ol

Thank you for research!

I got you. This behavior will be fixed in future Extension Pack releases?

comment:8 Changed 4 months ago by michaln

Yes, though unfortunately the fix came a bit too late to make it into 6.1.32.

comment:9 Changed 4 weeks ago by galitsyn

  • Status changed from new to closed
  • Resolution set to fixed

The issue should be fixed in VirtualBox 6.1.34. Closing.

Note: See TracTickets for help on using tickets.
ContactPrivacy policyTerms of Use