From fc1c8344e65807843ae8eaa25284e5277bdcd1eb Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Wed, 20 Jan 2021 01:02:55 -0500 Subject: 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 Reviewed-by: Darren Kenny Message-Id: <20210120060255.558535-1-alxndr@bu.edu> --- tests/qtest/fuzz/generic_fuzz.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'tests') 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 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) * 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 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write) * - 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 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr, bool is_write) 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; } -- cgit v1.1 From d54d9b1d124bcea44293e25f3a45c593d798d2a8 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Wed, 20 Jan 2021 10:22:11 -0500 Subject: fuzz: refine the ide/ahci fuzzer configs Disks work differently depending on the x86 machine type (SATA vs PATA). Additionally, we should fuzz the atapi code paths, which might contain vulnerabilities such as CVE-2020-29443. This patch adds hard-disk and cdrom generic-fuzzer configs for both the pc (PATA) and q35 (SATA) machine types. Signed-off-by: Alexander Bulekov Acked-by: Thomas Huth Reviewed-by: Darren Kenny Message-Id: <20210120152211.109782-1-alxndr@bu.edu> --- tests/qtest/fuzz/generic_fuzz_configs.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h index 7fed035..aa4c03f 100644 --- a/tests/qtest/fuzz/generic_fuzz_configs.h +++ b/tests/qtest/fuzz/generic_fuzz_configs.h @@ -85,10 +85,28 @@ const generic_fuzz_config predefined_configs[] = { .objects = "intel-hda", },{ .name = "ide-hd", + .args = "-machine pc -nodefaults " + "-drive file=null-co://,if=none,format=raw,id=disk0 " + "-device ide-hd,drive=disk0", + .objects = "*ide*", + },{ + .name = "ide-atapi", + .args = "-machine pc -nodefaults " + "-drive file=null-co://,if=none,format=raw,id=disk0 " + "-device ide-cd,drive=disk0", + .objects = "*ide*", + },{ + .name = "ahci-hd", .args = "-machine q35 -nodefaults " "-drive file=null-co://,if=none,format=raw,id=disk0 " "-device ide-hd,drive=disk0", - .objects = "ahci*", + .objects = "*ahci*", + },{ + .name = "ahci-atapi", + .args = "-machine q35 -nodefaults " + "-drive file=null-co://,if=none,format=raw,id=disk0 " + "-device ide-cd,drive=disk0", + .objects = "*ahci*", },{ .name = "floppy", .args = "-machine pc -nodefaults -device floppy,id=floppy0 " -- cgit v1.1 From 61f90e0461984438ddd5064d1c03133f561dc848 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Sun, 17 Jan 2021 15:10:14 -0500 Subject: fuzz: log the arguments used to initialize QEMU This is useful for building reproducers. Instead checking the code or the QEMU_FUZZ_ARGS, the arguments are at the top of the crash log. Signed-off-by: Alexander Bulekov Reviewed-by: Thomas Huth Message-Id: <20210117201014.271610-3-alxndr@bu.edu> --- tests/qtest/fuzz/fuzz.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c index 238866a..496d11a 100644 --- a/tests/qtest/fuzz/fuzz.c +++ b/tests/qtest/fuzz/fuzz.c @@ -159,6 +159,8 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp) char *target_name; const char *bindir; char *datadir; + GString *cmd_line; + gchar *pretty_cmd_line; bool serialize = false; /* Initialize qgraph and modules */ @@ -217,7 +219,7 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp) } /* Run QEMU's softmmu main with the fuzz-target dependent arguments */ - GString *cmd_line = fuzz_target->get_init_cmdline(fuzz_target); + cmd_line = fuzz_target->get_init_cmdline(fuzz_target); g_string_append_printf(cmd_line, " %s -qtest /dev/null ", getenv("QTEST_LOG") ? "" : "-qtest-log none"); @@ -226,6 +228,13 @@ int LLVMFuzzerInitialize(int *argc, char ***argv, char ***envp) wordexp(cmd_line->str, &result, 0); g_string_free(cmd_line, true); + if (getenv("QTEST_LOG")) { + pretty_cmd_line = g_strjoinv(" ", result.we_wordv + 1); + printf("Starting %s with Arguments: %s\n", + result.we_wordv[0], pretty_cmd_line); + g_free(pretty_cmd_line); + } + qemu_init(result.we_wordc, result.we_wordv, NULL); /* re-enable the rcu atfork, which was previously disabled in qemu_init */ -- cgit v1.1 From 8630b43f115d9736cbe9782f453a300ac3ba5af5 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Sun, 17 Jan 2021 18:09:22 -0500 Subject: fuzz: enable dynamic args for generic-fuzz configs For some device configurations, it is useful to configure some resources, and adjust QEMU arguments at runtime, prior to fuzzing. This patch adds an "argfunc" to generic the generic_fuzz_config. When specified, it is responsible for configuring the resources and returning a string containing the corresponding QEMU arguments. This can be useful for targets that rely on e.g.: * a temporary qcow2 image * a temporary directory * an unused TCP port used to bind the VNC server Signed-off-by: Alexander Bulekov Reviewed-by: Thomas Huth Message-Id: <20210117230924.449676-2-alxndr@bu.edu> --- tests/qtest/fuzz/generic_fuzz.c | 10 +++++++++- tests/qtest/fuzz/generic_fuzz_configs.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c index deb74f1..ee8c17a 100644 --- a/tests/qtest/fuzz/generic_fuzz.c +++ b/tests/qtest/fuzz/generic_fuzz.c @@ -933,12 +933,20 @@ static GString *generic_fuzz_cmdline(FuzzTarget *t) static GString *generic_fuzz_predefined_config_cmdline(FuzzTarget *t) { + gchar *args; const generic_fuzz_config *config; g_assert(t->opaque); config = t->opaque; setenv("QEMU_AVOID_DOUBLE_FETCH", "1", 1); - setenv("QEMU_FUZZ_ARGS", config->args, 1); + if (config->argfunc) { + args = config->argfunc(); + setenv("QEMU_FUZZ_ARGS", args, 1); + g_free(args); + } else { + g_assert_nonnull(config->args); + setenv("QEMU_FUZZ_ARGS", config->args, 1); + } setenv("QEMU_FUZZ_OBJECTS", config->objects, 1); return generic_fuzz_cmdline(t); } diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h index aa4c03f..51e69c6 100644 --- a/tests/qtest/fuzz/generic_fuzz_configs.h +++ b/tests/qtest/fuzz/generic_fuzz_configs.h @@ -16,6 +16,7 @@ typedef struct generic_fuzz_config { const char *name, *args, *objects; + gchar* (*argfunc)(void); /* Result must be freeable by g_free() */ } generic_fuzz_config; const generic_fuzz_config predefined_configs[] = { -- cgit v1.1 From fff7111fb90e93b148b2196175fd656b2bfea4cd Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Sun, 17 Jan 2021 18:09:24 -0500 Subject: fuzz: add virtio-9p configurations for fuzzing virtio-9p devices are often used to expose a virtual-filesystem to the guest. There have been some bugs reported in this device, such as CVE-2018-19364, and CVE-2021-20181. We should fuzz this device This patch adds two virtio-9p configurations: * One with the widely used -fsdev local driver. This driver leaks some state in the form of files/directories created in the shared dir. * One with the synth driver. While it is not used in the real world, this driver won't leak leak state between fuzz inputs. Signed-off-by: Alexander Bulekov Reviewed-by: Darren Kenny Message-Id: <20210117230924.449676-4-alxndr@bu.edu> --- tests/qtest/fuzz/generic_fuzz_configs.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'tests') diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h index 51e69c6..5d59976 100644 --- a/tests/qtest/fuzz/generic_fuzz_configs.h +++ b/tests/qtest/fuzz/generic_fuzz_configs.h @@ -19,6 +19,16 @@ typedef struct generic_fuzz_config { gchar* (*argfunc)(void); /* Result must be freeable by g_free() */ } generic_fuzz_config; +static inline gchar *generic_fuzzer_virtio_9p_args(void){ + char tmpdir[] = "/tmp/qemu-fuzz.XXXXXX"; + g_assert_nonnull(mkdtemp(tmpdir)); + + return g_strdup_printf("-machine q35 -nodefaults " + "-device virtio-9p,fsdev=hshare,mount_tag=hshare " + "-fsdev local,id=hshare,path=%s,security_model=mapped-xattr," + "writeout=immediate,fmode=0600,dmode=0700", tmpdir); +} + const generic_fuzz_config predefined_configs[] = { { .name = "virtio-net-pci-slirp", @@ -61,6 +71,16 @@ const generic_fuzz_config predefined_configs[] = { .args = "-machine q35 -nodefaults -device virtio-mouse", .objects = "virtio*", },{ + .name = "virtio-9p", + .argfunc = generic_fuzzer_virtio_9p_args, + .objects = "virtio*", + },{ + .name = "virtio-9p-synth", + .args = "-machine q35 -nodefaults " + "-device virtio-9p,fsdev=hshare,mount_tag=hshare " + "-fsdev synth,id=hshare", + .objects = "virtio*", + },{ .name = "e1000", .args = "-M q35 -nodefaults " "-device e1000,netdev=net0 -netdev user,id=net0", -- cgit v1.1 From f77147cd4de8c726f89b2702f7a9d0c9711d8875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:31 +0100 Subject: tests/meson: Only build softfloat objects if TCG is selected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested-by: Paolo Bonzini Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Reviewed-by: Alex Bennée Message-Id: <20210122204441.2145197-3-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- tests/meson.build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/meson.build b/tests/meson.build index 29ebaba..6f1ff92 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -276,7 +276,9 @@ test('decodetree', sh, workdir: meson.current_source_dir() / 'decode', suite: 'decodetree') -subdir('fp') +if 'CONFIG_TCG' in config_all + subdir('fp') +endif if not get_option('tcg').disabled() if 'CONFIG_PLUGIN' in config_host -- cgit v1.1 From 1935e0e4e09bcff8059ab17d2ce36fb1fbb70628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 22 Jan 2021 21:44:39 +0100 Subject: qapi/meson: Remove QMP from user-mode emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Message-Id: <20210122204441.2145197-11-philmd@redhat.com> Signed-off-by: Paolo Bonzini --- tests/meson.build | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/meson.build b/tests/meson.build index 6f1ff92..7d7da6a 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -86,7 +86,6 @@ tests = { 'test-qobject-input-visitor': [testqapi], 'test-string-input-visitor': [testqapi], 'test-string-output-visitor': [testqapi], - 'test-qmp-event': [testqapi], 'test-opts-visitor': [testqapi], 'test-visitor-serialization': [testqapi], 'test-bitmap': [], @@ -117,6 +116,12 @@ tests = { 'test-qapi-util': [], } +if have_system or have_tools + tests += { + 'test-qmp-event': [testqapi], + } +endif + test_deps = { 'test-qht-par': qht_bench, } -- cgit v1.1