VirtualBox

Changeset 87161 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jan 4, 2021 12:45:18 PM (4 years ago)
Author:
vboxsync
Message:

USB/IP: Be more strict about stuff we accept from the remote end, bugref:9861

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/USB/usbip/USBProxyDevice-usbip.cpp

    r82968 r87161  
    820820static int usbProxyUsbIpDisconnect(PUSBPROXYDEVUSBIP pProxyDevUsbIp)
    821821{
    822     int rc = VINF_SUCCESS;
     822    int rc = RTPollSetRemove(pProxyDevUsbIp->hPollSet, USBIP_POLL_ID_SOCKET);
     823    Assert(RT_SUCCESS(rc) || rc == VERR_POLL_HANDLE_ID_NOT_FOUND);
    823824
    824825    rc = RTTcpClientCloseEx(pProxyDevUsbIp->hSocket, false /*fGracefulShutdown*/);
     
    964965                case USBPROXYUSBIPRECVSTATE_HDR_RESIDUAL:
    965966                {
    966                     /** @todo Verify that the directions match, verify that the length doesn't exceed the buffer. */
    967 
    968967                    switch (RT_N2H_U32(pProxyDevUsbIp->BufRet.Hdr.u32ReqRet))
    969968                    {
     
    980979                                {
    981980                                    uint8_t *pbData = NULL;
     981                                    size_t cbRet = 0;
    982982
    983983                                    AssertPtr(pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb);
     
    986986                                        /* Preserve the setup request. */
    987987                                        pbData = &pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->abData[sizeof(VUSBSETUP)];
    988                                         pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength + sizeof(VUSBSETUP);
     988                                        cbRet = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength + sizeof(VUSBSETUP);
    989989                                    }
    990990                                    else
    991991                                    {
    992992                                        pbData = &pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->abData[0];
    993                                         pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength;
     993                                        cbRet = pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength;
    994994                                    }
    995995
    996996                                    if (pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength)
    997                                         usbProxyUsbIpRecvStateAdvance(pProxyDevUsbIp, USBPROXYUSBIPRECVSTATE_URB_BUFFER,
    998                                                                       pbData, pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength);
     997                                    {
     998                                        if (RT_LIKELY(pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData >= cbRet))
     999                                        {
     1000                                            pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData = cbRet;
     1001                                            usbProxyUsbIpRecvStateAdvance(pProxyDevUsbIp, USBPROXYUSBIPRECVSTATE_URB_BUFFER,
     1002                                                                          pbData, pProxyDevUsbIp->BufRet.RetSubmit.u32ActualLength);
     1003                                        }
     1004                                        else
     1005                                        {
     1006                                            /*
     1007                                             * Bogus length returned from the USB/IP remote server.
     1008                                             * Error out because there is no way to find the end of the current
     1009                                             * URB and the beginning of the next one. The error will cause closing the
     1010                                             * connection to the rogue remote and all URBs get completed with an error.
     1011                                             */
     1012                                            LogRelMax(10, ("USB/IP: Received reply with sequence number %u contains invalid length %zu (max %zu)\n",
     1013                                                           pProxyDevUsbIp->BufRet.Hdr.u32SeqNum, cbRet,
     1014                                                           pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData));
     1015                                            rc = VERR_NET_PROTOCOL_ERROR;
     1016                                        }
     1017                                    }
    9991018                                    else
    10001019                                    {
     
    10151034                                        RT_N2H_U32(pProxyDevUsbIp->BufRet.Hdr.u32SeqNum)));
    10161035                                usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
     1036                                rc = VERR_NET_PROTOCOL_ERROR;
    10171037                            }
    10181038                            break;
     
    10491069                    {
    10501070                        PVUSBURBISOCPTK pIsocPkt = &pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->aIsocPkts[i];
    1051                         usbProxyUsbIpIsocPktDescN2H(&pProxyDevUsbIp->aIsocPktDesc[i]);
    1052                         pIsocPkt->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pProxyDevUsbIp->aIsocPktDesc[i].i32Status);
    1053                         pIsocPkt->off       = pProxyDevUsbIp->aIsocPktDesc[i].u32Offset;
    1054                         pIsocPkt->cb        = pProxyDevUsbIp->aIsocPktDesc[i].u32ActualLength;
     1071                        PUsbIpIsocPktDesc pIsocPktUsbIp = &pProxyDevUsbIp->aIsocPktDesc[i];
     1072
     1073                        usbProxyUsbIpIsocPktDescN2H(pIsocPktUsbIp);
     1074                        pIsocPkt->enmStatus = usbProxyUsbIpVUsbStatusConvertFromStatus(pIsocPktUsbIp->i32Status);
     1075
     1076                        if (RT_LIKELY(   pIsocPktUsbIp->u32Offset < pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData
     1077                                      && pProxyDevUsbIp->pUrbUsbIp->pVUsbUrb->cbData - pIsocPktUsbIp->u32Offset >= pIsocPktUsbIp->u32ActualLength))
     1078                        {
     1079                            pIsocPkt->off = pIsocPktUsbIp->u32Offset;
     1080                            pIsocPkt->cb  = pIsocPktUsbIp->u32ActualLength;
     1081                        }
     1082                        else
     1083                        {
     1084                            /*
     1085                             * The offset and length value in the isoc packet descriptor are bogus and would cause a buffer overflow later on, leave an
     1086                             * error message and disconnect from the rogue remote end.
     1087                             */
     1088                            LogRelMax(10, ("USB/IP: Received reply with sequence number %u contains invalid isoc packet descriptor %u (offset=%u length=%u)\n",
     1089                                           pProxyDevUsbIp->BufRet.Hdr.u32SeqNum, i,
     1090                                           pIsocPktUsbIp->u32Offset, pIsocPktUsbIp->u32ActualLength));
     1091                            rc = VERR_NET_PROTOCOL_ERROR;
     1092                            break;
     1093                        }
    10551094                    }
    10561095
     
    10631102        }
    10641103    }
    1065     else
    1066     {
    1067         /** @todo Complete all URBs with DNR error and mark device as unplugged. */
    1068 #if 0
    1069         pUrbUsbIp = pProxyDevUsbIp->pUrbUsbIp;
    1070         pUrbUsbIp->pVUsbUrb->enmStatus = VUSBSTATUS_DNR;
    1071         usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
    1072 #endif
    1073     }
    10741104
    10751105    if (RT_SUCCESS(rc))
    10761106        *ppUrbUsbIp = pUrbUsbIp;
     1107    else
     1108    {
     1109        /* Complete all URBs with DNR error and mark device as unplugged, the current one is still in the in flight list. */
     1110        pProxyDevUsbIp->pUrbUsbIp = NULL;
     1111        usbProxyUsbIpResetRecvState(pProxyDevUsbIp);
     1112        usbProxyUsbIpDisconnect(pProxyDevUsbIp);
     1113
     1114        rc = RTSemFastMutexRequest(pProxyDevUsbIp->hMtxLists);
     1115        AssertRC(rc);
     1116        PUSBPROXYURBUSBIP pIt;
     1117        PUSBPROXYURBUSBIP pItNext;
     1118        RTListForEachSafe(&pProxyDevUsbIp->ListUrbsInFlight, pIt, pItNext, USBPROXYURBUSBIP, NodeList)
     1119        {
     1120            if (pIt->pVUsbUrb) /* can be NULL for requests created by usbProxyUsbIpCtrlUrbExchangeSync(). */
     1121                pIt->pVUsbUrb->enmStatus = VUSBSTATUS_CRC;
     1122            RTListNodeRemove(&pIt->NodeList);
     1123            RTListAppend(&pProxyDevUsbIp->ListUrbsLanded, &pIt->NodeList);
     1124        }
     1125        RTSemFastMutexRelease(pProxyDevUsbIp->hMtxLists);
     1126    }
    10771127
    10781128    return rc;
     
    11711221            break;
    11721222        default:
    1173             usbProxyUsbIpUrbFree(pProxyDevUsbIp, pUrbUsbIp);
    11741223            return VERR_INVALID_PARAMETER; /** @todo better status code. */
    11751224    }
     
    12161265        if (RT_FAILURE(rc))
    12171266        {
    1218             /** @todo  Complete the URB with an error. */
    1219             usbProxyUsbIpUrbFree(pProxyDevUsbIp, pIter);
     1267            /* Complete URB with an error and place into landed list. */
     1268            pIter->pVUsbUrb->enmStatus = VUSBSTATUS_DNR;
     1269            usbProxyUsbIpLinkUrb(pProxyDevUsbIp, &pProxyDevUsbIp->ListUrbsLanded, pIter);
    12201270        }
    12211271    }
     
    14751525
    14761526    PUSBPROXYDEVUSBIP pDevUsbIp = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVUSBIP);
     1527    if (pDevUsbIp->hSocket != NIL_RTSOCKET)
     1528        usbProxyUsbIpDisconnect(pDevUsbIp);
     1529
    14771530    /* Destroy the pipe and pollset if necessary. */
    14781531    if (pDevUsbIp->hPollSet != NIL_RTPOLLSET)
    14791532    {
    1480         if (pDevUsbIp->hSocket != NIL_RTSOCKET)
    1481         {
    1482             rc = RTPollSetRemove(pDevUsbIp->hPollSet, USBIP_POLL_ID_SOCKET);
    1483             Assert(RT_SUCCESS(rc) || rc == VERR_POLL_HANDLE_ID_NOT_FOUND);
    1484         }
    14851533        rc = RTPollSetRemove(pDevUsbIp->hPollSet, USBIP_POLL_ID_PIPE);
    14861534        AssertRC(rc);
     
    14931541    }
    14941542
    1495     if (pDevUsbIp->hSocket != NIL_RTSOCKET)
    1496         usbProxyUsbIpDisconnect(pDevUsbIp);
    14971543    if (pDevUsbIp->pszHost)
    14981544        RTStrFree(pDevUsbIp->pszHost);
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