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.
> + }
> +
> + 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.
> +
> + 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.
> + }
> +
> + while (len > 0) {
signature.asc
Description: PGP signature
