VirtualBox

Changeset 90049 in vbox for trunk


Ignore:
Timestamp:
Jul 6, 2021 10:23:26 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
145543
Message:

VUSB: If a descriptor read can't be satisfied from cache, pass it through to device rather than returning an error (stall). Fixes a problem with buggy drivers for Logitech C930e from Windows Update (see bugref:10059).

Location:
trunk/src/VBox/Devices/USB
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/USB/VUSBDevice.cpp

    r90025 r90049  
    810810
    811811/**
     812 * Checks whether a descriptor read can be satisfied by reading from the
     813 * descriptor cache or has to be passed to the device.
     814 * If we have descriptors cached, it is generally safe to satisfy descriptor reads
     815 * from the cache. As usual, there is broken USB software and hardware out there
     816 * and guests might try to read a nonexistent desciptor (out of range index for
     817 * string or configuration descriptor) and rely on it not failing.
     818 * Since we cannot very well guess if such invalid requests should really succeed,
     819 * and what exactly should happen if they do, we pass such requests to the device.
     820 * If the descriptor was cached because it was edited, and the guest bypasses the
     821 * edited cache by reading a descriptor with an invalid index, it is probably
     822 * best to smash the USB device with a large hammer.
     823 *
     824 * See @bugref{10016}.
     825 *
     826 * @returns false if request must be passed to device.
     827 */
     828bool vusbDevIsDescriptorInCache(PVUSBDEV pDev, PCVUSBSETUP pSetup)
     829{
     830    unsigned int iIndex = (pSetup->wValue & 0xff);
     831    Assert(pSetup->bRequest == VUSB_REQ_GET_DESCRIPTOR);
     832
     833    if ((pSetup->bmRequestType & VUSB_RECIP_MASK) == VUSB_TO_DEVICE)
     834    {
     835        if (pDev->pDescCache->fUseCachedDescriptors)
     836        {
     837            switch (pSetup->wValue >> 8)
     838            {
     839            case VUSB_DT_DEVICE:
     840                if (iIndex == 0)
     841                    return true;
     842
     843                LogRelMax(10, ("VUSB: %s: Warning: Reading device descriptor with non-zero index %u (wLength=%u), passing request to device\n",
     844                               pDev->pUsbIns->pszName, iIndex, pSetup->wLength));
     845                break;
     846
     847            case VUSB_DT_CONFIG:
     848                if (iIndex < pDev->pDescCache->pDevice->bNumConfigurations)
     849                    return true;
     850
     851                LogRelMax(10, ("VUSB: %s: Warning: Reading configuration descriptor invalid index %u (bNumConfigurations=%u, wLength=%u), passing request to device\n",
     852                               pDev->pUsbIns->pszName, iIndex, pDev->pDescCache->pDevice->bNumConfigurations, pSetup->wLength));
     853                break;
     854
     855            case VUSB_DT_STRING:
     856                if (pDev->pDescCache->fUseCachedStringsDescriptors)
     857                {
     858                    if (pSetup->wIndex == 0)    /* Language IDs. */
     859                        return true;
     860
     861                    if (FindCachedString(pDev->pDescCache->paLanguages, pDev->pDescCache->cLanguages,
     862                                         pSetup->wIndex, iIndex))
     863                        return true;
     864                }
     865                break;
     866
     867            default:
     868                break;
     869            }
     870            Log(("VUSB: %s: Descriptor not cached: type=%u descidx=%u lang=%u len=%u, passing request to device\n",
     871                 pDev->pUsbIns->pszName, pSetup->wValue >> 8, iIndex, pSetup->wIndex, pSetup->wLength));
     872        }
     873    }
     874    return false;
     875}
     876
     877
     878/**
    812879 * Standard device request: GET_DESCRIPTOR
    813880 * @returns success indicator.
    814  * @remark not really used yet as we consider GET_DESCRIPTOR 'safe'.
    815881 */
    816882static bool vusbDevStdReqGetDescriptor(PVUSBDEV pDev, int EndPt, PVUSBSETUP pSetup, uint8_t *pbBuf, uint32_t *pcbBuf)
  • trunk/src/VBox/Devices/USB/VUSBInternal.h

    r87762 r90049  
    533533int  vusbUrbQueueAsyncRh(PVUSBURB pUrb);
    534534
     535bool vusbDevIsDescriptorInCache(PVUSBDEV pDev, PCVUSBSETUP pSetup);
     536
    535537/**
    536538 * Initializes the given URB pool.
  • trunk/src/VBox/Devices/USB/VUSBUrb.cpp

    r87609 r90049  
    410410         */
    411411        case VUSB_REQ_GET_DESCRIPTOR:
    412             if (    !pUrb->pVUsb->pDev->pDescCache->fUseCachedDescriptors
    413                 ||  (pSetup->bmRequestType & VUSB_RECIP_MASK) != VUSB_TO_DEVICE)
    414                 return true;
    415             switch (pSetup->wValue >> 8)
    416             {
    417                 case VUSB_DT_DEVICE:
    418                 case VUSB_DT_CONFIG:
    419                     return false;
    420                 case VUSB_DT_STRING:
    421                     return !pUrb->pVUsb->pDev->pDescCache->fUseCachedStringsDescriptors;
    422                 default:
    423                     return true;
    424             }
     412            return !vusbDevIsDescriptorInCache(pUrb->pVUsb->pDev, pSetup);
    425413
    426414        default:
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette