The code mistakenly relied on address_space_translate to store the length remaining until the next memory-region. We care about this because when there is RAM or sparse-memory neighboring on an MMIO region, we should only write up to the border, to prevent inadvertently invoking MMIO handlers within the DMA callback. However address_space_translate_internal only stores the length until the end of the MemoryRegion if memory_region_is_ram(mr). Otherwise the *len is left unmodified. This caused some false-positive issues, where the fuzzer found a way to perform a nested MMIO write through a DMA callback on an [address, length] that started within sparse memory and spanned some device MMIO regions. To fix this, write to sparse memory in small chunks of memory_access_size (similar to the underlying address_space_write code), which will prevent accidentally hitting MMIO handlers through large writes. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
||
---|---|---|
.. | ||
fork_fuzz.c | ||
fork_fuzz.h | ||
fork_fuzz.ld | ||
fuzz.c | ||
fuzz.h | ||
generic_fuzz.c | ||
generic_fuzz_configs.h | ||
i440fx_fuzz.c | ||
meson.build | ||
qos_fuzz.c | ||
qos_fuzz.h | ||
qtest_wrappers.c | ||
virtio_blk_fuzz.c | ||
virtio_net_fuzz.c | ||
virtio_scsi_fuzz.c |