VirtualBox

Changeset 81300 in vbox for trunk/src/VBox/Devices/VirtIO


Ignore:
Timestamp:
Oct 17, 2019 5:51:54 AM (5 years ago)
Author:
vboxsync
Message:

Storage/DevVirtioSCSI.cpp: Improved bounds checking for MMIO functions, and tried to address Guru meditation reported by aichner in comment #9440 Comment #103 and the issues in Comment #110. See Comment #112

Location:
trunk/src/VBox/Devices/VirtIO
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp

    r81231 r81300  
    188188    } while (desc.fFlags & VIRTQ_DESC_F_NEXT);
    189189
    190 
    191190    PRTSGBUF pSgPhysIn = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF));
    192191    AssertReturn(pSgPhysIn, VERR_NO_MEMORY);
     
    194193    RTSgBufInit(pSgPhysIn, (PCRTSGSEG)paSegsIn, cSegsIn);
    195194
    196     void *pVirtOut = RTMemAlloc(cbOut);
    197     AssertReturn(pVirtOut, VERR_NO_MEMORY);
    198 
    199     /* If there's any guest → device data in phys. memory pulled
    200      * from queue, copy it into virtual memory to return to caller */
    201 
    202     if (cSegsOut)
    203     {
    204         uint8_t *outSgVirt = (uint8_t *)pVirtOut;
    205         RTSGBUF outSgPhys;
    206         RTSgBufInit(&outSgPhys, (PCRTSGSEG)paSegsOut, cSegsOut);
    207         for (size_t cb = cbOut; cb;)
    208         {
    209             size_t cbSeg = cb;
    210             RTGCPHYS GCPhys = (RTGCPHYS)RTSgBufGetNextSegment(&outSgPhys, &cbSeg);
    211             PDMDevHlpPhysRead(((PVIRTIOSTATE)hVirtio)->CTX_SUFF(pDevIns), GCPhys, outSgVirt, cbSeg);
    212             outSgVirt = ((uint8_t *)outSgVirt) + cbSeg;
    213             cb -= cbSeg;
    214         }
    215         RTMemFree(paSegsOut);
    216     }
     195    PRTSGBUF pSgPhysOut = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF));
     196    AssertReturn(pSgPhysOut, VERR_NO_MEMORY);
     197
     198    RTSgBufInit(pSgPhysOut, (PCRTSGSEG)paSegsOut, cSegsOut);
    217199
    218200    PVIRTIO_DESC_CHAIN_T pDescChain = (PVIRTIO_DESC_CHAIN_T)RTMemAllocZ(sizeof(VIRTIO_DESC_CHAIN_T));
     
    220202
    221203    pDescChain->uHeadIdx   = uHeadIdx;
    222     pDescChain->cbVirtSrc  = cbOut;
    223     pDescChain->pVirtSrc   = pVirtOut;
    224     pDescChain->cbPhysDst  = cbIn;
    225     pDescChain->pSgPhysDst = pSgPhysIn;
     204    pDescChain->cbPhysSend  = cbOut;
     205    pDescChain->pSgPhysSend = pSgPhysOut;
     206    pDescChain->cbPhysReturn  = cbIn;
     207    pDescChain->pSgPhysReturn = pSgPhysIn;
    226208    *ppDescChain = pDescChain;
    227209
     
    240222    PVIRTIOSTATE pVirtio = (PVIRTIOSTATE)hVirtio;
    241223    PVIRTQSTATE  pVirtq = &pVirtio->virtqState[qIdx];
    242     PRTSGBUF pSgPhysReturn = pDescChain->pSgPhysDst;
     224    PRTSGBUF pSgPhysReturn = pDescChain->pSgPhysReturn;
     225
    243226
    244227    AssertMsgReturn(DRIVER_OK(pVirtio) /*&& pVirtio->uQueueEnable[qIdx]*/,
     
    251234
    252235    /*
    253      * Copy virtual memory s/g buffer containing data to return to the guest
    254      * to phys. memory described by (IN direction ) s/g buffer of the descriptor chain
    255      * (pulled from avail ring of queue), essentially giving result back to the guest driver.
    256      */
     236     * Copy s/g buf (virtual memory) to guest phys mem (IN direction). This virtual memory
     237     * block will be small (fixed portion of response header + sense buffer area or
     238     * control commands or error return values)... The bulk of req data xfers to phys mem
     239     * is handled by client */
     240
    257241    size_t cbCopy = 0;
    258242    size_t cbRemain = RTSgBufCalcTotalLength(pSgVirtReturn);
     243    RTSgBufReset(pSgPhysReturn); /* Reset ptr because req data may have already been written */
    259244    while (cbRemain)
    260245    {
     
    272257
    273258    if (fFence)
    274         RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     259        RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); /* needed? */
    275260
    276261    /** If this write-ahead crosses threshold where the driver wants to get an event flag it */
     
    287272            (uint32_t)(cbCopy & 0xffffffff));
    288273
    289     Log2Func((".... Copied %ul bytes to %ul byte buffer, residual=%ul\n",
    290          cbCopy, pDescChain->cbPhysDst, pDescChain->cbPhysDst - cbCopy));
     274    Log2Func((".... Copied %lu bytes to %lu byte buffer, residual=%lu\n",
     275         cbCopy, pDescChain->cbPhysReturn, pDescChain->cbPhysReturn - cbCopy));
    291276
    292277    Log6Func(("Write ahead used_idx=%d, %s used_idx=%d\n",
     
    561546    {
    562547        if (fWrite) /* Guest WRITE pCommonCfg>uDeviceFeatures */
     548        {
    563549            LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.device_feature\n"));
     550            return VINF_SUCCESS;
     551        }
    564552        else /* Guest READ pCommonCfg->uDeviceFeatures */
    565553        {
     
    581569                    LogFunc(("Guest read uDeviceFeatures with out of range selector (%d), returning 0\n",
    582570                          pVirtio->uDeviceFeaturesSelect));
    583                     return VERR_ACCESS_DENIED;
     571                    return VINF_IOM_MMIO_UNUSED_00;
    584572            }
    585573        }
     
    604592                    LogFunc(("Guest wrote uDriverFeatures with out of range selector (%d), returning 0\n",
    605593                         pVirtio->uDriverFeaturesSelect));
    606                     return VERR_ACCESS_DENIED;
     594                    return VINF_SUCCESS;
    607595            }
    608596        }
     
    626614                    LogFunc(("Guest read uDriverFeatures with out of range selector (%d), returning 0\n",
    627615                         pVirtio->uDriverFeaturesSelect));
    628                     return VERR_ACCESS_DENIED;
     616                    return VINF_IOM_MMIO_UNUSED_00;
    629617            }
    630618        }
     
    635623        {
    636624            Log2Func(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n"));
    637             return VERR_ACCESS_DENIED;
     625            return VINF_SUCCESS;
    638626        }
    639627        else
     
    712700        Log2Func(("Bad guest %s access to virtio_pci_common_cfg: uOffset=%d, cb=%d\n",
    713701            fWrite ? "write" : "read ", uOffset, cb));
    714         rc = VERR_ACCESS_DENIED;
     702        return fWrite ? VINF_SUCCESS : VINF_IOM_MMIO_UNUSED_00;
    715703    }
    716704    return rc;
     
    770758    {
    771759        uint32_t uOffset = GCPhysAddr - pVirtio->pGcPhysCommonCfg;
    772         virtioCommonCfgAccessed(pVirtio, false /* fWrite */, uOffset, cb, (void const *)pv);
     760        rc = virtioCommonCfgAccessed(pVirtio, false /* fWrite */, uOffset, cb, (void const *)pv);
    773761    }
    774762    else
     
    784772                "                  pVirtio=%#p GCPhysAddr=%RGp cb=%u\n",
    785773                pVirtio, GCPhysAddr, cb));
     774        return VINF_IOM_MMIO_UNUSED_00;
    786775    }
    787776    return rc;
     
    802791    RT_NOREF(pvUser);
    803792    PVIRTIOSTATE pVirtio = *PDMINS_2_DATA(pDevIns, PVIRTIOSTATE *);
    804     int rc = VINF_SUCCESS;
    805793
    806794    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, pVirtio->pDeviceCap,     fDevSpecific);
     
    815803         * Pass this MMIO write access back to the client to handle
    816804         */
    817         rc = pVirtio->virtioCallbacks.pfnVirtioDevCapWrite(pDevIns, uOffset, pv, cb);
     805        (void)pVirtio->virtioCallbacks.pfnVirtioDevCapWrite(pDevIns, uOffset, pv, cb);
    818806    }
    819807    else
     
    821809    {
    822810        uint32_t uOffset = GCPhysAddr - pVirtio->pGcPhysCommonCfg;
    823         virtioCommonCfgAccessed(pVirtio, true /* fWrite */, uOffset, cb, pv);
     811        (void)virtioCommonCfgAccessed(pVirtio, true /* fWrite */, uOffset, cb, pv);
    824812    }
    825813    else
     
    847835                pVirtio, GCPhysAddr, pv, cb, pv, cb));
    848836    }
    849     return rc;
     837    return VINF_SUCCESS;
    850838}
    851839
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h

    r81122 r81300  
    6565typedef struct VIRTIO_DESC_CHAIN
    6666{
    67     uint32_t  uHeadIdx;                                    /**< Head idx of associated desc chain        */
    68     uint32_t  cbVirtSrc;                                   /**< Size of virt source buffer               */
    69     void     *pVirtSrc;                                    /**< Virt mem buf holding out data from guest */
    70     uint32_t  cbPhysDst;                                   /**< Total size of dst buffer                 */
    71     PRTSGBUF  pSgPhysDst;                                  /**< Phys S/G buf to store result for guest   */
     67    uint32_t  uHeadIdx;                                          /**< Head idx of associated desc chain        */
     68    uint32_t  cbPhysSend;                                        /**< Total size of src buffer                 */
     69    PRTSGBUF  pSgPhysSend;                                       /**< Phys S/G/ buf for data from guest        */
     70    uint32_t  cbPhysReturn;                                      /**< Total size of dst buffer                 */
     71    PRTSGBUF  pSgPhysReturn;                                     /**< Phys S/G buf to store result for guest   */
    7272} VIRTIO_DESC_CHAIN_T, *PVIRTIO_DESC_CHAIN_T, **PPVIRTIO_DESC_CHAIN_T;
    7373
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