fuzz: ignore address_space_map is_write flag
We passed an is_write flag to the fuzz_dma_read_cb function to
differentiate between the mapped DMA regions that need to be populated
with fuzzed data, and those that don't. We simply passed through the
address_space_map is_write parameter. The goal was to cut down on
unnecessarily populating mapped DMA regions, when they are not read
from.
Unfortunately, nothing precludes code from reading from regions mapped
with is_write=true. For example, see:
https://lists.gnu.org/archive/html/qemu-devel/2021-01/msg04729.html
This patch removes the is_write parameter to fuzz_dma_read_cb. As a
result, we will fill all mapped DMA regions with fuzzed data, ignoring
the specified transfer direction.
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Message-Id: <20210120060255.558535-1-alxndr@bu.edu>
diff --git a/include/exec/memory.h b/include/exec/memory.h
index c6ce74f..ecba90b 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -45,13 +45,11 @@
#ifdef CONFIG_FUZZ
void fuzz_dma_read_cb(size_t addr,
size_t len,
- MemoryRegion *mr,
- bool is_write);
+ MemoryRegion *mr);
#else
static inline void fuzz_dma_read_cb(size_t addr,
size_t len,
- MemoryRegion *mr,
- bool is_write)
+ MemoryRegion *mr)
{
/* Do Nothing */
}
@@ -2506,7 +2504,7 @@
void *buf, hwaddr len)
{
assert(addr < cache->len && len <= cache->len - addr);
- fuzz_dma_read_cb(cache->xlat + addr, len, cache->mrs.mr, false);
+ fuzz_dma_read_cb(cache->xlat + addr, len, cache->mrs.mr);
if (likely(cache->ptr)) {
memcpy(buf, cache->ptr + addr, len);
return MEMTX_OK;
diff --git a/include/exec/memory_ldst_cached.h.inc b/include/exec/memory_ldst_cached.h.inc
index 01efad6..7bc8790 100644
--- a/include/exec/memory_ldst_cached.h.inc
+++ b/include/exec/memory_ldst_cached.h.inc
@@ -28,7 +28,7 @@
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len && 4 <= cache->len - addr);
- fuzz_dma_read_cb(cache->xlat + addr, 4, cache->mrs.mr, false);
+ fuzz_dma_read_cb(cache->xlat + addr, 4, cache->mrs.mr);
if (likely(cache->ptr)) {
return LD_P(l)(cache->ptr + addr);
} else {
@@ -40,7 +40,7 @@
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len && 8 <= cache->len - addr);
- fuzz_dma_read_cb(cache->xlat + addr, 8, cache->mrs.mr, false);
+ fuzz_dma_read_cb(cache->xlat + addr, 8, cache->mrs.mr);
if (likely(cache->ptr)) {
return LD_P(q)(cache->ptr + addr);
} else {
@@ -52,7 +52,7 @@
hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
{
assert(addr < cache->len && 2 <= cache->len - addr);
- fuzz_dma_read_cb(cache->xlat + addr, 2, cache->mrs.mr, false);
+ fuzz_dma_read_cb(cache->xlat + addr, 2, cache->mrs.mr);
if (likely(cache->ptr)) {
return LD_P(uw)(cache->ptr + addr);
} else {
diff --git a/memory_ldst.c.inc b/memory_ldst.c.inc
index 2fed2de..b56e961 100644
--- a/memory_ldst.c.inc
+++ b/memory_ldst.c.inc
@@ -42,7 +42,7 @@
MO_32 | devend_memop(endian), attrs);
} else {
/* RAM case */
- fuzz_dma_read_cb(addr, 4, mr, false);
+ fuzz_dma_read_cb(addr, 4, mr);
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
@@ -111,7 +111,7 @@
MO_64 | devend_memop(endian), attrs);
} else {
/* RAM case */
- fuzz_dma_read_cb(addr, 8, mr, false);
+ fuzz_dma_read_cb(addr, 8, mr);
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
@@ -177,7 +177,7 @@
r = memory_region_dispatch_read(mr, addr1, &val, MO_8, attrs);
} else {
/* RAM case */
- fuzz_dma_read_cb(addr, 1, mr, false);
+ fuzz_dma_read_cb(addr, 1, mr);
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
val = ldub_p(ptr);
r = MEMTX_OK;
@@ -215,7 +215,7 @@
MO_16 | devend_memop(endian), attrs);
} else {
/* RAM case */
- fuzz_dma_read_cb(addr, 2, mr, false);
+ fuzz_dma_read_cb(addr, 2, mr);
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
diff --git a/softmmu/memory.c b/softmmu/memory.c
index c0c814f..23e8e33 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -1440,7 +1440,7 @@
unsigned size = memop_size(op);
MemTxResult r;
- fuzz_dma_read_cb(addr, size, mr, false);
+ fuzz_dma_read_cb(addr, size, mr);
if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
*pval = unassigned_mem_read(mr, addr, size);
return MEMTX_DECODE_ERROR;
@@ -3285,8 +3285,7 @@
#ifdef CONFIG_FUZZ
void __attribute__((weak)) fuzz_dma_read_cb(size_t addr,
size_t len,
- MemoryRegion *mr,
- bool is_write)
+ MemoryRegion *mr)
{
}
#endif
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 243c309..96efaef 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -2839,7 +2839,7 @@
stn_he_p(buf, l, val);
} else {
/* RAM case */
- fuzz_dma_read_cb(addr, len, mr, false);
+ fuzz_dma_read_cb(addr, len, mr);
ram_ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
memcpy(buf, ram_ptr, l);
}
@@ -3200,7 +3200,7 @@
memory_region_ref(mr);
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
l, is_write, attrs);
- fuzz_dma_read_cb(addr, *plen, mr, is_write);
+ fuzz_dma_read_cb(addr, *plen, mr);
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
return ptr;
diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
index be76d47..deb74f1 100644
--- a/tests/qtest/fuzz/generic_fuzz.c
+++ b/tests/qtest/fuzz/generic_fuzz.c
@@ -175,7 +175,7 @@
* generic_fuzz(), avoiding potential race-conditions, which we don't have
* a good way for reproducing right now.
*/
-void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
+void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr)
{
/* Are we in the generic-fuzzer or are we using another fuzz-target? */
if (!qts_global) {
@@ -187,14 +187,11 @@
* - We have no DMA patterns defined
* - The length of the DMA read request is zero
* - The DMA read is hitting an MR other than the machine's main RAM
- * - The DMA request is not a read (what happens for a address_space_map
- * with is_write=True? Can the device use the same pointer to do reads?)
* - The DMA request hits past the bounds of our RAM
*/
if (dma_patterns->len == 0
|| len == 0
|| mr != current_machine->ram
- || is_write
|| addr > current_machine->ram_size) {
return;
}
@@ -213,12 +210,12 @@
double_fetch = true;
if (addr < region.addr
&& avoid_double_fetches) {
- fuzz_dma_read_cb(addr, region.addr - addr, mr, is_write);
+ fuzz_dma_read_cb(addr, region.addr - addr, mr);
}
if (addr + len > region.addr + region.size
&& avoid_double_fetches) {
fuzz_dma_read_cb(region.addr + region.size,
- addr + len - (region.addr + region.size), mr, is_write);
+ addr + len - (region.addr + region.size), mr);
}
return;
}