diff options
author | Peter Maydell | 2020-11-10 13:23:05 +0100 |
---|---|---|
committer | Peter Maydell | 2020-11-10 13:23:05 +0100 |
commit | 879860ca706fa1ef47ba511c49a6e2b1b49be9b7 (patch) | |
tree | f6557aa49be6e488920c865482ce4c874337cc38 /tests | |
parent | Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.2-pull-re... (diff) | |
parent | s390x: Avoid variable size warning in ipl.h (diff) | |
download | qemu-879860ca706fa1ef47ba511c49a6e2b1b49be9b7.tar.gz qemu-879860ca706fa1ef47ba511c49a6e2b1b49be9b7.tar.xz qemu-879860ca706fa1ef47ba511c49a6e2b1b49be9b7.zip |
Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2020-11-10' into staging
* Some small qtest fixes
* Oss-fuzz updates
* Publish the docs built during gitlab CI to the user's gitlab.io page
* Update the OpenBSD VM test to v6.8
* Fix the device-crash-test script to run with the meson build system
* Some small s390x fixes
# gpg: Signature made Tue 10 Nov 2020 11:05:06 GMT
# gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg: issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg: aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5
* remotes/huth-gitlab/tags/pull-request-2020-11-10:
s390x: Avoid variable size warning in ipl.h
s390x: fix clang 11 warnings in cpu_models.c
qtest: Update references to parse_escape() in comments
fuzz: add virtio-blk fuzz target
docs: add "page source" link to sphinx documentation
gitlab: force enable docs build in Fedora, Ubuntu, Debian
gitlab: publish the docs built during CI
configure: surface deprecated targets in the help output
fuzz: Make fork_fuzz.ld compatible with LLVM's LLD
scripts/oss-fuzz: give all fuzzers -target names
docs/fuzz: update fuzzing documentation post-meson
docs/fuzz: rST-ify the fuzzing documentation
MAINTAINERS: Add gitlab-pipeline-status script to GitLab CI section
gitlab-ci: Drop generic cache rule
tests/qtest/tpm: Remove redundant check in the tpm_test_swtpm_test()
qtest: Fix bad printf format specifiers
device-crash-test: Check if path is actually an executable file
tests/vm: update openbsd to release 6.8
meson: always include contrib/libvhost-user
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/qtest/arm-cpu-features.c | 8 | ||||
-rw-r--r-- | tests/qtest/fuzz/fork_fuzz.ld | 12 | ||||
-rw-r--r-- | tests/qtest/fuzz/meson.build | 1 | ||||
-rw-r--r-- | tests/qtest/fuzz/virtio_blk_fuzz.c | 234 | ||||
-rw-r--r-- | tests/qtest/libqos/libqtest.h | 18 | ||||
-rw-r--r-- | tests/qtest/libqtest-single.h | 2 | ||||
-rw-r--r-- | tests/qtest/tpm-tests.c | 6 | ||||
-rwxr-xr-x | tests/vm/openbsd | 8 |
8 files changed, 266 insertions, 23 deletions
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c index d20094d5a7..bc681a95d5 100644 --- a/tests/qtest/arm-cpu-features.c +++ b/tests/qtest/arm-cpu-features.c @@ -536,7 +536,7 @@ static void test_query_cpu_model_expansion_kvm(const void *data) if (kvm_supports_sve) { g_assert(vls != 0); max_vq = 64 - __builtin_clzll(vls); - sprintf(max_name, "sve%d", max_vq * 128); + sprintf(max_name, "sve%u", max_vq * 128); /* Enabling a supported length is of course fine. */ assert_sve_vls(qts, "host", vls, "{ %s: true }", max_name); @@ -556,7 +556,7 @@ static void test_query_cpu_model_expansion_kvm(const void *data) * unless all larger, supported vector lengths are also * disabled. */ - sprintf(name, "sve%d", vq * 128); + sprintf(name, "sve%u", vq * 128); error = g_strdup_printf("cannot disable %s", name); assert_error(qts, "host", error, "{ %s: true, %s: false }", @@ -569,7 +569,7 @@ static void test_query_cpu_model_expansion_kvm(const void *data) * we need at least one vector length enabled. */ vq = __builtin_ffsll(vls); - sprintf(name, "sve%d", vq * 128); + sprintf(name, "sve%u", vq * 128); error = g_strdup_printf("cannot disable %s", name); assert_error(qts, "host", error, "{ %s: false }", name); g_free(error); @@ -581,7 +581,7 @@ static void test_query_cpu_model_expansion_kvm(const void *data) } } if (vq <= SVE_MAX_VQ) { - sprintf(name, "sve%d", vq * 128); + sprintf(name, "sve%u", vq * 128); error = g_strdup_printf("cannot enable %s", name); assert_error(qts, "host", error, "{ %s: true }", name); g_free(error); diff --git a/tests/qtest/fuzz/fork_fuzz.ld b/tests/qtest/fuzz/fork_fuzz.ld index bfb667ed06..cfb88b7fdb 100644 --- a/tests/qtest/fuzz/fork_fuzz.ld +++ b/tests/qtest/fuzz/fork_fuzz.ld @@ -16,6 +16,11 @@ SECTIONS /* Lowest stack counter */ *(__sancov_lowest_stack); } +} +INSERT AFTER .data; + +SECTIONS +{ .data.fuzz_ordered : { /* @@ -34,6 +39,11 @@ SECTIONS */ *(.bss._ZN6fuzzer3TPCE); } +} +INSERT AFTER .data.fuzz_start; + +SECTIONS +{ .data.fuzz_end : ALIGN(4K) { __FUZZ_COUNTERS_END = .; @@ -43,4 +53,4 @@ SECTIONS * Don't overwrite the SECTIONS in the default linker script. Instead insert the * above into the default script */ -INSERT AFTER .data; +INSERT AFTER .data.fuzz_ordered; diff --git a/tests/qtest/fuzz/meson.build b/tests/qtest/fuzz/meson.build index 5162321f30..8af6848cd5 100644 --- a/tests/qtest/fuzz/meson.build +++ b/tests/qtest/fuzz/meson.build @@ -5,6 +5,7 @@ specific_fuzz_ss.add(files('fuzz.c', 'fork_fuzz.c', 'qos_fuzz.c', specific_fuzz_ss.add(when: 'CONFIG_I440FX', if_true: files('i440fx_fuzz.c')) specific_fuzz_ss.add(when: 'CONFIG_VIRTIO_NET', if_true: files('virtio_net_fuzz.c')) specific_fuzz_ss.add(when: 'CONFIG_VIRTIO_SCSI', if_true: files('virtio_scsi_fuzz.c')) +specific_fuzz_ss.add(when: 'CONFIG_VIRTIO_BLK', if_true: files('virtio_blk_fuzz.c')) specific_fuzz_ss.add(files('generic_fuzz.c')) fork_fuzz = declare_dependency( diff --git a/tests/qtest/fuzz/virtio_blk_fuzz.c b/tests/qtest/fuzz/virtio_blk_fuzz.c new file mode 100644 index 0000000000..623a756fd4 --- /dev/null +++ b/tests/qtest/fuzz/virtio_blk_fuzz.c @@ -0,0 +1,234 @@ +/* + * virtio-blk Fuzzing Target + * + * Copyright Red Hat Inc., 2020 + * + * Based on virtio-scsi-fuzz target. + * + * 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 "tests/qtest/libqos/libqtest.h" +#include "tests/qtest/libqos/virtio-blk.h" +#include "tests/qtest/libqos/virtio.h" +#include "tests/qtest/libqos/virtio-pci.h" +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_pci.h" +#include "standard-headers/linux/virtio_blk.h" +#include "fuzz.h" +#include "fork_fuzz.h" +#include "qos_fuzz.h" + +#define TEST_IMAGE_SIZE (64 * 1024 * 1024) +#define PCI_SLOT 0x02 +#define PCI_FN 0x00 + +#define MAX_NUM_QUEUES 64 + +/* Based on tests/qtest/virtio-blk-test.c. */ +typedef struct { + int num_queues; + QVirtQueue *vq[MAX_NUM_QUEUES + 2]; +} QVirtioBlkQueues; + +static QVirtioBlkQueues *qvirtio_blk_init(QVirtioDevice *dev, uint64_t mask) +{ + QVirtioBlkQueues *vs; + uint64_t features; + + vs = g_new0(QVirtioBlkQueues, 1); + + features = qvirtio_get_features(dev); + if (!mask) { + mask = ~((1u << VIRTIO_RING_F_INDIRECT_DESC) | + (1u << VIRTIO_RING_F_EVENT_IDX) | + (1u << VIRTIO_BLK_F_SCSI)); + } + mask |= ~QVIRTIO_F_BAD_FEATURE; + features &= mask; + qvirtio_set_features(dev, features); + + vs->num_queues = 1; + vs->vq[0] = qvirtqueue_setup(dev, fuzz_qos_alloc, 0); + + qvirtio_set_driver_ok(dev); + + return vs; +} + +static void virtio_blk_fuzz(QTestState *s, QVirtioBlkQueues* queues, + const unsigned char *Data, size_t Size) +{ + /* + * Data is a sequence of random bytes. We split them up into "actions", + * followed by data: + * [vqa][dddddddd][vqa][dddd][vqa][dddddddddddd] ... + * The length of the data is specified by the preceding vqa.length + */ + typedef struct vq_action { + uint8_t queue; + uint8_t length; + uint8_t write; + uint8_t next; + uint8_t kick; + } vq_action; + + /* Keep track of the free head for each queue we interact with */ + bool vq_touched[MAX_NUM_QUEUES + 2] = {0}; + uint32_t free_head[MAX_NUM_QUEUES + 2]; + + QGuestAllocator *t_alloc = fuzz_qos_alloc; + + QVirtioBlk *blk = fuzz_qos_obj; + QVirtioDevice *dev = blk->vdev; + QVirtQueue *q; + vq_action vqa; + while (Size >= sizeof(vqa)) { + /* Copy the action, so we can normalize length, queue and flags */ + memcpy(&vqa, Data, sizeof(vqa)); + + Data += sizeof(vqa); + Size -= sizeof(vqa); + + vqa.queue = vqa.queue % queues->num_queues; + /* Cap length at the number of remaining bytes in data */ + vqa.length = vqa.length >= Size ? Size : vqa.length; + vqa.write = vqa.write & 1; + vqa.next = vqa.next & 1; + vqa.kick = vqa.kick & 1; + + q = queues->vq[vqa.queue]; + + /* Copy the data into ram, and place it on the virtqueue */ + uint64_t req_addr = guest_alloc(t_alloc, vqa.length); + qtest_memwrite(s, req_addr, Data, vqa.length); + if (vq_touched[vqa.queue] == 0) { + vq_touched[vqa.queue] = 1; + free_head[vqa.queue] = qvirtqueue_add(s, q, req_addr, vqa.length, + vqa.write, vqa.next); + } else { + qvirtqueue_add(s, q, req_addr, vqa.length, vqa.write , vqa.next); + } + + if (vqa.kick) { + qvirtqueue_kick(s, dev, q, free_head[vqa.queue]); + free_head[vqa.queue] = 0; + } + Data += vqa.length; + Size -= vqa.length; + } + /* In the end, kick each queue we interacted with */ + for (int i = 0; i < MAX_NUM_QUEUES + 2; i++) { + if (vq_touched[i]) { + qvirtqueue_kick(s, dev, queues->vq[i], free_head[i]); + } + } +} + +static void virtio_blk_fork_fuzz(QTestState *s, + const unsigned char *Data, size_t Size) +{ + QVirtioBlk *blk = fuzz_qos_obj; + static QVirtioBlkQueues *queues; + if (!queues) { + queues = qvirtio_blk_init(blk->vdev, 0); + } + if (fork() == 0) { + virtio_blk_fuzz(s, queues, Data, Size); + flush_events(s); + _Exit(0); + } else { + flush_events(s); + wait(NULL); + } +} + +static void virtio_blk_with_flag_fuzz(QTestState *s, + const unsigned char *Data, size_t Size) +{ + QVirtioBlk *blk = fuzz_qos_obj; + static QVirtioBlkQueues *queues; + + if (fork() == 0) { + if (Size >= sizeof(uint64_t)) { + queues = qvirtio_blk_init(blk->vdev, *(uint64_t *)Data); + virtio_blk_fuzz(s, queues, + Data + sizeof(uint64_t), Size - sizeof(uint64_t)); + flush_events(s); + } + _Exit(0); + } else { + flush_events(s); + wait(NULL); + } +} + +static void virtio_blk_pre_fuzz(QTestState *s) +{ + qos_init_path(s); + counter_shm_init(); +} + +static void drive_destroy(void *path) +{ + unlink(path); + g_free(path); +} + +static char *drive_create(void) +{ + int fd, ret; + char *t_path = g_strdup("/tmp/qtest.XXXXXX"); + + /* Create a temporary raw image */ + fd = mkstemp(t_path); + g_assert_cmpint(fd, >=, 0); + ret = ftruncate(fd, TEST_IMAGE_SIZE); + g_assert_cmpint(ret, ==, 0); + close(fd); + + g_test_queue_destroy(drive_destroy, t_path); + return t_path; +} + +static void *virtio_blk_test_setup(GString *cmd_line, void *arg) +{ + char *tmp_path = drive_create(); + + g_string_append_printf(cmd_line, + " -drive if=none,id=drive0,file=%s," + "format=raw,auto-read-only=off ", + tmp_path); + + return arg; +} + +static void register_virtio_blk_fuzz_targets(void) +{ + fuzz_add_qos_target(&(FuzzTarget){ + .name = "virtio-blk-fuzz", + .description = "Fuzz the virtio-blk virtual queues, forking " + "for each fuzz run", + .pre_vm_init = &counter_shm_init, + .pre_fuzz = &virtio_blk_pre_fuzz, + .fuzz = virtio_blk_fork_fuzz,}, + "virtio-blk", + &(QOSGraphTestOptions){.before = virtio_blk_test_setup} + ); + + fuzz_add_qos_target(&(FuzzTarget){ + .name = "virtio-blk-flags-fuzz", + .description = "Fuzz the virtio-blk virtual queues, forking " + "for each fuzz run (also fuzzes the virtio flags)", + .pre_vm_init = &counter_shm_init, + .pre_fuzz = &virtio_blk_pre_fuzz, + .fuzz = virtio_blk_with_flag_fuzz,}, + "virtio-blk", + &(QOSGraphTestOptions){.before = virtio_blk_test_setup} + ); +} + +fuzz_target_init(register_virtio_blk_fuzz_targets); diff --git a/tests/qtest/libqos/libqtest.h b/tests/qtest/libqos/libqtest.h index 5c959f1853..724f65aa94 100644 --- a/tests/qtest/libqos/libqtest.h +++ b/tests/qtest/libqos/libqtest.h @@ -88,7 +88,7 @@ void qtest_quit(QTestState *s); * @fds: array of file descriptors * @fds_num: number of elements in @fds * @fmt: QMP message to send to qemu, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * * Sends a QMP message to QEMU with fds and returns the response. @@ -101,7 +101,7 @@ QDict *qtest_qmp_fds(QTestState *s, int *fds, size_t fds_num, * qtest_qmp: * @s: #QTestState instance to operate on. * @fmt: QMP message to send to qemu, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * * Sends a QMP message to QEMU and returns the response. @@ -113,7 +113,7 @@ QDict *qtest_qmp(QTestState *s, const char *fmt, ...) * qtest_qmp_send: * @s: #QTestState instance to operate on. * @fmt: QMP message to send to qemu, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * * Sends a QMP message to QEMU and leaves the response in the stream. @@ -138,7 +138,7 @@ void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...) * @fds: array of file descriptors * @fds_num: number of elements in @fds * @fmt: QMP message to send to QEMU, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * @ap: QMP message arguments * @@ -152,7 +152,7 @@ QDict *qtest_vqmp_fds(QTestState *s, int *fds, size_t fds_num, * qtest_vqmp: * @s: #QTestState instance to operate on. * @fmt: QMP message to send to QEMU, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * @ap: QMP message arguments * @@ -167,7 +167,7 @@ QDict *qtest_vqmp(QTestState *s, const char *fmt, va_list ap) * @fds: array of file descriptors * @fds_num: number of elements in @fds * @fmt: QMP message to send to QEMU, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * @ap: QMP message arguments * @@ -181,7 +181,7 @@ void qtest_qmp_vsend_fds(QTestState *s, int *fds, size_t fds_num, * qtest_qmp_vsend: * @s: #QTestState instance to operate on. * @fmt: QMP message to send to QEMU, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * @ap: QMP message arguments * @@ -636,7 +636,7 @@ void qtest_add_abrt_handler(GHookFunc fn, const void *data); * qtest_qmp_assert_success: * @qts: QTestState instance to operate on * @fmt: QMP message to send to qemu, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * * Sends a QMP message to QEMU and asserts that a 'return' key is present in @@ -683,7 +683,7 @@ void qtest_qmp_device_add_qdict(QTestState *qts, const char *drv, * @driver: Name of the device that should be added * @id: Identification string * @fmt: QMP message to send to qemu, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * * Generic hot-plugging test via the device_add QMP command. diff --git a/tests/qtest/libqtest-single.h b/tests/qtest/libqtest-single.h index 176979a2ce..0d7f568678 100644 --- a/tests/qtest/libqtest-single.h +++ b/tests/qtest/libqtest-single.h @@ -47,7 +47,7 @@ static inline void qtest_end(void) /** * qmp: * @fmt...: QMP message to send to qemu, formatted like - * qobject_from_jsonf_nofail(). See parse_escape() for what's + * qobject_from_jsonf_nofail(). See parse_interpolation() for what's * supported after '%'. * * Sends a QMP message to QEMU and returns the response. diff --git a/tests/qtest/tpm-tests.c b/tests/qtest/tpm-tests.c index 70c80f8379..0da3a8a4df 100644 --- a/tests/qtest/tpm-tests.c +++ b/tests/qtest/tpm-tests.c @@ -70,10 +70,8 @@ void tpm_test_swtpm_test(const char *src_tpm_path, tx_func *tx, qtest_end(); tpm_util_swtpm_kill(swtpm_pid); - if (addr) { - g_unlink(addr->u.q_unix.path); - qapi_free_SocketAddress(addr); - } + g_unlink(addr->u.q_unix.path); + qapi_free_SocketAddress(addr); } void tpm_test_swtpm_migration_test(const char *src_tpm_path, diff --git a/tests/vm/openbsd b/tests/vm/openbsd index ad882a76a2..386b2c72f7 100755 --- a/tests/vm/openbsd +++ b/tests/vm/openbsd @@ -22,8 +22,8 @@ class OpenBSDVM(basevm.BaseVM): name = "openbsd" arch = "x86_64" - link = "https://cdn.openbsd.org/pub/OpenBSD/6.6/amd64/install66.iso" - csum = "b22e63df56e6266de6bbeed8e9be0fbe9ee2291551c5bc03f3cc2e4ab9436ee3" + link = "https://cdn.openbsd.org/pub/OpenBSD/6.8/amd64/install68.iso" + csum = "47e291fcc2d0c1a8ae0b66329f040b33af755b6adbd21739e20bb5ad56f62b6c" size = "20G" pkgs = [ # tools @@ -37,10 +37,10 @@ class OpenBSDVM(basevm.BaseVM): "bash", "gmake", "gsed", - "gettext", + "gettext-tools", # libs: usb - "libusb1", + "libusb1--", # libs: crypto "gnutls", |