From 477b44bb1831c15cdbabfa4db6e6d9f2d261a722 Mon Sep 17 00:00:00 2001 From: Andrey Gusakov Date: Mon, 22 Jun 2026 17:49:27 +0300 Subject: [PATCH] usb: truncate string descriptor response to match setup.wLength Windows requests the first 2 bytes of a string descriptor to read its size before asking for the full string. This fix ensures the firmware truncates the response data to match wLength, preventing endpoint stalls and timeouts on strict hosts. --- os/hal/src/hal_usb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/os/hal/src/hal_usb.c b/os/hal/src/hal_usb.c index 033977449b..173a83d54d 100644 --- a/os/hal/src/hal_usb.c +++ b/os/hal/src/hal_usb.c @@ -126,6 +126,8 @@ static bool default_handler(USBDriver *usbp) { return true; case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_GET_DESCRIPTOR << 8): case (uint32_t)USB_RTYPE_RECIPIENT_INTERFACE | ((uint32_t)USB_REQ_GET_DESCRIPTOR << 8): + { + size_t wLength; /* Handling descriptor requests from the host.*/ dp = usbp->config->get_descriptor_cb(usbp, usbp->setup[3], usbp->setup[2], @@ -133,10 +135,12 @@ static bool default_handler(USBDriver *usbp) { if (dp == NULL) { return false; } + wLength = get_hword(&usbp->setup[6]); /*lint -save -e9005 [11.8] Removing const is fine.*/ - usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL); + usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, wLength < dp->ud_size ? wLength : dp->ud_size, NULL); /*lint -restore*/ return true; + } case (uint32_t)USB_RTYPE_RECIPIENT_DEVICE | ((uint32_t)USB_REQ_GET_CONFIGURATION << 8): /* Returning the last selected configuration.*/ usbSetupTransfer(usbp, &usbp->configuration, 1, NULL);