[PATCH 0/9] omap_dma: avoid non-bounds-checked memcopy

Peter Maydell posted 9 patches 1 day, 12 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260710105907.2570621-1-peter.maydell@linaro.org
Maintainers: Peter Maydell <peter.maydell@linaro.org>
MAINTAINERS                       |   2 +
hw/arm/omap1.c                    |   8 +-
hw/dma/omap_dma.c                 |  37 +++---
hw/dma/soc_dma.c                  | 196 ++++++++++--------------------
include/hw/{arm => dma}/soc_dma.h |  33 ++---
5 files changed, 97 insertions(+), 179 deletions(-)
rename include/hw/{arm => dma}/soc_dma.h (70%)
[PATCH 0/9] omap_dma: avoid non-bounds-checked memcopy
Posted by Peter Maydell 1 day, 12 hours ago
The omap_dma device is the only user of the soc_dma code.  This code
has a fastpath for when DMA transfers are from RAM to RAM.  The
current implementation of this has the caller of
soc_dma_port_add_mem() pass the underlying host address of the RAM
block that the DMA port is connected to (obtained via
memory_region_get_ram_ptr()).  Then the actual transfer function does
a simple memcpy().  This has several problems.
    
Most importantly, no bounds checking is done on the address and size
passed by the guest, so the memcpy source and destination might be
outside the backing host RAM entirely.  Secondly, because the DMA
access is done via this back door, there is no updating of the dirty
region when memory is written this way.

The better way to handle memory-to-memory DMA is to use
physical_memory_map(), because this will tell you if the address/size
you asked for would run off the edge of the RAM block, and it handles
updating dirty bits on write.

There are also various places where the omap_dma code is a bit
cavalier about possible integer overflows if the guest sets a
very high element and frame count for a transfer.

This series fixes both these problems, thus resolving
https://gitlab.com/qemu-project/qemu/-/work_items/3204
In the process it also simplifies the soc_dma code by removing
the unused "FIFO port" handling, so we don't have to check or
update that code.

thanks
-- PMM

Peter Maydell (9):
  hw/dma/soc_dma: Remove soc_dma_port_fifo support
  hw/dma/soc_dma: Simplify soc_dma_ch_update()
  hw/dma/soc_dma: Remove union from memmap_entry_s struct
  hw/dma/omap_dma: Be more careful about overflow in transfer setup
  hw/dma/soc_dma: dma bytes is uint64_t
  hw/dma/soc_dma: Use physical_memory_map() for mem2mem transfers
  hw/dma/soc_dma: Remove unused mem.base, paddr fields
  include/hw/arm/omap_dma.h: Move to include/hw/dma
  MAINTAINERS: Add soc_dma to OMAP section

 MAINTAINERS                       |   2 +
 hw/arm/omap1.c                    |   8 +-
 hw/dma/omap_dma.c                 |  37 +++---
 hw/dma/soc_dma.c                  | 196 ++++++++++--------------------
 include/hw/{arm => dma}/soc_dma.h |  33 ++---
 5 files changed, 97 insertions(+), 179 deletions(-)
 rename include/hw/{arm => dma}/soc_dma.h (70%)

-- 
2.43.0