hathach / tinyusb

An open source cross-platform USB stack for embedded system
https://www.tinyusb.org
MIT License
4.66k stars 996 forks source link

EHCI driver attempts transfers exceeding the max transfer size #2645

Open bmbrownlee opened 1 month ago

bmbrownlee commented 1 month ago

Operating System

Linux

Board

i.MX6SL

Firmware

Custom firmware based on tinyusb v0.16.0 and small changes to portable/chipidea/ci_hs to support i.MX6SL using MSC/CDC interfaces. Issue effects all builds which use EHCI.

What happened ?

The EHCI driver does not check that the requested transfer size (uint16_t, max value of 65535 bytes) does not exceed the limit for a single qTD, which is 16385-20480 bytes depending on the provided buffer's alignment (see section 3.5 of the rev 1.0 EHCI spec). This results in data getting dropped, or in worse case scenarios, an invalid driver state that results in lockup of the USB stack.

A simple fix would be to return false from hcd_edpt_xfer() if the requested buflen is too large, forcing implementers to split transactions themselves. A more robust solution would be to automatically split transfers into multiple qTD and attach them together in the linked list. This, however, would require a significant restructuring of the EHCI driver code.

How to reproduce ?

Consider a setup using tinyusb and fatfs connected together. The maximum size read/write that fatfs will ever make is the cluster size of the filesystem. For a 64GiB flashdrive, many filesystem format tools will choose a fat cluster size of 64, meaning fatfs may request transfers as large as 64 * 512 = 32768 bytes. If you do not manually split the request between disk_read/disk_write and tuh_msc_read10/tuh_msc_write10, then the behavior described above may occur. The example in host/msc_file_explorer makes this mistake.

Debug Log as txt file (LOG/CFG_TUSB_DEBUG=2)

n/a

Screenshots

No response

I have checked existing issues, dicussion and documentation