@@ -35,6 +35,7 @@
#include "sysemu/kvm.h"
#include "sysemu/sysemu.h"
#include "sysemu/tcg.h"
+#include "sysemu/qtest.h"
#include "qemu/timer.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
@@ -2266,8 +2267,15 @@ static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared)
if (new_block->host) {
qemu_ram_setup_dump(new_block->host, new_block->max_length);
qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_HUGEPAGE);
- /* MADV_DONTFORK is also needed by KVM in absence of synchronous MMU */
- qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_DONTFORK);
+ /*
+ * MADV_DONTFORK is also needed by KVM in absence of synchronous MMU
+ * Configure it unless the machine is a qtest server, in which case it
+ * may be forked, for fuzzing purposes
+ */
+ if (!qtest_enabled()) {
+ qemu_madvise(new_block->host, new_block->max_length,
+ QEMU_MADV_DONTFORK);
+ }
ram_block_notify_add(new_block->host, new_block->max_length);
}
}
@@ -2,3 +2,6 @@ QEMU_PROG_FUZZ=qemu-fuzz-$(TARGET_NAME)$(EXESUF)
fuzz-obj-y = $(libqos-obj-y)
fuzz-obj-y += tests/libqtest.o
fuzz-obj-y += tests/fuzz/fuzz.o
+fuzz-obj-y += tests/fuzz/fork_fuzz.o
+
+FUZZ_LDFLAGS += -Xlinker -T$(SRC_PATH)/tests/fuzz/fork_fuzz.ld
new file mode 100644
@@ -0,0 +1,51 @@
+/*
+ * Fork-based fuzzing helpers
+ *
+ * Copyright Red Hat Inc., 2019
+ *
+ * Authors:
+ * Alexander Bulekov <alxndr@bu.edu>
+ *
+ * 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 "fork_fuzz.h"
+
+uintptr_t feature_shm;
+
+void counter_shm_init(void)
+{
+ int fd = shm_open("/qemu-fuzz-cntrs", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ perror("Error: ");
+ exit(1);
+ }
+ if (ftruncate(fd, &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START) == -1) {
+ perror("Error: ");
+ exit(1);
+ }
+ /* Copy what's in the counter region to the shm.. */
+ void *rptr = mmap(NULL ,
+ &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START,
+ PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ memcpy(rptr,
+ &__FUZZ_COUNTERS_START,
+ &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START);
+
+ munmap(rptr, &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START);
+
+ /* And map the shm over the counter region */
+ rptr = mmap(&__FUZZ_COUNTERS_START,
+ &__FUZZ_COUNTERS_END - &__FUZZ_COUNTERS_START,
+ PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
+ if (!rptr) {
+ perror("Error: ");
+ exit(1);
+ }
+ return;
+}
+
+
new file mode 100644
@@ -0,0 +1,23 @@
+/*
+ * Fork-based fuzzing helpers
+ *
+ * Copyright Red Hat Inc., 2019
+ *
+ * Authors:
+ * Alexander Bulekov <alxndr@bu.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef FORK_FUZZ_H
+#define FORK_FUZZ_H
+
+extern uint8_t __FUZZ_COUNTERS_START;
+extern uint8_t __FUZZ_COUNTERS_END;
+
+void counter_shm_init(void);
+
+#endif
+
new file mode 100644
@@ -0,0 +1,37 @@
+/* We adjust linker script modification to place all of the stuff that needs to
+ * persist across fuzzing runs into a contiguous seciton of memory. Then, it is
+ * easy to re-map the counter-related memory as shared.
+*/
+
+SECTIONS
+{
+ .data.fuzz_start : ALIGN(4K)
+ {
+ __FUZZ_COUNTERS_START = .;
+ __start___sancov_cntrs = .;
+ *(_*sancov_cntrs);
+ __stop___sancov_cntrs = .;
+
+ /* Lowest stack counter */
+ *(__sancov_lowest_stack);
+
+ /* Coverage counters. They're not necessary for fuzzing, but are useful
+ * for analyzing the fuzzing performance
+ */
+ __start___llvm_prf_cnts = .;
+ *(*llvm_prf_cnts);
+ __stop___llvm_prf_cnts = .;
+ }
+ .data.fuzz_ordered :
+ {
+ /* Internal Libfuzzer TracePC object which contains the ValueProfileMap */
+ FuzzerTracePC*(.bss);
+ }
+ .data.fuzz_end : ALIGN(4K)
+ {
+ __FUZZ_COUNTERS_END = .;
+ }
+}
+/* Dont overwrite the SECTIONS in the default linker script. Instead insert the
+ * above into the default script */
+INSERT AFTER .data;