diff mbox series

[PATCH-for-5.2,1/3] fuzz: fix writing DMA patterns

Message ID 20201029172901.534442-2-alxndr@bu.edu
State Superseded
Headers show
Series Bug-fixes for the generic-fuzzer | expand

Commit Message

Alexander Bulekov Oct. 29, 2020, 5:28 p.m. UTC
This code had all sorts of issues. We used a loop similar to
address_space_write_rom, but I did not remove a "break" that only made
sense in the context of the switch statement in the original code. Then,
after the loop, we did a separate qtest_memwrite over the entire DMA
access range, defeating the purpose of the loop. Additionally, we
increment the buf pointer, and then try to g_free() it. Fix these
problems.

Reported-by: OSS-Fuzz (Issue 26725)
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
---
 tests/qtest/fuzz/generic_fuzz.c | 37 +++++++++++++++------------------
 1 file changed, 17 insertions(+), 20 deletions(-)

Comments

Alexander Bulekov Oct. 29, 2020, 6:11 p.m. UTC | #1
On 201029 1328, Alexander Bulekov wrote:
> This code had all sorts of issues. We used a loop similar to

> address_space_write_rom, but I did not remove a "break" that only made

> sense in the context of the switch statement in the original code. Then,

> after the loop, we did a separate qtest_memwrite over the entire DMA

> access range, defeating the purpose of the loop. Additionally, we

> increment the buf pointer, and then try to g_free() it. Fix these

> problems.

> 

> Reported-by: OSS-Fuzz (Issue 26725)


Also:
Reported-by: OSS-Fuzz (Issue 26691)

> Signed-off-by: Alexander Bulekov <alxndr@bu.edu>

> ---

>  tests/qtest/fuzz/generic_fuzz.c | 37 +++++++++++++++------------------

>  1 file changed, 17 insertions(+), 20 deletions(-)

> 

> diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c

> index a8f5864883..3e2d50feaa 100644

> --- a/tests/qtest/fuzz/generic_fuzz.c

> +++ b/tests/qtest/fuzz/generic_fuzz.c

> @@ -229,10 +229,10 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)

>      address_range ar = {addr, len};

>      g_array_append_val(dma_regions, ar);

>      pattern p = g_array_index(dma_patterns, pattern, dma_pattern_index);

> -    void *buf = pattern_alloc(p, ar.size);

> +    void *buf_base = pattern_alloc(p, ar.size);

> +    void *buf = buf_base;

>      hwaddr l, addr1;

>      MemoryRegion *mr1;

> -    uint8_t *ram_ptr;

>      while (len > 0) {

>          l = len;

>          mr1 = address_space_translate(first_cpu->as,

> @@ -244,30 +244,27 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)

>              l = memory_access_size(mr1, l, addr1);

>          } else {

>              /* ROM/RAM case */

> -            ram_ptr = qemu_map_ram_ptr(mr1->ram_block, addr1);

> -            memcpy(ram_ptr, buf, l);

> -            break;

> +            if (qtest_log_enabled) {

> +                /*

> +                * With QTEST_LOG, use a normal, slow QTest memwrite. Prefix the log

> +                * that will be written by qtest.c with a DMA tag, so we can reorder

> +                * the resulting QTest trace so the DMA fills precede the last PIO/MMIO

> +                * command.

> +                */

> +                fprintf(stderr, "[DMA] ");

> +                if (double_fetch) {

> +                    fprintf(stderr, "[DOUBLE-FETCH] ");

> +                }

> +                fflush(stderr);

> +            }

> +            qtest_memwrite(qts_global, addr, buf, l);

>          }

>          len -= l;

>          buf += l;

>          addr += l;

>  

>      }

> -    if (qtest_log_enabled) {

> -        /*

> -         * With QTEST_LOG, use a normal, slow QTest memwrite. Prefix the log

> -         * that will be written by qtest.c with a DMA tag, so we can reorder

> -         * the resulting QTest trace so the DMA fills precede the last PIO/MMIO

> -         * command.

> -         */

> -        fprintf(stderr, "[DMA] ");

> -        if (double_fetch) {

> -            fprintf(stderr, "[DOUBLE-FETCH] ");

> -        }

> -        fflush(stderr);

> -    }

> -    qtest_memwrite(qts_global, ar.addr, buf, ar.size);

> -    g_free(buf);

> +    g_free(buf_base);

>  

>      /* Increment the index of the pattern for the next DMA access */

>      dma_pattern_index = (dma_pattern_index + 1) % dma_patterns->len;

> -- 

> 2.28.0

>
diff mbox series

Patch

diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
index a8f5864883..3e2d50feaa 100644
--- a/tests/qtest/fuzz/generic_fuzz.c
+++ b/tests/qtest/fuzz/generic_fuzz.c
@@ -229,10 +229,10 @@  void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
     address_range ar = {addr, len};
     g_array_append_val(dma_regions, ar);
     pattern p = g_array_index(dma_patterns, pattern, dma_pattern_index);
-    void *buf = pattern_alloc(p, ar.size);
+    void *buf_base = pattern_alloc(p, ar.size);
+    void *buf = buf_base;
     hwaddr l, addr1;
     MemoryRegion *mr1;
-    uint8_t *ram_ptr;
     while (len > 0) {
         l = len;
         mr1 = address_space_translate(first_cpu->as,
@@ -244,30 +244,27 @@  void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write)
             l = memory_access_size(mr1, l, addr1);
         } else {
             /* ROM/RAM case */
-            ram_ptr = qemu_map_ram_ptr(mr1->ram_block, addr1);
-            memcpy(ram_ptr, buf, l);
-            break;
+            if (qtest_log_enabled) {
+                /*
+                * With QTEST_LOG, use a normal, slow QTest memwrite. Prefix the log
+                * that will be written by qtest.c with a DMA tag, so we can reorder
+                * the resulting QTest trace so the DMA fills precede the last PIO/MMIO
+                * command.
+                */
+                fprintf(stderr, "[DMA] ");
+                if (double_fetch) {
+                    fprintf(stderr, "[DOUBLE-FETCH] ");
+                }
+                fflush(stderr);
+            }
+            qtest_memwrite(qts_global, addr, buf, l);
         }
         len -= l;
         buf += l;
         addr += l;
 
     }
-    if (qtest_log_enabled) {
-        /*
-         * With QTEST_LOG, use a normal, slow QTest memwrite. Prefix the log
-         * that will be written by qtest.c with a DMA tag, so we can reorder
-         * the resulting QTest trace so the DMA fills precede the last PIO/MMIO
-         * command.
-         */
-        fprintf(stderr, "[DMA] ");
-        if (double_fetch) {
-            fprintf(stderr, "[DOUBLE-FETCH] ");
-        }
-        fflush(stderr);
-    }
-    qtest_memwrite(qts_global, ar.addr, buf, ar.size);
-    g_free(buf);
+    g_free(buf_base);
 
     /* Increment the index of the pattern for the next DMA access */
     dma_pattern_index = (dma_pattern_index + 1) % dma_patterns->len;