VirtualBox

Changeset 83567 in vbox for trunk/src


Ignore:
Timestamp:
Apr 5, 2020 7:24:56 PM (5 years ago)
Author:
vboxsync
Message:

DevVirtioSCSI.cpp: Made virtioScsiR3ReqErr use a stack buffer for the sense data instead of heap. Eliminated the other allocations too in that function. bugref:9440

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp

    r83566 r83567  
    765765 * @param   pRespHdr    Response header
    766766 * @param   pbSense     Pointer to sense buffer or NULL if none.
     767 * @param   cbSenseCfg  The configured sense buffer size.
    767768 *
    768  * @returns VBox status code.
     769 * @returns VINF_SUCCESS
    769770 */
    770771static int virtioScsiR3ReqErr(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t qIdx,
    771                               PVIRTIO_DESC_CHAIN_T pDescChain, REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense)
    772 {
    773     /** @todo r=bird: There is too much allocating here and we'll leak stuff if
    774      *        we're low on memory and one of the RTMemAllocZ calls fail! */
    775     uint8_t *pabSenseBuf = (uint8_t *)RTMemAllocZ(pThis->virtioScsiConfig.uSenseSize);
    776     AssertReturn(pabSenseBuf, VERR_NO_MEMORY);
    777 
     772                              PVIRTIO_DESC_CHAIN_T pDescChain, REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense,
     773                              uint32_t cbSenseCfg)
     774{
    778775    Log2Func(("   status: %s    response: %s\n",
    779776              SCSIStatusText(pRespHdr->uStatus), virtioGetReqRespText(pRespHdr->uResponse)));
    780777
    781     PRTSGBUF pReqSegBuf = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF));
    782     AssertReturn(pReqSegBuf, VERR_NO_MEMORY);
    783 
    784     PRTSGSEG paReqSegs  = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * 2);
    785     AssertReturn(paReqSegs, VERR_NO_MEMORY);
    786 
    787     paReqSegs[0].cbSeg = sizeof(*pRespHdr);
    788     paReqSegs[0].pvSeg = pRespHdr;
    789     paReqSegs[1].cbSeg = pThis->virtioScsiConfig.uSenseSize;
    790     paReqSegs[1].pvSeg = pabSenseBuf;
    791 
     778    RTSGSEG aReqSegs[2];
     779
     780    /* Segment #1: Request header*/
     781    aReqSegs[0].pvSeg = pRespHdr;
     782    aReqSegs[0].cbSeg = sizeof(*pRespHdr);
     783
     784    /* Segment #2: Sense data. */
     785    uint8_t abSenseBuf[VIRTIOSCSI_SENSE_SIZE_MAX];
     786    AssertCompile(VIRTIOSCSI_SENSE_SIZE_MAX <= 4096);
     787    Assert(cbSenseCfg <= sizeof(abSenseBuf));
     788
     789    RT_ZERO(abSenseBuf);
    792790    if (pbSense && pRespHdr->cbSenseLen)
    793         memcpy(pabSenseBuf, pbSense, pRespHdr->cbSenseLen);
     791        memcpy(abSenseBuf, pbSense, RT_MIN(pRespHdr->cbSenseLen, sizeof(abSenseBuf)));
    794792    else
    795793        pRespHdr->cbSenseLen = 0;
    796794
    797     /* Copy segment data to malloc'd memory to avoid stack out-of-scope errors sanitizer doesn't detect */
    798     /** @todo r=bird: The above comment makes zero sense as the memory is freed
    799      *        before we return, so there cannot be any trouble with out-of-scope
    800      *        stuff here. */
    801     for (int i = 0; i < 2; i++)
    802     {
    803         void *pv = paReqSegs[i].pvSeg;
    804         paReqSegs[i].pvSeg = RTMemDup(pv, paReqSegs[i].cbSeg);
    805         AssertReturn(paReqSegs[i].pvSeg, VERR_NO_MEMORY);
    806     }
    807 
    808     RTSgBufInit(pReqSegBuf, paReqSegs, 2);
     795    aReqSegs[1].pvSeg = abSenseBuf;
     796    aReqSegs[1].cbSeg = cbSenseCfg;
     797
     798    /* Init S/G buffer. */
     799    RTSGBUF ReqSgBuf;
     800    RTSgBufInit(&ReqSgBuf, aReqSegs, RT_ELEMENTS(aReqSegs));
    809801
    810802    if (pThis->fResetting)
    811803        pRespHdr->uResponse = VIRTIOSCSI_S_RESET;
    812804
    813     virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, qIdx, pReqSegBuf, pDescChain, true /* fFence */);
     805    virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, qIdx, &ReqSgBuf, pDescChain, true /* fFence */);
    814806    virtioCoreQueueSync(pDevIns, &pThis->Virtio, qIdx);
    815 
    816     for (int i = 0; i < 2; i++)
    817         RTMemFree(paReqSegs[i].pvSeg);
    818 
    819     RTMemFree(paReqSegs);
    820     RTMemFree(pReqSegBuf);
    821     RTMemFree(pabSenseBuf);
    822807
    823808    if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing)
     
    948933        respHdr.uResidual  = pReq->cbDataIn;
    949934
    950         virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->qIdx, pReq->pDescChain, &respHdr, abSense);
     935        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->qIdx, pReq->pDescChain, &respHdr, abSense,
     936                           RT_MIN(pThis->virtioScsiConfig.uSenseSize, VIRTIOSCSI_SENSE_SIZE_MAX));
    951937    }
    952938    else
     
    11981184        respHdr.uResponse  = VIRTIOSCSI_S_FAILURE;
    11991185        respHdr.uResidual  = cbDataIn + cbDataOut;
    1200         virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr , NULL);
     1186        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL, cbSense);
    12011187        return VINF_SUCCESS;
    12021188    }
     
    12171203        respHdr.uResponse  = VIRTIOSCSI_S_BAD_TARGET;
    12181204        respHdr.uResidual  = cbDataOut + cbDataIn;
    1219         virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense);
     1205        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense);
    12201206        return VINF_SUCCESS;
    12211207
     
    12341220        respHdr.uResponse  = VIRTIOSCSI_S_OK;
    12351221        respHdr.uResidual  = cbDataOut + cbDataIn;
    1236         virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense);
     1222        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense);
    12371223        return VINF_SUCCESS;
    12381224    }
     
    12471233        respHdr.uResponse  = VIRTIOSCSI_S_RESET;
    12481234        respHdr.uResidual  = cbDataIn + cbDataOut;
    1249         virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL);
     1235        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL, cbSense);
    12501236        return VINF_SUCCESS;
    12511237    }
     
    12651251        respHdr.uResponse  = VIRTIOSCSI_S_FAILURE;
    12661252        respHdr.uResidual  = cbDataIn + cbDataOut;
    1267         virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr , abSense);
     1253        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense);
    12681254        return VINF_SUCCESS;
    12691255    }
     
    13291315        respHdr.uResponse  = VIRTIOSCSI_S_FAILURE;
    13301316        respHdr.uResidual  = cbDataIn + cbDataOut;
    1331         virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense);
     1317        virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense);
    13321318        virtioScsiR3FreeReq(pTarget, pReq);
    13331319    }
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