summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorPeter Maydell2021-03-17 23:18:54 +0100
committerPeter Maydell2021-03-17 23:18:54 +0100
commit56b89f455894e4628ad7994fe5dd348145d1a9c5 (patch)
tree63092421a2db4aa8d6405072a74cef28f76192b4 /tests
parentMerge remote-tracking branch 'remotes/mcayland/tags/qemu-openbios-20210316' i... (diff)
parentqemu-timer: allow freeing a NULL timer (diff)
downloadqemu-56b89f455894e4628ad7994fe5dd348145d1a9c5.tar.gz
qemu-56b89f455894e4628ad7994fe5dd348145d1a9c5.tar.xz
qemu-56b89f455894e4628ad7994fe5dd348145d1a9c5.zip
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
* add --enable/--disable-libgio to configure (Denis) * small fixes (Pavel, myself) * fuzzing update (Alexander) # gpg: Signature made Tue 16 Mar 2021 18:30:38 GMT # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini-gitlab/tags/for-upstream: qemu-timer: allow freeing a NULL timer hw/i8254: fix vmstate load scsi: fix sense code for EREMOTEIO Revert "accel: kvm: Add aligment assert for kvm_log_clear_one_slot" configure: add option to explicitly enable/disable libgio fuzz: move some DMA hooks fuzz: configure a sparse-mem device, by default memory: add a sparse memory device for fuzzing fuzz: add a am53c974 generic-fuzzer config fuzz: add instructions for building reproducers fuzz: add a script to build reproducers fuzz: don't leave orphan llvm-symbolizers around fuzz: fix the pro100 generic-fuzzer config MAINTAINERS: Cover fuzzer reproducer tests within 'Device Fuzzing' tests/qtest: Only run fuzz-virtio-scsi when virtio-scsi is available tests/qtest: Only run fuzz-megasas-test if megasas device is available Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/qtest/fuzz-megasas-test.c49
-rw-r--r--tests/qtest/fuzz-test.c76
-rw-r--r--tests/qtest/fuzz-virtio-scsi-test.c75
-rw-r--r--tests/qtest/fuzz/generic_fuzz.c29
-rw-r--r--tests/qtest/fuzz/generic_fuzz_configs.h8
-rw-r--r--tests/qtest/meson.build5
6 files changed, 161 insertions, 81 deletions
diff --git a/tests/qtest/fuzz-megasas-test.c b/tests/qtest/fuzz-megasas-test.c
new file mode 100644
index 0000000000..940a76bf25
--- /dev/null
+++ b/tests/qtest/fuzz-megasas-test.c
@@ -0,0 +1,49 @@
+/*
+ * QTest fuzzer-generated testcase for megasas device
+ *
+ * Copyright (c) 2020 Li Qiang <liq3ea@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqos/libqtest.h"
+
+/*
+ * This used to trigger the assert in scsi_dma_complete
+ * https://bugs.launchpad.net/qemu/+bug/1878263
+ */
+static void test_lp1878263_megasas_zero_iov_cnt(void)
+{
+ QTestState *s;
+
+ s = qtest_init("-nographic -monitor none -serial none "
+ "-M q35 -device megasas -device scsi-cd,drive=null0 "
+ "-blockdev driver=null-co,read-zeroes=on,node-name=null0");
+ qtest_outl(s, 0xcf8, 0x80001818);
+ qtest_outl(s, 0xcfc, 0xc101);
+ qtest_outl(s, 0xcf8, 0x8000181c);
+ qtest_outl(s, 0xcf8, 0x80001804);
+ qtest_outw(s, 0xcfc, 0x7);
+ qtest_outl(s, 0xcf8, 0x8000186a);
+ qtest_writeb(s, 0x14, 0xfe);
+ qtest_writeb(s, 0x0, 0x02);
+ qtest_outb(s, 0xc1c0, 0x17);
+ qtest_quit(s);
+}
+
+int main(int argc, char **argv)
+{
+ const char *arch = qtest_get_arch();
+
+ g_test_init(&argc, &argv, NULL);
+
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt",
+ test_lp1878263_megasas_zero_iov_cnt);
+ }
+
+ return g_test_run();
+}
diff --git a/tests/qtest/fuzz-test.c b/tests/qtest/fuzz-test.c
index 6f161c93be..00149abec7 100644
--- a/tests/qtest/fuzz-test.c
+++ b/tests/qtest/fuzz-test.c
@@ -11,29 +11,6 @@
#include "libqos/libqtest.h"
-/*
- * This used to trigger the assert in scsi_dma_complete
- * https://bugs.launchpad.net/qemu/+bug/1878263
- */
-static void test_lp1878263_megasas_zero_iov_cnt(void)
-{
- QTestState *s;
-
- s = qtest_init("-nographic -monitor none -serial none "
- "-M q35 -device megasas -device scsi-cd,drive=null0 "
- "-blockdev driver=null-co,read-zeroes=on,node-name=null0");
- qtest_outl(s, 0xcf8, 0x80001818);
- qtest_outl(s, 0xcfc, 0xc101);
- qtest_outl(s, 0xcf8, 0x8000181c);
- qtest_outl(s, 0xcf8, 0x80001804);
- qtest_outw(s, 0xcfc, 0x7);
- qtest_outl(s, 0xcf8, 0x8000186a);
- qtest_writeb(s, 0x14, 0xfe);
- qtest_writeb(s, 0x0, 0x02);
- qtest_outb(s, 0xc1c0, 0x17);
- qtest_quit(s);
-}
-
static void test_lp1878642_pci_bus_get_irq_level_assert(void)
{
QTestState *s;
@@ -47,55 +24,6 @@ static void test_lp1878642_pci_bus_get_irq_level_assert(void)
qtest_quit(s);
}
-/*
- * Here a MemoryRegionCache pointed to an MMIO region but had a
- * larger size than the underlying region.
- */
-static void test_mmio_oob_from_memory_region_cache(void)
-{
- QTestState *s;
-
- s = qtest_init("-M pc-q35-5.2 -display none -m 512M "
- "-device virtio-scsi,num_queues=8,addr=03.0 ");
-
- qtest_outl(s, 0xcf8, 0x80001811);
- qtest_outb(s, 0xcfc, 0x6e);
- qtest_outl(s, 0xcf8, 0x80001824);
- qtest_outl(s, 0xcf8, 0x80001813);
- qtest_outl(s, 0xcfc, 0xa080000);
- qtest_outl(s, 0xcf8, 0x80001802);
- qtest_outl(s, 0xcfc, 0x5a175a63);
- qtest_outb(s, 0x6e08, 0x9e);
- qtest_writeb(s, 0x9f003, 0xff);
- qtest_writeb(s, 0x9f004, 0x01);
- qtest_writeb(s, 0x9e012, 0x0e);
- qtest_writeb(s, 0x9e01b, 0x0e);
- qtest_writeb(s, 0x9f006, 0x01);
- qtest_writeb(s, 0x9f008, 0x01);
- qtest_writeb(s, 0x9f00a, 0x01);
- qtest_writeb(s, 0x9f00c, 0x01);
- qtest_writeb(s, 0x9f00e, 0x01);
- qtest_writeb(s, 0x9f010, 0x01);
- qtest_writeb(s, 0x9f012, 0x01);
- qtest_writeb(s, 0x9f014, 0x01);
- qtest_writeb(s, 0x9f016, 0x01);
- qtest_writeb(s, 0x9f018, 0x01);
- qtest_writeb(s, 0x9f01a, 0x01);
- qtest_writeb(s, 0x9f01c, 0x01);
- qtest_writeb(s, 0x9f01e, 0x01);
- qtest_writeb(s, 0x9f020, 0x01);
- qtest_writeb(s, 0x9f022, 0x01);
- qtest_writeb(s, 0x9f024, 0x01);
- qtest_writeb(s, 0x9f026, 0x01);
- qtest_writeb(s, 0x9f028, 0x01);
- qtest_writeb(s, 0x9f02a, 0x01);
- qtest_writeb(s, 0x9f02c, 0x01);
- qtest_writeb(s, 0x9f02e, 0x01);
- qtest_writeb(s, 0x9f030, 0x01);
- qtest_outb(s, 0x6e10, 0x00);
- qtest_quit(s);
-}
-
int main(int argc, char **argv)
{
const char *arch = qtest_get_arch();
@@ -103,12 +31,8 @@ int main(int argc, char **argv)
g_test_init(&argc, &argv, NULL);
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt",
- test_lp1878263_megasas_zero_iov_cnt);
qtest_add_func("fuzz/test_lp1878642_pci_bus_get_irq_level_assert",
test_lp1878642_pci_bus_get_irq_level_assert);
- qtest_add_func("fuzz/test_mmio_oob_from_memory_region_cache",
- test_mmio_oob_from_memory_region_cache);
}
return g_test_run();
diff --git a/tests/qtest/fuzz-virtio-scsi-test.c b/tests/qtest/fuzz-virtio-scsi-test.c
new file mode 100644
index 0000000000..aaf6d10e18
--- /dev/null
+++ b/tests/qtest/fuzz-virtio-scsi-test.c
@@ -0,0 +1,75 @@
+/*
+ * QTest fuzzer-generated testcase for virtio-scsi device
+ *
+ * Copyright (c) 2020 Li Qiang <liq3ea@gmail.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqos/libqtest.h"
+
+/*
+ * Here a MemoryRegionCache pointed to an MMIO region but had a
+ * larger size than the underlying region.
+ */
+static void test_mmio_oob_from_memory_region_cache(void)
+{
+ QTestState *s;
+
+ s = qtest_init("-M pc-q35-5.2 -display none -m 512M "
+ "-device virtio-scsi,num_queues=8,addr=03.0 ");
+
+ qtest_outl(s, 0xcf8, 0x80001811);
+ qtest_outb(s, 0xcfc, 0x6e);
+ qtest_outl(s, 0xcf8, 0x80001824);
+ qtest_outl(s, 0xcf8, 0x80001813);
+ qtest_outl(s, 0xcfc, 0xa080000);
+ qtest_outl(s, 0xcf8, 0x80001802);
+ qtest_outl(s, 0xcfc, 0x5a175a63);
+ qtest_outb(s, 0x6e08, 0x9e);
+ qtest_writeb(s, 0x9f003, 0xff);
+ qtest_writeb(s, 0x9f004, 0x01);
+ qtest_writeb(s, 0x9e012, 0x0e);
+ qtest_writeb(s, 0x9e01b, 0x0e);
+ qtest_writeb(s, 0x9f006, 0x01);
+ qtest_writeb(s, 0x9f008, 0x01);
+ qtest_writeb(s, 0x9f00a, 0x01);
+ qtest_writeb(s, 0x9f00c, 0x01);
+ qtest_writeb(s, 0x9f00e, 0x01);
+ qtest_writeb(s, 0x9f010, 0x01);
+ qtest_writeb(s, 0x9f012, 0x01);
+ qtest_writeb(s, 0x9f014, 0x01);
+ qtest_writeb(s, 0x9f016, 0x01);
+ qtest_writeb(s, 0x9f018, 0x01);
+ qtest_writeb(s, 0x9f01a, 0x01);
+ qtest_writeb(s, 0x9f01c, 0x01);
+ qtest_writeb(s, 0x9f01e, 0x01);
+ qtest_writeb(s, 0x9f020, 0x01);
+ qtest_writeb(s, 0x9f022, 0x01);
+ qtest_writeb(s, 0x9f024, 0x01);
+ qtest_writeb(s, 0x9f026, 0x01);
+ qtest_writeb(s, 0x9f028, 0x01);
+ qtest_writeb(s, 0x9f02a, 0x01);
+ qtest_writeb(s, 0x9f02c, 0x01);
+ qtest_writeb(s, 0x9f02e, 0x01);
+ qtest_writeb(s, 0x9f030, 0x01);
+ qtest_outb(s, 0x6e10, 0x00);
+ qtest_quit(s);
+}
+
+int main(int argc, char **argv)
+{
+ const char *arch = qtest_get_arch();
+
+ g_test_init(&argc, &argv, NULL);
+
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qtest_add_func("fuzz/test_mmio_oob_from_memory_region_cache",
+ test_mmio_oob_from_memory_region_cache);
+ }
+
+ return g_test_run();
+}
diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
index ee8c17a04c..b5fe27aae1 100644
--- a/tests/qtest/fuzz/generic_fuzz.c
+++ b/tests/qtest/fuzz/generic_fuzz.c
@@ -28,6 +28,7 @@
#include "hw/pci/pci.h"
#include "hw/boards.h"
#include "generic_fuzz_configs.h"
+#include "hw/mem/sparse-mem.h"
/*
* SEPARATOR is used to separate "operations" in the fuzz input
@@ -64,6 +65,8 @@ static useconds_t timeout = DEFAULT_TIMEOUT_US;
static bool qtest_log_enabled;
+MemoryRegion *sparse_mem_mr;
+
/*
* A pattern used to populate a DMA region or perform a memwrite. This is
* useful for e.g. populating tables of unique addresses.
@@ -191,8 +194,7 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr)
*/
if (dma_patterns->len == 0
|| len == 0
- || mr != current_machine->ram
- || addr > current_machine->ram_size) {
+ || (mr != current_machine->ram && mr != sparse_mem_mr)) {
return;
}
@@ -238,7 +240,7 @@ void fuzz_dma_read_cb(size_t addr, size_t len, MemoryRegion *mr)
MEMTXATTRS_UNSPECIFIED);
if (!(memory_region_is_ram(mr1) ||
- memory_region_is_romd(mr1))) {
+ memory_region_is_romd(mr1)) && mr1 != sparse_mem_mr) {
l = memory_access_size(mr1, l, addr1);
} else {
/* ROM/RAM case */
@@ -583,6 +585,21 @@ static void handle_timeout(int sig)
fprintf(stderr, "[Timeout]\n");
fflush(stderr);
}
+
+ /*
+ * If there is a crash, libfuzzer/ASAN forks a child to run an
+ * "llvm-symbolizer" process for printing out a pretty stacktrace. It
+ * communicates with this child using a pipe. If we timeout+Exit, while
+ * libfuzzer is still communicating with the llvm-symbolizer child, we will
+ * be left with an orphan llvm-symbolizer process. Sometimes, this appears
+ * to lead to a deadlock in the forkserver. Use waitpid to check if there
+ * are any waitable children. If so, exit out of the signal-handler, and
+ * let libfuzzer finish communicating with the child, and exit, on its own.
+ */
+ if (waitpid(-1, NULL, WNOHANG) == 0) {
+ return;
+ }
+
_Exit(0);
}
@@ -799,6 +816,12 @@ static void generic_pre_fuzz(QTestState *s)
}
qts_global = s;
+ /*
+ * Create a special device that we can use to back DMA buffers at very
+ * high memory addresses
+ */
+ sparse_mem_mr = sparse_mem_init(0, UINT64_MAX);
+
dma_regions = g_array_new(false, false, sizeof(address_range));
dma_patterns = g_array_new(false, false, sizeof(pattern));
diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h
index 5d599765c4..8b8c7ac553 100644
--- a/tests/qtest/fuzz/generic_fuzz_configs.h
+++ b/tests/qtest/fuzz/generic_fuzz_configs.h
@@ -177,7 +177,7 @@ const generic_fuzz_config predefined_configs[] = {
.name = "i82550",
.args = "-machine q35 -nodefaults "
"-device i82550,netdev=net0 -netdev user,id=net0",
- .objects = "eepro*"
+ .objects = "i8255*"
},{
.name = "sdhci-v3",
.args = "-nodefaults -device sdhci-pci,sd-spec-version=3 "
@@ -209,6 +209,12 @@ const generic_fuzz_config predefined_configs[] = {
"-blockdev driver=null-co,read-zeroes=on,node-name=null0",
.objects = "megasas*",
},{
+ .name = "am53c974",
+ .args = "-device am53c974,id=scsi -device scsi-hd,drive=disk0 "
+ "-drive id=disk0,if=none,file=null-co://,format=raw "
+ "-nodefaults",
+ .objects = "*esp* *scsi* *am53c974*",
+ },{
.name = "ac97",
.args = "-machine q35 -nodefaults "
"-device ac97,audiodev=snd0 -audiodev none,id=snd0 -nodefaults",
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 66ee9fbf45..6e871077c1 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -17,7 +17,10 @@ slow_qtests = {
'test-hmp' : 120,
}
-qtests_generic = [
+qtests_generic = \
+ (config_all_devices.has_key('CONFIG_MEGASAS_SCSI_PCI') ? ['fuzz-megasas-test'] : []) + \
+ (config_all_devices.has_key('CONFIG_VIRTIO_SCSI') ? ['fuzz-virtio-scsi-test'] : []) + \
+ [
'cdrom-test',
'device-introspect-test',
'machine-none-test',