> On Mar 29, 2022, at 8:50 AM, Stefan Hajnoczi <stefa...@redhat.com> wrote:
> 
> On Fri, Mar 25, 2022 at 03:19:43PM -0400, Jagannathan Raman wrote:
>> @@ -324,6 +325,170 @@ static void dma_unregister(vfu_ctx_t *vfu_ctx, 
>> vfu_dma_info_t *info)
>>     trace_vfu_dma_unregister((uint64_t)info->iova.iov_base);
>> }
>> 
>> +static size_t vfu_object_bar_rw(PCIDevice *pci_dev, int pci_bar,
>> +                                hwaddr offset, char * const buf,
>> +                                hwaddr len, const bool is_write)
>> +{
>> +    uint8_t *ptr = (uint8_t *)buf;
>> +    uint8_t *ram_ptr = NULL;
>> +    bool release_lock = false;
>> +    MemoryRegionSection section = { 0 };
>> +    MemoryRegion *mr = NULL;
>> +    int access_size;
>> +    hwaddr size = 0;
>> +    MemTxResult result;
>> +    uint64_t val;
>> +
>> +    section = memory_region_find(pci_dev->io_regions[pci_bar].memory,
>> +                                 offset, len);
>> +
>> +    if (!section.mr) {
>> +        return 0;
>> +    }
>> +
>> +    mr = section.mr;
>> +    offset = section.offset_within_region;
>> +
>> +    if (is_write && mr->readonly) {
>> +        warn_report("vfu: attempting to write to readonly region in "
>> +                    "bar %d - [0x%"PRIx64" - 0x%"PRIx64"]",
>> +                    pci_bar, offset, (offset + len));
>> +        return 0;
> 
> A mr reference is leaked. The return statement can be replaced with goto
> exit.

OK.

> 
>> +    }
>> +
>> +    if (memory_access_is_direct(mr, is_write)) {
>> +        /**
>> +         * Some devices expose a PCI expansion ROM, which could be buffer
>> +         * based as compared to other regions which are primarily based on
>> +         * MemoryRegionOps. memory_region_find() would already check
>> +         * for buffer overflow, we don't need to repeat it here.
>> +         */
>> +        ram_ptr = memory_region_get_ram_ptr(mr);
>> +
>> +        size = len;
> 
> This looks like it will access beyond the end of ram_ptr when
> section.size < len after memory_region_find() returns.

OK - will will handle shorter sections returned by memory_region_find().

> 
>> +
>> +        if (is_write) {
>> +            memcpy((ram_ptr + offset), buf, size);
>> +        } else {
>> +            memcpy(buf, (ram_ptr + offset), size);
>> +        }
>> +
>> +        goto exit;
> 
> What happens when the access spans two adjacent MemoryRegions? I think
> the while (len > 0) loop is needed even in the memory_access_is_direct()
> case so we perform the full access instead of truncating it.

OK - this should be covered by the shorter section handling above.

Thank you!
--
Jag

> 
>> +    }
>> +
>> +    while (len > 0) {


Reply via email to