diff options
Diffstat (limited to 'qemu_mode')
31 files changed, 80 insertions, 2786 deletions
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION new file mode 100644 index 00000000..cde6b9b7 --- /dev/null +++ b/qemu_mode/QEMUAFL_VERSION @@ -0,0 +1 @@ +c688bac2ac diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index 30ac158f..5d9f5be7 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -29,13 +29,10 @@ # will be written to ../afl-qemu-trace. # - -VERSION="3.1.1" -QEMU_URL="http://download.qemu-project.org/qemu-${VERSION}.tar.xz" -QEMU_SHA384="28ff22ec4b8c957309460aa55d0b3188e971be1ea7dfebfb2ecc7903cd20cfebc2a7c97eedfcc7595f708357f1623f8b" +QEMUAFL_VERSION="$(cat ./QEMUAFL_VERSION)" echo "=================================================" -echo "AFL binary-only instrumentation QEMU build script" +echo " QemuAFL build script" echo "=================================================" echo @@ -48,7 +45,7 @@ if [ ! "`uname -s`" = "Linux" ]; then fi -if [ ! -f "patches/afl-qemu-cpu-inl.h" -o ! -f "../config.h" ]; then +if [ ! -f "../config.h" ]; then echo "[-] Error: key files not found - wrong working directory?" exit 1 @@ -111,41 +108,38 @@ fi echo "[+] All checks passed!" -ARCHIVE="`basename -- "$QEMU_URL"`" - -CKSUM=`sha384sum -- "$ARCHIVE" 2>/dev/null | cut -d' ' -f1` - -if [ ! "$CKSUM" = "$QEMU_SHA384" ]; then - - echo "[*] Downloading QEMU ${VERSION} from the web..." - rm -f "$ARCHIVE" - OK= - while [ -z "$OK" ]; do - wget -c -O "$ARCHIVE" -- "$QEMU_URL" && OK=1 - done - - CKSUM=`sha384sum -- "$ARCHIVE" 2>/dev/null | cut -d' ' -f1` - -fi - -if [ "$CKSUM" = "$QEMU_SHA384" ]; then - - echo "[+] Cryptographic signature on $ARCHIVE checks out." +echo "[*] Making sure qemuafl is checked out" +git status 1>/dev/null 2>/dev/null +if [ $? -eq 0 ]; then + echo "[*] initializing qemuafl submodule" + git submodule init || exit 1 + git submodule update 2>/dev/null # ignore errors else - - echo "[-] Error: signature mismatch on $ARCHIVE (perhaps download error?), removing archive ..." - rm -f "$ARCHIVE" - exit 1 - + echo "[*] cloning qemuafl" + test -d qemuafl || { + CNT=1 + while [ '!' -d qemuafl -a "$CNT" -lt 4 ]; do + echo "Trying to clone qemuafl (attempt $CNT/3)" + git clone https://github.com/AFLplusplus/qemuafl + CNT=`expr "$CNT" + 1` + done + } fi -echo "[*] Uncompressing archive (this will take a while)..." +test -d qemuafl || { echo "[-] Not checked out, please install git or check your internet connection." ; exit 1 ; } +echo "[+] Got qemuafl." -rm -rf "qemu-${VERSION}" || exit 1 -tar xf "$ARCHIVE" || exit 1 +cd "qemuafl" || exit 1 +echo "[*] Checking out $QEMUAFL_VERSION" +sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null +git checkout "$QEMUAFL_VERSION" || exit 1 -echo "[+] Unpacking successful." +echo "[*] Making sure imported headers matches" +cp "../../include/config.h" "./qemuafl/imported/" || exit 1 +cp "../../include/cmplog.h" "./qemuafl/imported/" || exit 1 +cp "../../include/snapshot-inl.h" "./qemuafl/imported/" || exit 1 +cp "../../include/types.h" "./qemuafl/imported/" || exit 1 if [ -n "$HOST" ]; then echo "[+] Configuring host architecture to $HOST..." @@ -169,34 +163,7 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then esac fi -cd qemu-$VERSION || exit 1 - -echo Building for CPU target $CPU_TARGET - -echo "[*] Applying patches..." - -patch -p1 <../patches/elfload.diff || exit 1 -patch -p1 <../patches/mips-fpu.diff || exit 1 -patch -p1 <../patches/bsd-elfload.diff || exit 1 -patch -p1 <../patches/cpu-exec.diff || exit 1 -patch -p1 <../patches/syscall.diff || exit 1 -patch -p1 <../patches/translate-all.diff || exit 1 -patch -p1 <../patches/tcg.diff || exit 1 -patch -p1 <../patches/i386-translate.diff || exit 1 -patch -p1 <../patches/arm-translate.diff || exit 1 -patch -p1 <../patches/arm-translate-a64.diff || exit 1 -patch -p1 <../patches/i386-ops_sse.diff || exit 1 -patch -p1 <../patches/i386-fpu_helper.diff || exit 1 -patch -p1 <../patches/softfloat.diff || exit 1 -patch -p1 <../patches/configure.diff || exit 1 -patch -p1 <../patches/tcg-runtime.diff || exit 1 -patch -p1 <../patches/tcg-runtime-head.diff || exit 1 -patch -p1 <../patches/translator.diff || exit 1 -patch -p1 <../patches/__init__.py.diff || exit 1 -patch -p1 <../patches/make_strncpy_safe.diff || exit 1 -patch -p1 <../patches/mmap_fixes.diff || exit 1 - -echo "[+] Patching done." +echo "Building for CPU target $CPU_TARGET" if [ "$STATIC" = "1" ]; then @@ -211,7 +178,7 @@ if [ "$STATIC" = "1" ]; then --disable-sdl --disable-seccomp --disable-smartcard --disable-snappy --disable-spice --disable-libssh2 \ --disable-libusb --disable-usb-redir --disable-vde --disable-vhost-net --disable-virglrenderer \ --disable-virtfs --disable-vnc --disable-vte --disable-xen --disable-xen-pci-passthrough --disable-xfsctl \ - --enable-linux-user --disable-system --disable-blobs --disable-tools --enable-capstone=internal \ + --enable-linux-user --disable-system --disable-blobs --disable-tools \ --target-list="${CPU_TARGET}-linux-user" --static --disable-pie --cross-prefix=$CROSS_PREFIX --python="$PYTHONBIN" \ || exit 1 @@ -221,7 +188,7 @@ else # improvement, much to my surprise. Not sure how universal this is.. ./configure --disable-system \ - --enable-linux-user --disable-gtk --disable-sdl --disable-vnc --enable-capstone=internal \ + --enable-linux-user --disable-gtk --disable-sdl --disable-vnc --disable-werror \ --target-list="${CPU_TARGET}-linux-user" --enable-pie $CROSS_PREFIX --python="$PYTHONBIN" || exit 1 fi @@ -236,7 +203,7 @@ echo "[+] Build process successful!" echo "[*] Copying binary..." -cp -f "${CPU_TARGET}-linux-user/qemu-${CPU_TARGET}" "../../afl-qemu-trace" || exit 1 +cp -f "build/${CPU_TARGET}-linux-user/qemu-${CPU_TARGET}" "../../afl-qemu-trace" || exit 1 cd .. ls -l ../afl-qemu-trace || exit 1 diff --git a/qemu_mode/patches/__init__.py.diff b/qemu_mode/patches/__init__.py.diff deleted file mode 100644 index 7e189b99..00000000 --- a/qemu_mode/patches/__init__.py.diff +++ /dev/null @@ -1,17 +0,0 @@ ---- a/scripts/tracetool/__init__.py 2020-03-28 13:42:21.937700726 +0100 -+++ b/scripts/tracetool/__init__.py 2020-03-28 13:41:50.991034257 +0100 -@@ -447,12 +447,12 @@ - import tracetool - - format = str(format) -- if len(format) is 0: -+ if len(format) == 0: - raise TracetoolError("format not set") - if not tracetool.format.exists(format): - raise TracetoolError("unknown format: %s" % format) - -- if len(backends) is 0: -+ if len(backends) == 0: - raise TracetoolError("no backends specified") - for backend in backends: - if not tracetool.backend.exists(backend): diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h deleted file mode 100644 index 6fac32ef..00000000 --- a/qemu_mode/patches/afl-qemu-common.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This code is a shim patched into the separately-distributed source - code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality - to implement AFL-style instrumentation and to take care of the remaining - parts of the AFL fork server logic. - - The resulting QEMU binary is essentially a standalone instrumentation - tool; for an example of how to leverage it for other purposes, you can - have a look at afl-showmap.c. - - */ - -#ifndef __AFL_QEMU_COMMON -#define __AFL_QEMU_COMMON - -#include "../../config.h" -#include "../../include/cmplog.h" - -#define PERSISTENT_DEFAULT_MAX_CNT 1000 - -#ifdef CPU_NB_REGS - #define AFL_REGS_NUM CPU_NB_REGS -#elif TARGET_ARM - #define AFL_REGS_NUM 16 -#elif TARGET_AARCH64 - #define AFL_REGS_NUM 32 -#else - #define AFL_REGS_NUM 100 -#endif - -/* NeverZero */ - -#if (defined(__x86_64__) || defined(__i386__)) && defined(AFL_QEMU_NOT_ZERO) - #define INC_AFL_AREA(loc) \ - asm volatile( \ - "addb $1, (%0, %1, 1)\n" \ - "adcb $0, (%0, %1, 1)\n" \ - : /* no out */ \ - : "r"(afl_area_ptr), "r"(loc) \ - : "memory", "eax") -#else - #define INC_AFL_AREA(loc) afl_area_ptr[loc]++ -#endif - -typedef void (*afl_persistent_hook_fn)(uint64_t *regs, uint64_t guest_base, - uint8_t *input_buf, - uint32_t input_buf_len); - -/* Declared in afl-qemu-cpu-inl.h */ - -extern unsigned char *afl_area_ptr; -extern unsigned int afl_inst_rms; -extern abi_ulong afl_entry_point, afl_start_code, afl_end_code; -extern abi_ulong afl_persistent_addr; -extern abi_ulong afl_persistent_ret_addr; -extern u8 afl_compcov_level; -extern unsigned char afl_fork_child; -extern unsigned char is_persistent; -extern target_long persistent_stack_offset; -extern unsigned char persistent_first_pass; -extern unsigned char persistent_save_gpr; -extern uint64_t persistent_saved_gpr[AFL_REGS_NUM]; -extern int persisent_retaddr_offset; - -extern u8 * shared_buf; -extern u32 *shared_buf_len; -extern u8 sharedmem_fuzzing; - -extern afl_persistent_hook_fn afl_persistent_hook_ptr; - -extern __thread abi_ulong afl_prev_loc; - -extern struct cmp_map *__afl_cmp_map; -extern __thread u32 __afl_cmp_counter; - -void afl_setup(void); -void afl_forkserver(CPUState *cpu); - -// void afl_debug_dump_saved_regs(void); - -void afl_persistent_loop(void); - -void afl_gen_tcg_plain_call(void *func); - -void afl_float_compcov_log_32(target_ulong cur_loc, float32 arg1, float32 arg2, - void *status); -void afl_float_compcov_log_64(target_ulong cur_loc, float64 arg1, float64 arg2, - void *status); -void afl_float_compcov_log_80(target_ulong cur_loc, floatx80 arg1, - floatx80 arg2); - -/* Check if an address is valid in the current mapping */ - -static inline int is_valid_addr(target_ulong addr) { - - int flags; - target_ulong page; - - page = addr & TARGET_PAGE_MASK; - - flags = page_get_flags(page); - if (!(flags & PAGE_VALID) || !(flags & PAGE_READ)) return 0; - - return 1; - -} - -#endif - diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h deleted file mode 100644 index 63b7581d..00000000 --- a/qemu_mode/patches/afl-qemu-cpu-inl.h +++ /dev/null @@ -1,640 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This code is a shim patched into the separately-distributed source - code of QEMU 3.1.1. It leverages the built-in QEMU tracing functionality - to implement AFL-style instrumentation and to take care of the remaining - parts of the AFL fork server logic. - - The resulting QEMU binary is essentially a standalone instrumentation - tool; for an example of how to leverage it for other purposes, you can - have a look at afl-showmap.c. - - */ - -#include <sys/shm.h> -#include "afl-qemu-common.h" - -#ifndef AFL_QEMU_STATIC_BUILD - #include <dlfcn.h> -#endif - -/*************************** - * VARIOUS AUXILIARY STUFF * - ***************************/ - -/* We use one additional file descriptor to relay "needs translation" - messages between the child and the fork server. */ - -#define TSL_FD (FORKSRV_FD - 1) - -/* This is equivalent to afl-as.h: */ - -static unsigned char - dummy[MAP_SIZE]; /* costs MAP_SIZE but saves a few instructions */ -unsigned char *afl_area_ptr = dummy; /* Exported for afl_gen_trace */ - -/* Exported variables populated by the code patched into elfload.c: */ - -abi_ulong afl_entry_point, /* ELF entry point (_start) */ - afl_start_code, /* .text start pointer */ - afl_end_code; /* .text end pointer */ - -abi_ulong afl_persistent_addr, afl_persistent_ret_addr; -unsigned int afl_persistent_cnt; - -u8 afl_compcov_level; - -__thread abi_ulong afl_prev_loc; - -struct cmp_map *__afl_cmp_map; -__thread u32 __afl_cmp_counter; - -/* Set in the child process in forkserver mode: */ - -static int forkserver_installed = 0; -static int disable_caching = 0; - -unsigned char afl_fork_child; -unsigned int afl_forksrv_pid; -unsigned char is_persistent; -target_long persistent_stack_offset; -unsigned char persistent_first_pass = 1; -unsigned char persistent_save_gpr; -uint64_t persistent_saved_gpr[AFL_REGS_NUM]; -int persisent_retaddr_offset; - -u8 * shared_buf; -u32 *shared_buf_len; -u8 sharedmem_fuzzing; - -afl_persistent_hook_fn afl_persistent_hook_ptr; - -/* Instrumentation ratio: */ - -unsigned int afl_inst_rms = MAP_SIZE; /* Exported for afl_gen_trace */ - -/* Function declarations. */ - -static void afl_wait_tsl(CPUState *, int); -static void afl_request_tsl(target_ulong, target_ulong, uint32_t, uint32_t, - TranslationBlock *, int); - -/* Data structures passed around by the translate handlers: */ - -struct afl_tb { - - target_ulong pc; - target_ulong cs_base; - uint32_t flags; - uint32_t cf_mask; - -}; - -struct afl_tsl { - - struct afl_tb tb; - char is_chain; - -}; - -struct afl_chain { - - struct afl_tb last_tb; - uint32_t cf_mask; - int tb_exit; - -}; - -/* Some forward decls: */ - -static inline TranslationBlock *tb_find(CPUState *, TranslationBlock *, int, - uint32_t); -static inline void tb_add_jump(TranslationBlock *tb, int n, - TranslationBlock *tb_next); -int open_self_maps(void *cpu_env, int fd); -static void afl_map_shm_fuzz(void); - -/************************* - * ACTUAL IMPLEMENTATION * - *************************/ - -/* Set up SHM region and initialize other stuff. */ - -static void afl_map_shm_fuzz(void) { - - char *id_str = getenv(SHM_FUZZ_ENV_VAR); - - if (id_str) { - - u32 shm_id = atoi(id_str); - u8 *map = (u8 *)shmat(shm_id, NULL, 0); - /* Whooooops. */ - - if (!map || map == (void *)-1) { - - perror("[AFL] ERROR: could not access fuzzing shared memory"); - exit(1); - - } - - shared_buf_len = (u32 *)map; - shared_buf = map + sizeof(u32); - - if (getenv("AFL_DEBUG")) { - - fprintf(stderr, "[AFL] DEBUG: successfully got fuzzing shared memory\n"); - - } - - } else { - - fprintf(stderr, - "[AFL] ERROR: variable for fuzzing shared memory is not set\n"); - exit(1); - - } - -} - -void afl_setup(void) { - - char *id_str = getenv(SHM_ENV_VAR), *inst_r = getenv("AFL_INST_RATIO"); - - int shm_id; - - if (inst_r) { - - unsigned int r; - - r = atoi(inst_r); - - if (r > 100) r = 100; - if (!r) r = 1; - - afl_inst_rms = MAP_SIZE * r / 100; - - } - - if (id_str) { - - shm_id = atoi(id_str); - afl_area_ptr = shmat(shm_id, NULL, 0); - - if (afl_area_ptr == (void *)-1) exit(1); - - /* With AFL_INST_RATIO set to a low value, we want to touch the bitmap - so that the parent doesn't give up on us. */ - - if (inst_r) afl_area_ptr[0] = 1; - - } - - if (getenv("___AFL_EINS_ZWEI_POLIZEI___")) { // CmpLog forkserver - - id_str = getenv(CMPLOG_SHM_ENV_VAR); - - if (id_str) { - - u32 shm_id = atoi(id_str); - - __afl_cmp_map = shmat(shm_id, NULL, 0); - - if (__afl_cmp_map == (void *)-1) exit(1); - - } - - } - - if (getenv("AFL_INST_LIBS")) { - - afl_start_code = 0; - afl_end_code = (abi_ulong)-1; - - } - - if (getenv("AFL_CODE_START")) - afl_start_code = strtoll(getenv("AFL_CODE_START"), NULL, 16); - if (getenv("AFL_CODE_END")) - afl_end_code = strtoll(getenv("AFL_CODE_END"), NULL, 16); - - /* Maintain for compatibility */ - if (getenv("AFL_QEMU_COMPCOV")) { afl_compcov_level = 1; } - if (getenv("AFL_COMPCOV_LEVEL")) { - - afl_compcov_level = atoi(getenv("AFL_COMPCOV_LEVEL")); - - } - - /* pthread_atfork() seems somewhat broken in util/rcu.c, and I'm - not entirely sure what is the cause. This disables that - behaviour, and seems to work alright? */ - - rcu_disable_atfork(); - - disable_caching = getenv("AFL_QEMU_DISABLE_CACHE") != NULL; - - is_persistent = getenv("AFL_QEMU_PERSISTENT_ADDR") != NULL; - - if (is_persistent) { - - afl_persistent_addr = strtoll(getenv("AFL_QEMU_PERSISTENT_ADDR"), NULL, 0); - if (getenv("AFL_QEMU_PERSISTENT_RET")) - afl_persistent_ret_addr = - strtoll(getenv("AFL_QEMU_PERSISTENT_RET"), NULL, 0); - /* If AFL_QEMU_PERSISTENT_RET is not specified patch the return addr */ - - } - - if (getenv("AFL_QEMU_PERSISTENT_GPR")) persistent_save_gpr = 1; - - if (getenv("AFL_QEMU_PERSISTENT_HOOK")) { - -#ifdef AFL_QEMU_STATIC_BUILD - - fprintf(stderr, - "[AFL] ERROR: you cannot use AFL_QEMU_PERSISTENT_HOOK when " - "afl-qemu-trace is static\n"); - exit(1); - -#else - - persistent_save_gpr = 1; - - void *plib = dlopen(getenv("AFL_QEMU_PERSISTENT_HOOK"), RTLD_NOW); - if (!plib) { - - fprintf(stderr, "[AFL] ERROR: invalid AFL_QEMU_PERSISTENT_HOOK=%s\n", - getenv("AFL_QEMU_PERSISTENT_HOOK")); - exit(1); - - } - - int (*afl_persistent_hook_init_ptr)(void) = - dlsym(plib, "afl_persistent_hook_init"); - if (afl_persistent_hook_init_ptr) - sharedmem_fuzzing = afl_persistent_hook_init_ptr(); - - afl_persistent_hook_ptr = dlsym(plib, "afl_persistent_hook"); - if (!afl_persistent_hook_ptr) { - - fprintf(stderr, - "[AFL] ERROR: failed to find the function " - "\"afl_persistent_hook\" in %s\n", - getenv("AFL_QEMU_PERSISTENT_HOOK")); - exit(1); - - } - -#endif - - } - - if (getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET")) - persisent_retaddr_offset = - strtoll(getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"), NULL, 0); - - if (getenv("AFL_QEMU_PERSISTENT_CNT")) - afl_persistent_cnt = strtoll(getenv("AFL_QEMU_PERSISTENT_CNT"), NULL, 0); - else - afl_persistent_cnt = PERSISTENT_DEFAULT_MAX_CNT; - -} - -/* Fork server logic, invoked once we hit _start. */ - -void afl_forkserver(CPUState *cpu) { - - // u32 map_size = 0; - unsigned char tmp[4] = {0}; - - if (forkserver_installed == 1) return; - forkserver_installed = 1; - - if (getenv("AFL_QEMU_DEBUG_MAPS")) open_self_maps(cpu->env_ptr, 0); - - // if (!afl_area_ptr) return; // not necessary because of fixed dummy buffer - - pid_t child_pid; - int t_fd[2]; - u8 child_stopped = 0; - u32 was_killed; - int status = 0; - - // with the max ID value - if (MAP_SIZE <= FS_OPT_MAX_MAPSIZE) - status |= (FS_OPT_SET_MAPSIZE(MAP_SIZE) | FS_OPT_MAPSIZE); - if (sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ; - if (status) status |= (FS_OPT_ENABLED); - if (getenv("AFL_DEBUG")) - fprintf(stderr, "Debug: Sending status %08x\n", status); - memcpy(tmp, &status, 4); - - /* Tell the parent that we're alive. If the parent doesn't want - to talk, assume that we're not running in forkserver mode. */ - - if (write(FORKSRV_FD + 1, tmp, 4) != 4) return; - - afl_forksrv_pid = getpid(); - - int first_run = 1; - - if (sharedmem_fuzzing) { - - if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2); - - if ((was_killed & (0xffffffff & (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ))) == - (FS_OPT_ENABLED | FS_OPT_SHDMEM_FUZZ)) - afl_map_shm_fuzz(); - else { - - fprintf(stderr, - "[AFL] ERROR: afl-fuzz is old and does not support" - " shmem input"); - exit(1); - - } - - } - - /* All right, let's await orders... */ - - while (1) { - - /* Whoops, parent dead? */ - - if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2); - - /* If we stopped the child in persistent mode, but there was a race - condition and afl-fuzz already issued SIGKILL, write off the old - process. */ - - if (child_stopped && was_killed) { - - child_stopped = 0; - if (waitpid(child_pid, &status, 0) < 0) exit(8); - - } - - if (!child_stopped) { - - /* Establish a channel with child to grab translation commands. We'll - read from t_fd[0], child will write to TSL_FD. */ - - if (pipe(t_fd) || dup2(t_fd[1], TSL_FD) < 0) exit(3); - close(t_fd[1]); - - child_pid = fork(); - if (child_pid < 0) exit(4); - - if (!child_pid) { - - /* Child process. Close descriptors and run free. */ - - afl_fork_child = 1; - close(FORKSRV_FD); - close(FORKSRV_FD + 1); - close(t_fd[0]); - return; - - } - - /* Parent. */ - - close(TSL_FD); - - } else { - - /* Special handling for persistent mode: if the child is alive but - currently stopped, simply restart it with SIGCONT. */ - - kill(child_pid, SIGCONT); - child_stopped = 0; - - } - - /* Parent. */ - - if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5); - - /* Collect translation requests until child dies and closes the pipe. */ - - afl_wait_tsl(cpu, t_fd[0]); - - /* Get and relay exit status to parent. */ - - if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0) exit(6); - - /* In persistent mode, the child stops itself with SIGSTOP to indicate - a successful run. In this case, we want to wake it up without forking - again. */ - - if (WIFSTOPPED(status)) - child_stopped = 1; - else if (unlikely(first_run && is_persistent)) { - - fprintf(stderr, "[AFL] ERROR: no persistent iteration executed\n"); - exit(12); // Persistent is wrong - - } - - first_run = 0; - - if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7); - - } - -} - -/* A simplified persistent mode handler, used as explained in - * llvm_mode/README.md. */ - -void afl_persistent_loop(void) { - - static u32 cycle_cnt; - static struct afl_tsl exit_cmd_tsl = {{-1, 0, 0, 0}, '\0'}; - - if (!afl_fork_child) return; - - if (persistent_first_pass) { - - /* Make sure that every iteration of __AFL_LOOP() starts with a clean slate. - On subsequent calls, the parent will take care of that, but on the first - iteration, it's our job to erase any trace of whatever happened - before the loop. */ - - if (is_persistent) { - - memset(afl_area_ptr, 0, MAP_SIZE); - afl_area_ptr[0] = 1; - afl_prev_loc = 0; - - } - - cycle_cnt = afl_persistent_cnt; - persistent_first_pass = 0; - persistent_stack_offset = TARGET_LONG_BITS / 8; - - return; - - } - - if (is_persistent) { - - if (--cycle_cnt) { - - if (write(TSL_FD, &exit_cmd_tsl, sizeof(struct afl_tsl)) != - sizeof(struct afl_tsl)) { - - /* Exit the persistent loop on pipe error */ - afl_area_ptr = dummy; - exit(0); - - } - - raise(SIGSTOP); - - afl_area_ptr[0] = 1; - afl_prev_loc = 0; - - } else { - - afl_area_ptr = dummy; - exit(0); - - } - - } - -} - -/* This code is invoked whenever QEMU decides that it doesn't have a - translation of a particular block and needs to compute it, or when it - decides to chain two TBs together. When this happens, we tell the parent to - mirror the operation, so that the next fork() has a cached copy. */ - -static void afl_request_tsl(target_ulong pc, target_ulong cb, uint32_t flags, - uint32_t cf_mask, TranslationBlock *last_tb, - int tb_exit) { - - if (disable_caching) return; - - struct afl_tsl t; - struct afl_chain c; - - if (!afl_fork_child) return; - - t.tb.pc = pc; - t.tb.cs_base = cb; - t.tb.flags = flags; - t.tb.cf_mask = cf_mask; - t.is_chain = (last_tb != NULL); - - if (write(TSL_FD, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl)) - return; - - if (t.is_chain) { - - c.last_tb.pc = last_tb->pc; - c.last_tb.cs_base = last_tb->cs_base; - c.last_tb.flags = last_tb->flags; - c.cf_mask = cf_mask; - c.tb_exit = tb_exit; - - if (write(TSL_FD, &c, sizeof(struct afl_chain)) != sizeof(struct afl_chain)) - return; - - } - -} - -/* This is the other side of the same channel. Since timeouts are handled by - afl-fuzz simply killing the child, we can just wait until the pipe breaks. */ - -static void afl_wait_tsl(CPUState *cpu, int fd) { - - struct afl_tsl t; - struct afl_chain c; - TranslationBlock *tb, *last_tb; - - while (1) { - - u8 invalid_pc = 0; - - /* Broken pipe means it's time to return to the fork server routine. */ - - if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl)) break; - - /* Exit command for persistent */ - - if (t.tb.pc == (target_ulong)(-1)) return; - - tb = tb_htable_lookup(cpu, t.tb.pc, t.tb.cs_base, t.tb.flags, t.tb.cf_mask); - - if (!tb) { - - /* The child may request to transate a block of memory that is not - mapped in the parent (e.g. jitted code or dlopened code). - This causes a SIGSEV in gen_intermediate_code() and associated - subroutines. We simply avoid caching of such blocks. */ - - if (is_valid_addr(t.tb.pc)) { - - mmap_lock(); - tb = tb_gen_code(cpu, t.tb.pc, t.tb.cs_base, t.tb.flags, t.tb.cf_mask); - mmap_unlock(); - - } else { - - invalid_pc = 1; - - } - - } - - if (t.is_chain) { - - if (read(fd, &c, sizeof(struct afl_chain)) != sizeof(struct afl_chain)) - break; - - if (!invalid_pc) { - - last_tb = tb_htable_lookup(cpu, c.last_tb.pc, c.last_tb.cs_base, - c.last_tb.flags, c.cf_mask); -#define TB_JMP_RESET_OFFSET_INVALID 0xffff - if (last_tb && (last_tb->jmp_reset_offset[c.tb_exit] != - TB_JMP_RESET_OFFSET_INVALID)) { - - tb_add_jump(last_tb, c.tb_exit, tb); - - } - - } - - } - - } - - close(fd); - -} - diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h deleted file mode 100644 index 8553f194..00000000 --- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This code is a shim patched into the separately-distributed source - code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality - to implement AFL-style instrumentation and to take care of the remaining - parts of the AFL fork server logic. - - The resulting QEMU binary is essentially a standalone instrumentation - tool; for an example of how to leverage it for other purposes, you can - have a look at afl-showmap.c. - - */ - -#include "afl-qemu-common.h" -#include "tcg.h" -#include "tcg-op.h" - -#if TCG_TARGET_REG_BITS == 64 - #define _DEFAULT_MO MO_64 -#else - #define _DEFAULT_MO MO_32 -#endif - -static void afl_gen_compcov(target_ulong cur_loc, TCGv arg1, TCGv arg2, - TCGMemOp ot, int is_imm) { - - if (cur_loc > afl_end_code || cur_loc < afl_start_code) return; - - if (__afl_cmp_map) { - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= CMP_MAP_W - 1; - - TCGv cur_loc_v = tcg_const_tl(cur_loc); - - switch (ot & MO_SIZE) { - - case MO_64: - gen_helper_afl_cmplog_64(cur_loc_v, arg1, arg2); - break; - case MO_32: - gen_helper_afl_cmplog_32(cur_loc_v, arg1, arg2); - break; - case MO_16: - gen_helper_afl_cmplog_16(cur_loc_v, arg1, arg2); - break; - case MO_8: - gen_helper_afl_cmplog_8(cur_loc_v, arg1, arg2); - break; - default: - break; - - } - - tcg_temp_free(cur_loc_v); - - } else if (afl_compcov_level) { - - if (!is_imm && afl_compcov_level < 2) return; - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; - - TCGv cur_loc_v = tcg_const_tl(cur_loc); - - if (cur_loc >= afl_inst_rms) return; - - switch (ot & MO_SIZE) { - - case MO_64: - gen_helper_afl_compcov_64(cur_loc_v, arg1, arg2); - break; - case MO_32: - gen_helper_afl_compcov_32(cur_loc_v, arg1, arg2); - break; - case MO_16: - gen_helper_afl_compcov_16(cur_loc_v, arg1, arg2); - break; - default: - break; - - } - - tcg_temp_free(cur_loc_v); - - } - -} - -/* Routines for debug */ -/* -static void log_x86_saved_gpr(void) { - - static const char reg_names[CPU_NB_REGS][4] = { - -#ifdef TARGET_X86_64 - [R_EAX] = "rax", - [R_EBX] = "rbx", - [R_ECX] = "rcx", - [R_EDX] = "rdx", - [R_ESI] = "rsi", - [R_EDI] = "rdi", - [R_EBP] = "rbp", - [R_ESP] = "rsp", - [8] = "r8", - [9] = "r9", - [10] = "r10", - [11] = "r11", - [12] = "r12", - [13] = "r13", - [14] = "r14", - [15] = "r15", -#else - [R_EAX] = "eax", - [R_EBX] = "ebx", - [R_ECX] = "ecx", - [R_EDX] = "edx", - [R_ESI] = "esi", - [R_EDI] = "edi", - [R_EBP] = "ebp", - [R_ESP] = "esp", -#endif - - }; - - int i; - for (i = 0; i < CPU_NB_REGS; ++i) { - - fprintf(stderr, "%s = %lx\n", reg_names[i], persistent_saved_gpr[i]); - - } - -} - -static void log_x86_sp_content(void) { - - fprintf(stderr, ">> SP = %lx -> %lx\n", persistent_saved_gpr[R_ESP], -*(unsigned long*)persistent_saved_gpr[R_ESP]); - -}*/ - -static void callback_to_persistent_hook(void) { - - afl_persistent_hook_ptr(persistent_saved_gpr, guest_base, shared_buf, - *shared_buf_len); - -} - -static void gpr_saving(TCGv *cpu_regs, int regs_num) { - - int i; - TCGv_ptr gpr_sv; - - TCGv_ptr first_pass_ptr = tcg_const_ptr(&persistent_first_pass); - TCGv first_pass = tcg_temp_local_new(); - TCGv one = tcg_const_tl(1); - tcg_gen_ld8u_tl(first_pass, first_pass_ptr, 0); - - TCGLabel *lbl_restore_gpr = gen_new_label(); - tcg_gen_brcond_tl(TCG_COND_NE, first_pass, one, lbl_restore_gpr); - - // save GPR registers - for (i = 0; i < regs_num; ++i) { - - gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); - tcg_gen_st_tl(cpu_regs[i], gpr_sv, 0); - tcg_temp_free_ptr(gpr_sv); - - } - - gen_set_label(lbl_restore_gpr); - - afl_gen_tcg_plain_call(&afl_persistent_loop); - - if (afl_persistent_hook_ptr) - afl_gen_tcg_plain_call(callback_to_persistent_hook); - - // restore GPR registers - for (i = 0; i < regs_num; ++i) { - - gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); - tcg_gen_ld_tl(cpu_regs[i], gpr_sv, 0); - tcg_temp_free_ptr(gpr_sv); - - } - - tcg_temp_free_ptr(first_pass_ptr); - tcg_temp_free(first_pass); - tcg_temp_free(one); - -} - -static void restore_state_for_persistent(TCGv *cpu_regs, int regs_num, int sp) { - - if (persistent_save_gpr) { - - gpr_saving(cpu_regs, regs_num); - - } else if (afl_persistent_ret_addr == 0) { - - TCGv_ptr stack_off_ptr = tcg_const_ptr(&persistent_stack_offset); - TCGv stack_off = tcg_temp_new(); - tcg_gen_ld_tl(stack_off, stack_off_ptr, 0); - tcg_gen_sub_tl(cpu_regs[sp], cpu_regs[sp], stack_off); - tcg_temp_free(stack_off); - - } - -} - -#define AFL_QEMU_TARGET_I386_SNIPPET \ - if (is_persistent) { \ - \ - if (s->pc == afl_persistent_addr) { \ - \ - restore_state_for_persistent(cpu_regs, AFL_REGS_NUM, R_ESP); \ - /*afl_gen_tcg_plain_call(log_x86_saved_gpr); \ - afl_gen_tcg_plain_call(log_x86_sp_content);*/ \ - \ - if (afl_persistent_ret_addr == 0) { \ - \ - TCGv paddr = tcg_const_tl(afl_persistent_addr); \ - tcg_gen_qemu_st_tl(paddr, cpu_regs[R_ESP], persisent_retaddr_offset, \ - _DEFAULT_MO); \ - tcg_temp_free(paddr); \ - \ - } \ - \ - if (!persistent_save_gpr) afl_gen_tcg_plain_call(&afl_persistent_loop); \ - /*afl_gen_tcg_plain_call(log_x86_sp_content);*/ \ - \ - } else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \ - \ - gen_jmp_im(s, afl_persistent_addr); \ - gen_eob(s); \ - \ - } \ - \ - } - -// SP = 13, LINK = 14 - -#define AFL_QEMU_TARGET_ARM_SNIPPET \ - if (is_persistent) { \ - \ - if (dc->pc == afl_persistent_addr) { \ - \ - if (persistent_save_gpr) gpr_saving(cpu_R, AFL_REGS_NUM); \ - \ - if (afl_persistent_ret_addr == 0) { \ - \ - tcg_gen_movi_tl(cpu_R[14], afl_persistent_addr); \ - \ - } \ - \ - if (!persistent_save_gpr) afl_gen_tcg_plain_call(&afl_persistent_loop); \ - \ - } else if (afl_persistent_ret_addr && dc->pc == afl_persistent_ret_addr) { \ - \ - gen_bx_im(dc, afl_persistent_addr); \ - \ - } \ - \ - } - -// SP = 31, LINK = 30 - -#define AFL_QEMU_TARGET_ARM64_SNIPPET \ - if (is_persistent) { \ - \ - if (s->pc == afl_persistent_addr) { \ - \ - if (persistent_save_gpr) gpr_saving(cpu_X, AFL_REGS_NUM); \ - \ - if (afl_persistent_ret_addr == 0) { \ - \ - tcg_gen_movi_tl(cpu_X[30], afl_persistent_addr); \ - \ - } \ - \ - if (!persistent_save_gpr) afl_gen_tcg_plain_call(&afl_persistent_loop); \ - \ - } else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \ - \ - gen_goto_tb(s, 0, afl_persistent_addr); \ - \ - } \ - \ - } - diff --git a/qemu_mode/patches/afl-qemu-floats.h b/qemu_mode/patches/afl-qemu-floats.h deleted file mode 100644 index 2e50cf7e..00000000 --- a/qemu_mode/patches/afl-qemu-floats.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This code is a shim patched into the separately-distributed source - code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality - to implement AFL-style instrumentation and to take care of the remaining - parts of the AFL fork server logic. - - The resulting QEMU binary is essentially a standalone instrumentation - tool; for an example of how to leverage it for other purposes, you can - have a look at afl-showmap.c. - - */ - -#include "tcg.h" -#include "afl-qemu-common.h" - -union afl_float32 { - - float32 f; - struct { - - u64 sign : 1; - u64 exp : 7; - u64 frac : 24; - - }; - -}; - -union afl_float64 { - - float64 f; - struct { - - u64 sign : 1; - u64 exp : 11; - u64 frac : 52; - - }; - -}; - -// TODO 16 and 128 bits floats -// TODO figure out why float*_unpack_canonical does not work - -void afl_float_compcov_log_32(target_ulong cur_loc, float32 arg1, float32 arg2, - void *status) { - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; - - if (cur_loc >= afl_inst_rms) return; - - // float_status*s = (float_status*)status; - // FloatParts a = float32_unpack_canonical(arg1, s); - // FloatParts b = float32_unpack_canonical(arg2, s); - union afl_float32 a = {.f = arg1}; - union afl_float32 b = {.f = arg2}; - - // if (is_nan(a.cls) || is_nan(b.cls)) return; - - register uintptr_t idx = cur_loc; - - if (a.sign != b.sign) return; - INC_AFL_AREA(idx); - if (a.exp != b.exp) return; - INC_AFL_AREA(idx + 1); - - if ((a.frac & 0xff0000) == (b.frac & 0xff0000)) { - - INC_AFL_AREA(idx + 2); - if ((a.frac & 0xff00) == (b.frac & 0xff00)) { INC_AFL_AREA(idx + 3); } - - } - -} - -void afl_float_compcov_log_64(target_ulong cur_loc, float64 arg1, float64 arg2, - void *status) { - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; - - if (cur_loc >= afl_inst_rms) return; - - // float_status*s = (float_status*)status; - // FloatParts a = float64_unpack_canonical(arg1, s); - // FloatParts b = float64_unpack_canonical(arg2, s); - union afl_float64 a = {.f = arg1}; - union afl_float64 b = {.f = arg2}; - - // if (is_nan(a.cls) || is_nan(b.cls)) return; - - register uintptr_t idx = cur_loc; - - if (a.sign == b.sign) INC_AFL_AREA(idx); - if ((a.exp & 0xff00) == (b.exp & 0xff00)) { - - INC_AFL_AREA(idx + 1); - if ((a.exp & 0xff) == (b.exp & 0xff)) INC_AFL_AREA(idx + 2); - - } - - if ((a.frac & 0xff000000000000) == (b.frac & 0xff000000000000)) { - - INC_AFL_AREA(idx + 3); - if ((a.frac & 0xff0000000000) == (b.frac & 0xff0000000000)) { - - INC_AFL_AREA(idx + 4); - if ((a.frac & 0xff00000000) == (b.frac & 0xff00000000)) { - - INC_AFL_AREA(idx + 5); - if ((a.frac & 0xff000000) == (b.frac & 0xff000000)) { - - INC_AFL_AREA(idx + 6); - if ((a.frac & 0xff0000) == (b.frac & 0xff0000)) { - - INC_AFL_AREA(idx + 7); - if ((a.frac & 0xff00) == (b.frac & 0xff00)) INC_AFL_AREA(idx + 8); - - } - - } - - } - - } - - } - -} - -void afl_float_compcov_log_80(target_ulong cur_loc, floatx80 arg1, - floatx80 arg2) { - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; - - if (cur_loc >= afl_inst_rms) return; - - if (floatx80_invalid_encoding(arg1) || floatx80_invalid_encoding(arg2)) - return; - - flag a_sign = extractFloatx80Sign(arg1); - flag b_sign = extractFloatx80Sign(arg2); - - /*if (((extractFloatx80Exp(arg1) == 0x7fff) && - (extractFloatx80Frac(arg1) << 1)) || - ((extractFloatx80Exp(arg2) == 0x7fff) && - (extractFloatx80Frac(arg2) << 1))) - return;*/ - - register uintptr_t idx = cur_loc; - - if (a_sign == b_sign) INC_AFL_AREA(idx); - - if ((arg1.high & 0x7f00) == (arg2.high & 0x7f00)) { - - INC_AFL_AREA(idx + 1); - if ((arg1.high & 0xff) == (arg2.high & 0xff)) INC_AFL_AREA(idx + 2); - - } - - if ((arg1.low & 0xff00000000000000) == (arg2.low & 0xff00000000000000)) { - - INC_AFL_AREA(idx + 3); - if ((arg1.low & 0xff000000000000) == (arg2.low & 0xff000000000000)) { - - INC_AFL_AREA(idx + 4); - if ((arg1.low & 0xff0000000000) == (arg2.low & 0xff0000000000)) { - - INC_AFL_AREA(idx + 5); - if ((arg1.low & 0xff00000000) == (arg2.low & 0xff00000000)) { - - INC_AFL_AREA(idx + 6); - if ((arg1.low & 0xff000000) == (arg2.low & 0xff000000)) { - - INC_AFL_AREA(idx + 7); - if ((arg1.low & 0xff0000) == (arg2.low & 0xff0000)) { - - INC_AFL_AREA(idx + 8); - if ((arg1.low & 0xff00) == (arg2.low & 0xff00)) { - - INC_AFL_AREA(idx + 9); - // if ((arg1.low & 0xff) == (arg2.low & 0xff)) - // INC_AFL_AREA(idx + 10); - - } - - } - - } - - } - - } - - } - - } - -} - diff --git a/qemu_mode/patches/afl-qemu-tcg-inl.h b/qemu_mode/patches/afl-qemu-tcg-inl.h deleted file mode 100644 index f7c662db..00000000 --- a/qemu_mode/patches/afl-qemu-tcg-inl.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This code is a shim patched into the separately-distributed source - code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality - to implement AFL-style instrumentation and to take care of the remaining - parts of the AFL fork server logic. - - The resulting QEMU binary is essentially a standalone instrumentation - tool; for an example of how to leverage it for other purposes, you can - have a look at afl-showmap.c. - - */ -void afl_gen_tcg_plain_call(void *func); - -void afl_gen_tcg_plain_call(void *func) { - - TCGOp *op = tcg_emit_op(INDEX_op_call); - - TCGOP_CALLO(op) = 0; - - op->args[0] = (uintptr_t)func; - op->args[1] = 0; - TCGOP_CALLI(op) = 0; - -} - diff --git a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h b/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h deleted file mode 100644 index 400ebf24..00000000 --- a/qemu_mode/patches/afl-qemu-tcg-runtime-inl.h +++ /dev/null @@ -1,250 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This code is a shim patched into the separately-distributed source - code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality - to implement AFL-style instrumentation and to take care of the remaining - parts of the AFL fork server logic. - - The resulting QEMU binary is essentially a standalone instrumentation - tool; for an example of how to leverage it for other purposes, you can - have a look at afl-showmap.c. - - */ - -#include "afl-qemu-common.h" -#include "tcg.h" - -void HELPER(afl_entry_routine)(CPUArchState *env) { - - afl_forkserver(ENV_GET_CPU(env)); - -} - -void HELPER(afl_compcov_16)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t idx = cur_loc; - - if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } - -} - -void HELPER(afl_compcov_32)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t idx = cur_loc; - - if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { - - INC_AFL_AREA(idx + 2); - if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { - - INC_AFL_AREA(idx + 1); - if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } - - } - - } - -} - -void HELPER(afl_compcov_64)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t idx = cur_loc; - - if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) { - - INC_AFL_AREA(idx + 6); - if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) { - - INC_AFL_AREA(idx + 5); - if ((arg1 & 0xff0000000000) == (arg2 & 0xff0000000000)) { - - INC_AFL_AREA(idx + 4); - if ((arg1 & 0xff00000000) == (arg2 & 0xff00000000)) { - - INC_AFL_AREA(idx + 3); - if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { - - INC_AFL_AREA(idx + 2); - if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { - - INC_AFL_AREA(idx + 1); - if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } - - } - - } - - } - - } - - } - - } - -} - -void HELPER(afl_cmplog_8)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - // if (!__afl_cmp_map->headers[k].cnt) - // __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++; - - __afl_cmp_map->headers[k].shape = 0; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -void HELPER(afl_cmplog_16)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - // if (!__afl_cmp_map->headers[k].cnt) - // __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++; - - __afl_cmp_map->headers[k].shape = 1; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -void HELPER(afl_cmplog_32)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = 3; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -void HELPER(afl_cmplog_64)(target_ulong cur_loc, target_ulong arg1, - target_ulong arg2) { - - register uintptr_t k = (uintptr_t)cur_loc; - - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = 7; - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = arg1; - __afl_cmp_map->log[k][hits].v1 = arg2; - -} - -#include <sys/mman.h> - -static int area_is_mapped(void *ptr, size_t len) { - - char *p = ptr; - char *page = (char *)((uintptr_t)p & ~(sysconf(_SC_PAGE_SIZE) - 1)); - - int r = msync(page, (p - page) + len, MS_ASYNC); - if (r < 0) return errno != ENOMEM; - return 1; - -} - -void HELPER(afl_cmplog_rtn)(CPUArchState *env) { - -#if defined(TARGET_X86_64) - - void *ptr1 = g2h(env->regs[R_EDI]); - void *ptr2 = g2h(env->regs[R_ESI]); - -#elif defined(TARGET_I386) - - target_ulong *stack = g2h(env->regs[R_ESP]); - - if (!area_is_mapped(stack, sizeof(target_ulong) * 2)) return; - - // when this hook is executed, the retaddr is not on stack yet - void * ptr1 = g2h(stack[0]); - void * ptr2 = g2h(stack[1]); - -#else - - // stupid code to make it compile - void *ptr1 = NULL; - void *ptr2 = NULL; - return; - -#endif - - if (!area_is_mapped(ptr1, 32) || !area_is_mapped(ptr2, 32)) return; - -#if defined(TARGET_X86_64) || defined(TARGET_I386) - uintptr_t k = (uintptr_t)env->eip; -#else - uintptr_t k = 0; -#endif - - k = (k >> 4) ^ (k << 8); - k &= CMP_MAP_W - 1; - - __afl_cmp_map->headers[k].type = CMP_TYPE_RTN; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = 31; - - hits &= CMP_MAP_RTN_H - 1; - __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, - ptr1, 32); - __builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, - ptr2, 32); - -} - diff --git a/qemu_mode/patches/afl-qemu-translate-inl.h b/qemu_mode/patches/afl-qemu-translate-inl.h deleted file mode 100644 index 09614f5b..00000000 --- a/qemu_mode/patches/afl-qemu-translate-inl.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - american fuzzy lop++ - high-performance binary-only instrumentation - ------------------------------------------------------------------- - - Originally written by Andrew Griffiths <agriffiths@google.com> and - Michal Zalewski - - TCG instrumentation and block chaining support by Andrea Biondo - <andrea.biondo965@gmail.com> - - QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero - counters by Andrea Fioraldi <andreafioraldi@gmail.com> - - Copyright 2015, 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - This code is a shim patched into the separately-distributed source - code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality - to implement AFL-style instrumentation and to take care of the remaining - parts of the AFL fork server logic. - - The resulting QEMU binary is essentially a standalone instrumentation - tool; for an example of how to leverage it for other purposes, you can - have a look at afl-showmap.c. - - */ - -#include "afl-qemu-common.h" -#include "tcg-op.h" - -void HELPER(afl_maybe_log)(target_ulong cur_loc) { - - register uintptr_t afl_idx = cur_loc ^ afl_prev_loc; - - INC_AFL_AREA(afl_idx); - - afl_prev_loc = cur_loc >> 1; - -} - -/* Generates TCG code for AFL's tracing instrumentation. */ -static void afl_gen_trace(target_ulong cur_loc) { - - /* Optimize for cur_loc > afl_end_code, which is the most likely case on - Linux systems. */ - - if (cur_loc > afl_end_code || - cur_loc < afl_start_code /*|| !afl_area_ptr*/) // not needed because of - // static dummy buffer - return; - - /* Looks like QEMU always maps to fixed locations, so ASLR is not a - concern. Phew. But instruction addresses may be aligned. Let's mangle - the value to get something quasi-uniform. */ - - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 1; - - /* Implement probabilistic instrumentation by looking at scrambled block - address. This keeps the instrumented locations stable across runs. */ - - if (cur_loc >= afl_inst_rms) return; - - TCGv cur_loc_v = tcg_const_tl(cur_loc); - gen_helper_afl_maybe_log(cur_loc_v); - tcg_temp_free(cur_loc_v); - -} - diff --git a/qemu_mode/patches/arm-translate-a64.diff b/qemu_mode/patches/arm-translate-a64.diff deleted file mode 100644 index 83856217..00000000 --- a/qemu_mode/patches/arm-translate-a64.diff +++ /dev/null @@ -1,64 +0,0 @@ -diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c -index fd36425..992bf17 100644 ---- a/target/arm/translate-a64.c -+++ b/target/arm/translate-a64.c -@@ -39,6 +39,8 @@ - #include "translate-a64.h" - #include "qemu/atomic128.h" - -+#include "../patches/afl-qemu-cpu-translate-inl.h" -+ - static TCGv_i64 cpu_X[32]; - static TCGv_i64 cpu_pc; - -@@ -3365,6 +3367,12 @@ static void disas_add_sub_imm(DisasContext *s, uint32_t insn) - return; - } - -+ if (rd == 31 && sub_op) { // cmp xX, imm -+ TCGv_i64 tcg_imm = tcg_const_i64(imm); -+ afl_gen_compcov(s->pc, tcg_rn, tcg_imm, is_64bit ? MO_64 : MO_32, 1); -+ tcg_temp_free_i64(tcg_imm); -+ } -+ - tcg_result = tcg_temp_new_i64(); - if (!setflags) { - if (sub_op) { -@@ -3972,6 +3980,9 @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn) - - tcg_rm = read_cpu_reg(s, rm, sf); - ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3); -+ -+ if (rd == 31 && sub_op) // cmp xX, xY -+ afl_gen_compcov(s->pc, tcg_rn, tcg_rm, sf ? MO_64 : MO_32, 0); - - tcg_result = tcg_temp_new_i64(); - -@@ -4037,6 +4048,9 @@ static void disas_add_sub_reg(DisasContext *s, uint32_t insn) - - shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6); - -+ if (rd == 31 && sub_op) // cmp xX, xY -+ afl_gen_compcov(s->pc, tcg_rn, tcg_rm, sf ? MO_64 : MO_32, 0); -+ - tcg_result = tcg_temp_new_i64(); - - if (!setflags) { -@@ -4246,6 +4260,8 @@ static void disas_cc(DisasContext *s, uint32_t insn) - tcg_y = cpu_reg(s, y); - } - tcg_rn = cpu_reg(s, rn); -+ -+ afl_gen_compcov(s->pc, tcg_rn, tcg_y, sf ? MO_64 : MO_32, is_imm); - - /* Set the flags for the new comparison. */ - tcg_tmp = tcg_temp_new_i64(); -@@ -13317,6 +13333,8 @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) - static void disas_a64_insn(CPUARMState *env, DisasContext *s) - { - uint32_t insn; -+ -+ AFL_QEMU_TARGET_ARM64_SNIPPET - - insn = arm_ldl_code(env, s->pc, s->sctlr_b); - s->insn = insn; diff --git a/qemu_mode/patches/arm-translate.diff b/qemu_mode/patches/arm-translate.diff deleted file mode 100644 index daa5d43b..00000000 --- a/qemu_mode/patches/arm-translate.diff +++ /dev/null @@ -1,152 +0,0 @@ -diff --git a/target/arm/translate.c b/target/arm/translate.c -index 7c4675f..e3d999a 100644 ---- a/target/arm/translate.c -+++ b/target/arm/translate.c -@@ -59,6 +59,8 @@ - #define IS_USER(s) (s->user) - #endif - -+#include "../patches/afl-qemu-cpu-translate-inl.h" -+ - /* We reuse the same 64-bit temporaries for efficiency. */ - static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; - static TCGv_i32 cpu_R[16]; -@@ -9541,6 +9543,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) - } else { - if (set_cc) { - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); - } else { - tcg_gen_sub_i32(tmp, tmp, tmp2); - } -@@ -9550,6 +9553,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) - case 0x03: - if (set_cc) { - gen_sub_CC(tmp, tmp2, tmp); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); - } else { - tcg_gen_sub_i32(tmp, tmp2, tmp); - } -@@ -9604,6 +9608,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) - case 0x0a: - if (set_cc) { - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); - } - tcg_temp_free_i32(tmp); - break; -@@ -10565,7 +10570,7 @@ thumb2_logic_op(int op) - - static int - gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, -- TCGv_i32 t0, TCGv_i32 t1) -+ TCGv_i32 t0, TCGv_i32 t1, int has_imm) - { - int logic_cc; - -@@ -10611,15 +10616,17 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, - } - break; - case 13: /* sub */ -- if (conds) -+ if (conds) { - gen_sub_CC(t0, t0, t1); -- else -+ afl_gen_compcov(s->pc, t0, t1, MO_32, has_imm); -+ } else - tcg_gen_sub_i32(t0, t0, t1); - break; - case 14: /* rsb */ -- if (conds) -+ if (conds) { - gen_sub_CC(t0, t1, t0); -- else -+ afl_gen_compcov(s->pc, t0, t1, MO_32, has_imm); -+ } else - tcg_gen_sub_i32(t0, t1, t0); - break; - default: /* 5, 6, 7, 9, 12, 15. */ -@@ -11085,7 +11092,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) - conds = (insn & (1 << 20)) != 0; - logic_cc = (conds && thumb2_logic_op(op)); - gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); -- if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) -+ if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2, insn & (1 << 10))) - goto illegal_op; - tcg_temp_free_i32(tmp2); - if (rd == 13 && -@@ -11955,7 +11962,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) - } - op = (insn >> 21) & 0xf; - if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, -- shifter_out, tmp, tmp2)) -+ shifter_out, tmp, tmp2, insn & (1 << 10))) - goto illegal_op; - tcg_temp_free_i32(tmp2); - rd = (insn >> 8) & 0xf; -@@ -12206,8 +12213,10 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - if (insn & (1 << 9)) { - if (s->condexec_mask) - tcg_gen_sub_i32(tmp, tmp, tmp2); -- else -+ else { - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 10)); -+ } - } else { - if (s->condexec_mask) - tcg_gen_add_i32(tmp, tmp, tmp2); -@@ -12247,6 +12256,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - switch (op) { - case 1: /* cmp */ - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 1); - tcg_temp_free_i32(tmp); - tcg_temp_free_i32(tmp2); - break; -@@ -12261,8 +12271,10 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - case 3: /* sub */ - if (s->condexec_mask) - tcg_gen_sub_i32(tmp, tmp, tmp2); -- else -+ else { - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 1); -+ } - tcg_temp_free_i32(tmp2); - store_reg(s, rd, tmp); - break; -@@ -12308,6 +12320,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - tmp = load_reg(s, rd); - tmp2 = load_reg(s, rm); - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 0); - tcg_temp_free_i32(tmp2); - tcg_temp_free_i32(tmp); - break; -@@ -12466,6 +12479,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) - break; - case 0xa: /* cmp */ - gen_sub_CC(tmp, tmp, tmp2); -+ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 0); - rd = 16; - break; - case 0xb: /* cmn */ -@@ -13233,6 +13247,8 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) - return; - } - -+ AFL_QEMU_TARGET_ARM_SNIPPET -+ - insn = arm_ldl_code(env, dc->pc, dc->sctlr_b); - dc->insn = insn; - dc->pc += 4; -@@ -13301,6 +13317,8 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) - return; - } - -+ AFL_QEMU_TARGET_ARM_SNIPPET -+ - insn = arm_lduw_code(env, dc->pc, dc->sctlr_b); - is_16bit = thumb_insn_is_16bit(dc, insn); - dc->pc += 2; diff --git a/qemu_mode/patches/bsd-elfload.diff b/qemu_mode/patches/bsd-elfload.diff deleted file mode 100644 index 19e44f5b..00000000 --- a/qemu_mode/patches/bsd-elfload.diff +++ /dev/null @@ -1,83 +0,0 @@ -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index 7cccf3eb..195875af 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -15,6 +15,8 @@ - #undef ELF_ARCH - #endif - -+extern abi_ulong afl_entry_point, afl_start_code, afl_end_code; -+ - /* from personality.h */ - - /* -@@ -737,9 +739,13 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss) - end_addr1 = REAL_HOST_PAGE_ALIGN(elf_bss); - end_addr = HOST_PAGE_ALIGN(elf_bss); - if (end_addr1 < end_addr) { -- mmap((void *)g2h(end_addr1), end_addr - end_addr1, -+ void *p = mmap((void *)g2h(end_addr1), end_addr - end_addr1, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0); -+ if (p == MAP_FAILED) { -+ perror("padzero: cannot mmap"); -+ exit(-1); -+ } - } - } - -@@ -979,9 +985,13 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, - - /* Map the last of the bss segment */ - if (last_bss > elf_bss) { -- target_mmap(elf_bss, last_bss-elf_bss, -+ void *p = target_mmap(elf_bss, last_bss-elf_bss, - PROT_READ|PROT_WRITE|PROT_EXEC, - MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0); -+ if (p == MAP_FAILED) { -+ perror("load_elf_interp: cannot mmap"); -+ exit(-1); -+ } - } - free(elf_phdata); - -@@ -1522,6 +1532,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - info->start_data = start_data; - info->end_data = end_data; - info->start_stack = bprm->p; -+ if (!afl_start_code) afl_start_code = vaddr; -+ if (!afl_end_code) afl_end_code = vaddr_ef; - - /* Calling set_brk effectively mmaps the pages that we need for the bss and break - sections */ -@@ -1544,11 +1556,29 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - and some applications "depend" upon this behavior. - Since we do not have the power to recompile these, we - emulate the SVr4 behavior. Sigh. */ -- target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC, -+ void *p = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE, -1, 0); -+ if (p == MAP_FAILED) { -+ perror("load_elf_binary: cannot mmap"); -+ exit(-1); -+ } - } - - info->entry = elf_entry; -+ if (!afl_entry_point) { -+ char *ptr; -+ if ((ptr = getenv("AFL_ENTRYPOINT")) != NULL) { -+ afl_entry_point = strtoul(ptr, NULL, 16); -+ } else { -+ afl_entry_point = info->entry; -+ } -+#ifdef TARGET_ARM -+ /* The least significant bit indicates Thumb mode. */ -+ afl_entry_point = afl_entry_point & ~(target_ulong)1; -+#endif -+ } -+ if (getenv("AFL_DEBUG") != NULL) -+ fprintf(stderr, "AFL forkserver entrypoint: %p\n", (void*)afl_entry_point); - - return 0; - } diff --git a/qemu_mode/patches/configure.diff b/qemu_mode/patches/configure.diff deleted file mode 100644 index e265edae..00000000 --- a/qemu_mode/patches/configure.diff +++ /dev/null @@ -1,33 +0,0 @@ ---- a/configure 2019-08-02 18:04:50.000000000 +0200 -+++ b/configure 2020-02-28 06:31:30.424895061 +0100 -@@ -1479,6 +1479,8 @@ - ;; - --enable-capstone=system) capstone="system" - ;; -+ --enable-capstone=internal) capstone="internal" -+ ;; - --with-git=*) git="$optarg" - ;; - --enable-git-update) git_update=yes -@@ -4604,6 +4606,21 @@ - fi - - ########################################## -+cat > $TMPC << EOF -+#include <dlfcn.h> -+#include <stdlib.h> -+int main(int argc, char **argv) { return dlopen("libc.so", RTLD_NOW) != NULL; } -+EOF -+if compile_prog "" "" ; then -+ : -+elif compile_prog "" "-ldl" ; then -+ LIBS="-ldl $LIBS" -+ libs_qga="-ldl $libs_qga" -+else -+ error_exit "libdl check failed" -+fi -+ -+########################################## - # spice probe - if test "$spice" != "no" ; then - cat > $TMPC << EOF diff --git a/qemu_mode/patches/cpu-exec.diff b/qemu_mode/patches/cpu-exec.diff deleted file mode 100644 index 844be58c..00000000 --- a/qemu_mode/patches/cpu-exec.diff +++ /dev/null @@ -1,38 +0,0 @@ -diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c -index 870027d4..0bc87dfc 100644 ---- a/accel/tcg/cpu-exec.c -+++ b/accel/tcg/cpu-exec.c -@@ -36,6 +36,8 @@ - #include "sysemu/cpus.h" - #include "sysemu/replay.h" - -+#include "../patches/afl-qemu-cpu-inl.h" -+ - /* -icount align implementation. */ - - typedef struct SyncClocks { -@@ -397,11 +399,13 @@ static inline TranslationBlock *tb_find(CPUState *cpu, - TranslationBlock *tb; - target_ulong cs_base, pc; - uint32_t flags; -+ bool was_translated = false, was_chained = false; - - tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask); - if (tb == NULL) { - mmap_lock(); - tb = tb_gen_code(cpu, pc, cs_base, flags, cf_mask); -+ was_translated = true; - mmap_unlock(); - /* We add the TB in the virtual pc hash table for the fast lookup */ - atomic_set(&cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)], tb); -@@ -418,6 +422,10 @@ static inline TranslationBlock *tb_find(CPUState *cpu, - /* See if we can patch the calling TB. */ - if (last_tb) { - tb_add_jump(last_tb, tb_exit, tb); -+ was_chained = true; -+ } -+ if (was_translated || was_chained) { -+ afl_request_tsl(pc, cs_base, flags, cf_mask, was_chained ? last_tb : NULL, tb_exit); - } - return tb; - } diff --git a/qemu_mode/patches/elfload.diff b/qemu_mode/patches/elfload.diff deleted file mode 100644 index 011b03ea..00000000 --- a/qemu_mode/patches/elfload.diff +++ /dev/null @@ -1,70 +0,0 @@ -diff --git a/linux-user/elfload.c b/linux-user/elfload.c -index 5bccd2e2..fd7460b3 100644 ---- a/linux-user/elfload.c -+++ b/linux-user/elfload.c -@@ -20,6 +20,8 @@ - - #define ELF_OSABI ELFOSABI_SYSV - -+extern abi_ulong afl_entry_point, afl_start_code, afl_end_code; -+ - /* from personality.h */ - - /* -@@ -2301,6 +2303,21 @@ static void load_elf_image(const char *image_name, int image_fd, - info->brk = 0; - info->elf_flags = ehdr->e_flags; - -+ if (!afl_entry_point) { -+ char *ptr; -+ if ((ptr = getenv("AFL_ENTRYPOINT")) != NULL) { -+ afl_entry_point = strtoul(ptr, NULL, 16); -+ } else { -+ afl_entry_point = info->entry; -+ } -+#ifdef TARGET_ARM -+ /* The least significant bit indicates Thumb mode. */ -+ afl_entry_point = afl_entry_point & ~(target_ulong)1; -+#endif -+ } -+ if (getenv("AFL_DEBUG") != NULL) -+ fprintf(stderr, "AFL forkserver entrypoint: %p\n", (void*)afl_entry_point); -+ - for (i = 0; i < ehdr->e_phnum; i++) { - struct elf_phdr *eppnt = phdr + i; - if (eppnt->p_type == PT_LOAD) { -@@ -2335,9 +2352,11 @@ static void load_elf_image(const char *image_name, int image_fd, - if (elf_prot & PROT_EXEC) { - if (vaddr < info->start_code) { - info->start_code = vaddr; -+ if (!afl_start_code) afl_start_code = vaddr; - } - if (vaddr_ef > info->end_code) { - info->end_code = vaddr_ef; -+ if (!afl_end_code) afl_end_code = vaddr_ef; - } - } - if (elf_prot & PROT_WRITE) { -@@ -2662,6 +2681,22 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) - change some of these later */ - bprm->p = setup_arg_pages(bprm, info); - -+ // On PowerPC64 the entry point is the _function descriptor_ -+ // of the entry function. For AFL to properly initialize, -+ // afl_entry_point needs to be set to the actual first instruction -+ // as opposed executed by the target program. This as opposed to -+ // where the function's descriptor sits in memory. -+ // copied from PPC init_thread -+#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) -+ if (get_ppc64_abi(infop) < 2) { -+ uint64_t val; -+ get_user_u64(val, infop->entry + 8); -+ _regs->gpr[2] = val + infop->load_bias; -+ get_user_u64(val, infop->entry); -+ infop->entry = val + infop->load_bias; -+ } -+#endif -+ - scratch = g_new0(char, TARGET_PAGE_SIZE); - if (STACK_GROWS_DOWN) { - bprm->p = copy_elf_strings(1, &bprm->filename, scratch, diff --git a/qemu_mode/patches/i386-fpu_helper.diff b/qemu_mode/patches/i386-fpu_helper.diff deleted file mode 100644 index 3bd09d9c..00000000 --- a/qemu_mode/patches/i386-fpu_helper.diff +++ /dev/null @@ -1,54 +0,0 @@ -diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c -index ea5a0c48..89901315 100644 ---- a/target/i386/fpu_helper.c -+++ b/target/i386/fpu_helper.c -@@ -384,10 +384,16 @@ void helper_fxchg_ST0_STN(CPUX86State *env, int st_index) - - static const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; - -+#include "../patches/afl-qemu-common.h" -+ - void helper_fcom_ST0_FT0(CPUX86State *env) - { - int ret; - -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_80(env->eip, ST0, FT0); -+ - ret = floatx80_compare(ST0, FT0, &env->fp_status); - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; - } -@@ -396,6 +402,10 @@ void helper_fucom_ST0_FT0(CPUX86State *env) - { - int ret; - -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_80(env->eip, ST0, FT0); -+ - ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status); - env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; - } -@@ -407,6 +417,10 @@ void helper_fcomi_ST0_FT0(CPUX86State *env) - int eflags; - int ret; - -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_80(env->eip, ST0, FT0); -+ - ret = floatx80_compare(ST0, FT0, &env->fp_status); - eflags = cpu_cc_compute_all(env, CC_OP); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; -@@ -418,6 +432,10 @@ void helper_fucomi_ST0_FT0(CPUX86State *env) - int eflags; - int ret; - -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_80(env->eip, ST0, FT0); -+ - ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status); - eflags = cpu_cc_compute_all(env, CC_OP); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; diff --git a/qemu_mode/patches/i386-ops_sse.diff b/qemu_mode/patches/i386-ops_sse.diff deleted file mode 100644 index d2779ea8..00000000 --- a/qemu_mode/patches/i386-ops_sse.diff +++ /dev/null @@ -1,61 +0,0 @@ -diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h -index ed059897..a5296caa 100644 ---- a/target/i386/ops_sse.h -+++ b/target/i386/ops_sse.h -@@ -997,6 +997,8 @@ SSE_HELPER_CMP(cmpord, FPU_CMPORD) - - static const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; - -+#include "../patches/afl-qemu-common.h" -+ - void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s) - { - int ret; -@@ -1004,6 +1006,11 @@ void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s) - - s0 = d->ZMM_S(0); - s1 = s->ZMM_S(0); -+ -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status); -+ - ret = float32_compare_quiet(s0, s1, &env->sse_status); - CC_SRC = comis_eflags[ret + 1]; - } -@@ -1015,6 +1022,11 @@ void helper_comiss(CPUX86State *env, Reg *d, Reg *s) - - s0 = d->ZMM_S(0); - s1 = s->ZMM_S(0); -+ -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status); -+ - ret = float32_compare(s0, s1, &env->sse_status); - CC_SRC = comis_eflags[ret + 1]; - } -@@ -1026,6 +1038,11 @@ void helper_ucomisd(CPUX86State *env, Reg *d, Reg *s) - - d0 = d->ZMM_D(0); - d1 = s->ZMM_D(0); -+ -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status); -+ - ret = float64_compare_quiet(d0, d1, &env->sse_status); - CC_SRC = comis_eflags[ret + 1]; - } -@@ -1037,6 +1054,11 @@ void helper_comisd(CPUX86State *env, Reg *d, Reg *s) - - d0 = d->ZMM_D(0); - d1 = s->ZMM_D(0); -+ -+ if (afl_compcov_level > 2 && env->eip < afl_end_code && -+ env->eip >= afl_start_code) -+ afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status); -+ - ret = float64_compare(d0, d1, &env->sse_status); - CC_SRC = comis_eflags[ret + 1]; - } diff --git a/qemu_mode/patches/i386-translate.diff b/qemu_mode/patches/i386-translate.diff deleted file mode 100644 index f0d1393b..00000000 --- a/qemu_mode/patches/i386-translate.diff +++ /dev/null @@ -1,62 +0,0 @@ -diff --git a/target/i386/translate.c b/target/i386/translate.c -index 0dd5fbe4..0d405fb6 100644 ---- a/target/i386/translate.c -+++ b/target/i386/translate.c -@@ -32,6 +32,8 @@ - #include "trace-tcg.h" - #include "exec/log.h" - -+#include "../patches/afl-qemu-cpu-translate-inl.h" -+ - #define PREFIX_REPZ 0x01 - #define PREFIX_REPNZ 0x02 - #define PREFIX_LOCK 0x04 -@@ -1343,9 +1345,11 @@ static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d) - tcg_gen_atomic_fetch_add_tl(s1->cc_srcT, s1->A0, s1->T0, - s1->mem_index, ot | MO_LE); - tcg_gen_sub_tl(s1->T0, s1->cc_srcT, s1->T1); -+ afl_gen_compcov(s1->pc, s1->cc_srcT, s1->T1, ot, d == OR_EAX); - } else { - tcg_gen_mov_tl(s1->cc_srcT, s1->T0); - tcg_gen_sub_tl(s1->T0, s1->T0, s1->T1); -+ afl_gen_compcov(s1->pc, s1->T0, s1->T1, ot, d == OR_EAX); - gen_op_st_rm_T0_A0(s1, ot, d); - } - gen_op_update2_cc(s1); -@@ -1389,6 +1393,7 @@ static void gen_op(DisasContext *s1, int op, TCGMemOp ot, int d) - tcg_gen_mov_tl(cpu_cc_src, s1->T1); - tcg_gen_mov_tl(s1->cc_srcT, s1->T0); - tcg_gen_sub_tl(cpu_cc_dst, s1->T0, s1->T1); -+ afl_gen_compcov(s1->pc, s1->T0, s1->T1, ot, d == OR_EAX); - set_cc_op(s1, CC_OP_SUBB + ot); - break; - } -@@ -4508,6 +4513,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) - rex_w = -1; - rex_r = 0; - -+ AFL_QEMU_TARGET_I386_SNIPPET -+ - next_byte: - b = x86_ldub_code(env, s); - /* Collect prefixes. */ -@@ -5056,6 +5063,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) - tcg_gen_ext16u_tl(s->T0, s->T0); - } - next_eip = s->pc - s->cs_base; -+ if (__afl_cmp_map && next_eip >= afl_start_code && -+ next_eip < afl_end_code) -+ gen_helper_afl_cmplog_rtn(cpu_env); - tcg_gen_movi_tl(s->T1, next_eip); - gen_push_v(s, s->T1); - gen_op_jmp_v(s->T0); -@@ -6544,6 +6554,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) - tval = (int16_t)insn_get(env, s, MO_16); - } - next_eip = s->pc - s->cs_base; -+ if (__afl_cmp_map && next_eip >= afl_start_code && -+ next_eip < afl_end_code) -+ gen_helper_afl_cmplog_rtn(cpu_env); - tval += next_eip; - if (dflag == MO_16) { - tval &= 0xffff; diff --git a/qemu_mode/patches/make_strncpy_safe.diff b/qemu_mode/patches/make_strncpy_safe.diff deleted file mode 100644 index 38c7d248..00000000 --- a/qemu_mode/patches/make_strncpy_safe.diff +++ /dev/null @@ -1,31 +0,0 @@ ---- a/util/qemu-sockets.c 2020-03-28 13:55:09.511029429 +0100 -+++ b/util/qemu-sockets.c 2020-03-28 14:01:12.147693937 +0100 -@@ -877,7 +877,7 @@ - - memset(&un, 0, sizeof(un)); - un.sun_family = AF_UNIX; -- strncpy(un.sun_path, path, sizeof(un.sun_path)); -+ strncpy(un.sun_path, path, sizeof(un.sun_path) - 1); - - if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { - error_setg_errno(errp, errno, "Failed to bind socket to %s", path); -@@ -922,7 +922,7 @@ - - memset(&un, 0, sizeof(un)); - un.sun_family = AF_UNIX; -- strncpy(un.sun_path, saddr->path, sizeof(un.sun_path)); -+ strncpy(un.sun_path, saddr->path, sizeof(un.sun_path) - 1); - - /* connect to peer */ - do { ---- a/block/sheepdog.c 2020-03-28 14:01:57.164360270 +0100 -+++ b/block/sheepdog.c 2020-03-28 14:02:52.781026597 +0100 -@@ -1236,7 +1236,7 @@ - * don't want the send_req to read uninitialized data. - */ - strncpy(buf, filename, SD_MAX_VDI_LEN); -- strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN); -+ strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN - 1); - - memset(&hdr, 0, sizeof(hdr)); - if (lock) { diff --git a/qemu_mode/patches/mips-fpu.diff b/qemu_mode/patches/mips-fpu.diff deleted file mode 100644 index 646d167e..00000000 --- a/qemu_mode/patches/mips-fpu.diff +++ /dev/null @@ -1,15 +0,0 @@ ---- a/linux-user/elfload.c 2020-07-13 20:10:37.776374566 -0700 -+++ b/linux-user/elfload.c 2020-07-13 20:11:51.794957015 -0700 -@@ -2667,6 +2667,11 @@ - char *elf_interpreter = NULL; - char *scratch; - -+ memset(&interp_info, 0, sizeof(interp_info)); -+#ifdef TARGET_MIPS -+ interp_info.fp_abi = MIPS_ABI_FP_UNKNOWN; -+#endif -+ - info->start_mmap = (abi_ulong)ELF_START_MMAP; - - load_elf_image(bprm->filename, bprm->fd, info, - diff --git a/qemu_mode/patches/mmap_fixes.diff b/qemu_mode/patches/mmap_fixes.diff deleted file mode 100644 index 1882bd40..00000000 --- a/qemu_mode/patches/mmap_fixes.diff +++ /dev/null @@ -1,165 +0,0 @@ -diff --git a/exec.c b/exec.c -index df5571e..d484098 100644 ---- a/exec.c -+++ b/exec.c -@@ -2457,7 +2457,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) - area = mmap(vaddr, length, PROT_READ | PROT_WRITE, - flags, -1, 0); - } -- if (area != vaddr) { -+ if (area == MAP_FAILED || area != vaddr) { - error_report("Could not remap addr: " - RAM_ADDR_FMT "@" RAM_ADDR_FMT "", - length, addr); -diff --git a/linux-user/mmap.c b/linux-user/mmap.c -index 41e0983..0a8b8e5 100644 ---- a/linux-user/mmap.c -+++ b/linux-user/mmap.c -@@ -612,9 +612,13 @@ static void mmap_reserve(abi_ulong start, abi_ulong size) - real_end -= qemu_host_page_size; - } - if (real_start != real_end) { -- mmap(g2h(real_start), real_end - real_start, PROT_NONE, -+ void *p = mmap(g2h(real_start), real_end - real_start, PROT_NONE, - MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, - -1, 0); -+ if (p == MAP_FAILED) { -+ perror("mmap_reserve: cannot mmap"); -+ exit(-1); -+ } - } - } - -diff --git a/roms/SLOF/tools/sloffs.c b/roms/SLOF/tools/sloffs.c -index 9a1eace..10366f0 100644 ---- a/roms/SLOF/tools/sloffs.c -+++ b/roms/SLOF/tools/sloffs.c -@@ -308,6 +308,10 @@ sloffs_append(const int file, const char *name, const char *dest) - - fstat(fd, &stat); - append = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0); -+ if (append == MAP_FAILED) { -+ perror("sloffs_append: cannot mmap for read"); -+ exit(1); -+ } - header = sloffs_header(file); - - if (!header) -@@ -331,6 +335,10 @@ sloffs_append(const int file, const char *name, const char *dest) - write(out, "", 1); - write_start = mmap(NULL, new_len, PROT_READ | PROT_WRITE, - MAP_SHARED, out, 0); -+ if (write_start == MAP_FAILED) { -+ perror("sloffs_append: cannot mmap for read/write"); -+ exit(1); -+ } - - memset(write_start, 0, new_len); - memset(&new_file, 0, sizeof(struct sloffs)); -diff --git a/roms/skiboot/core/test/run-trace.c b/roms/skiboot/core/test/run-trace.c -index 9801688..236b51d 100644 ---- a/roms/skiboot/core/test/run-trace.c -+++ b/roms/skiboot/core/test/run-trace.c -@@ -178,6 +178,10 @@ static void test_parallel(void) - i = (CPUS*len + getpagesize()-1)&~(getpagesize()-1); - p = mmap(NULL, i, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_SHARED, -1, 0); -+ if (p == MAP_FAILED) { -+ perror("test_parallel: cannot mmap"); -+ exit(-1); -+ } - - for (i = 0; i < CPUS; i++) { - fake_cpus[i].trace = p + i * len; -diff --git a/roms/skiboot/external/ffspart/ffspart.c b/roms/skiboot/external/ffspart/ffspart.c -index 7703477..efbbd5b 100644 ---- a/roms/skiboot/external/ffspart/ffspart.c -+++ b/roms/skiboot/external/ffspart/ffspart.c -@@ -379,7 +379,7 @@ int main(int argc, char *argv[]) - } - - data_ptr = mmap(NULL, pactual, PROT_READ, MAP_SHARED, data_fd, 0); -- if (!data_ptr) { -+ if (data_ptr == MAP_FAILED) { - fprintf(stderr, "Couldn't mmap data file for partition '%s': %s\n", - name, strerror(errno)); - rc = -1; -diff --git a/roms/skiboot/extract-gcov.c b/roms/skiboot/extract-gcov.c -index 3d31d1b..ebc03e6 100644 ---- a/roms/skiboot/extract-gcov.c -+++ b/roms/skiboot/extract-gcov.c -@@ -229,7 +229,11 @@ int main(int argc, char *argv[]) - } - - addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); -- assert(addr != NULL); -+ assert(addr != MAP_FAILED); -+ if (addr == MAP_FAILED) { -+ perror("main: cannot mmap"); -+ exit(-1); -+ } - skiboot_dump_size = sb.st_size; - - printf("Skiboot memory dump %p - %p\n", -diff --git a/roms/skiboot/libstb/create-container.c b/roms/skiboot/libstb/create-container.c -index 5cf80a0..64699ad 100644 ---- a/roms/skiboot/libstb/create-container.c -+++ b/roms/skiboot/libstb/create-container.c -@@ -96,7 +96,11 @@ void getSigRaw(ecc_signature_t *sigraw, char *inFile) - assert(r==0); - - infile = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fdin, 0); -- assert(infile); -+ assert(infile != MAP_FAILED); -+ if (infile == MAP_FAILED) { -+ perror("getSigRaw: cannot mmap"); -+ exit(-1); -+ } - - signature = d2i_ECDSA_SIG(NULL, (const unsigned char **) &infile, 7 + 2*EC_COORDBYTES); - -@@ -356,7 +360,11 @@ int main(int argc, char* argv[]) - r = fstat(fdin, &s); - assert(r==0); - infile = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fdin, 0); -- assert(infile); -+ assert(infile != MAP_FAILED); -+ if (infile == MAP_FAILED) { -+ perror("main: cannot mmap"); -+ exit(-1); -+ } - fdout = open(params.imagefn, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - assert(fdout > 0); - -diff --git a/tests/tcg/multiarch/test-mmap.c b/tests/tcg/multiarch/test-mmap.c -index 11d0e77..14f5919 100644 ---- a/tests/tcg/multiarch/test-mmap.c -+++ b/tests/tcg/multiarch/test-mmap.c -@@ -203,6 +203,7 @@ void check_aligned_anonymous_fixed_mmaps(void) - p1 = mmap(addr, pagesize, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, - -1, 0); -+ fail_unless (p1 != MAP_FAILED); - /* Make sure we get pages aligned with the pagesize. - The target expects this. */ - p = (uintptr_t) p1; -@@ -234,6 +235,7 @@ void check_aligned_anonymous_fixed_mmaps_collide_with_host(void) - p1 = mmap(addr, pagesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, - -1, 0); -+ fail_unless (p1 != MAP_FAILED); - /* Make sure we get pages aligned with the pagesize. - The target expects this. */ - p = (uintptr_t) p1; -@@ -401,6 +403,10 @@ void check_file_fixed_mmaps(void) - p4 = mmap(addr + pagesize * 3, pagesize, PROT_READ, - MAP_PRIVATE | MAP_FIXED, - test_fd, pagesize * 3); -+ fail_unless (p1 != MAP_FAILED); -+ fail_unless (p2 != MAP_FAILED); -+ fail_unless (p3 != MAP_FAILED); -+ fail_unless (p4 != MAP_FAILED); - - /* Make sure we get pages aligned with the pagesize. - The target expects this. */ - diff --git a/qemu_mode/patches/softfloat.diff b/qemu_mode/patches/softfloat.diff deleted file mode 100644 index 86ffb97f..00000000 --- a/qemu_mode/patches/softfloat.diff +++ /dev/null @@ -1,10 +0,0 @@ -diff --git a/fpu/softfloat.c b/fpu/softfloat.c -index e1eef954..2f8d0d62 100644 ---- a/fpu/softfloat.c -+++ b/fpu/softfloat.c -@@ -7205,3 +7205,5 @@ float128 float128_scalbn(float128 a, int n, float_status *status) - , status); - - } -+ -+#include "../../patches/afl-qemu-floats.h" diff --git a/qemu_mode/patches/syscall.diff b/qemu_mode/patches/syscall.diff deleted file mode 100644 index b635a846..00000000 --- a/qemu_mode/patches/syscall.diff +++ /dev/null @@ -1,102 +0,0 @@ -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index b13a170e..3f5cc902 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -111,6 +111,9 @@ - - #include "qemu.h" - #include "fd-trans.h" -+#include <linux/sockios.h> -+ -+extern unsigned int afl_forksrv_pid; - - #ifndef CLONE_IO - #define CLONE_IO 0x80000000 /* Clone io context */ -@@ -250,7 +253,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \ - #endif - - #ifdef __NR_gettid --_syscall0(int, gettid) -+#define __NR_sys_gettid __NR_gettid -+_syscall0(int, sys_gettid) - #else - /* This is a replacement for the host gettid() and must return a host - errno. */ -@@ -5384,7 +5388,7 @@ static void *clone_func(void *arg) - cpu = ENV_GET_CPU(env); - thread_cpu = cpu; - ts = (TaskState *)cpu->opaque; -- info->tid = gettid(); -+ info->tid = sys_gettid(); - task_settid(ts); - if (info->child_tidptr) - put_user_u32(info->tid, info->child_tidptr); -@@ -5529,9 +5533,9 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, - mapping. We can't repeat the spinlock hack used above because - the child process gets its own copy of the lock. */ - if (flags & CLONE_CHILD_SETTID) -- put_user_u32(gettid(), child_tidptr); -+ put_user_u32(sys_gettid(), child_tidptr); - if (flags & CLONE_PARENT_SETTID) -- put_user_u32(gettid(), parent_tidptr); -+ put_user_u32(sys_gettid(), parent_tidptr); - ts = (TaskState *)cpu->opaque; - if (flags & CLONE_SETTLS) - cpu_set_tls (env, newtls); -@@ -6554,7 +6558,8 @@ static int open_self_cmdline(void *cpu_env, int fd) - return 0; - } - --static int open_self_maps(void *cpu_env, int fd) -+int open_self_maps(void *cpu_env, int fd); -+int open_self_maps(void *cpu_env, int fd) - { - CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); - TaskState *ts = cpu->opaque; -@@ -7324,10 +7329,12 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, - #ifdef TARGET_NR_stime /* not on alpha */ - case TARGET_NR_stime: - { -- time_t host_time; -- if (get_user_sal(host_time, arg1)) -+ struct timespec ts; -+ ts.tv_nsec = 0; -+ if (get_user_sal(ts.tv_sec, arg1)) { - return -TARGET_EFAULT; -- return get_errno(stime(&host_time)); -+ } -+ return get_errno(clock_settime(CLOCK_REALTIME, &ts)); - } - #endif - #ifdef TARGET_NR_alarm /* not on alpha */ -@@ -10529,7 +10536,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, - return TARGET_PAGE_SIZE; - #endif - case TARGET_NR_gettid: -- return get_errno(gettid()); -+ return get_errno(sys_gettid()); - #ifdef TARGET_NR_readahead - case TARGET_NR_readahead: - #if TARGET_ABI_BITS == 32 -@@ -10813,8 +10820,19 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, - return get_errno(safe_tkill((int)arg1, target_to_host_signal(arg2))); - - case TARGET_NR_tgkill: -- return get_errno(safe_tgkill((int)arg1, (int)arg2, -- target_to_host_signal(arg3))); -+ { -+ int pid = (int)arg1, -+ tgid = (int)arg2, -+ sig = (int)arg3; -+ -+ /* Not entirely sure if the below is correct for all architectures. */ -+ -+ if(afl_forksrv_pid && afl_forksrv_pid == pid && sig == SIGABRT) -+ pid = tgid = getpid(); -+ -+ ret = get_errno(safe_tgkill(pid, tgid, target_to_host_signal(sig))); -+ -+ } - - #ifdef TARGET_NR_set_robust_list - case TARGET_NR_set_robust_list: diff --git a/qemu_mode/patches/tcg-runtime-head.diff b/qemu_mode/patches/tcg-runtime-head.diff deleted file mode 100644 index f250686e..00000000 --- a/qemu_mode/patches/tcg-runtime-head.diff +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h -index 1bd39d13..81ef3973 100644 ---- a/accel/tcg/tcg-runtime.h -+++ b/accel/tcg/tcg-runtime.h -@@ -260,3 +260,14 @@ DEF_HELPER_FLAGS_4(gvec_leu8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) - DEF_HELPER_FLAGS_4(gvec_leu16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) - DEF_HELPER_FLAGS_4(gvec_leu32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) - DEF_HELPER_FLAGS_4(gvec_leu64, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32) -+ -+DEF_HELPER_FLAGS_1(afl_entry_routine, TCG_CALL_NO_RWG, void, env) -+DEF_HELPER_FLAGS_1(afl_maybe_log, TCG_CALL_NO_RWG, void, tl) -+DEF_HELPER_FLAGS_3(afl_compcov_16, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_compcov_32, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_compcov_64, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_cmplog_8, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_cmplog_16, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_cmplog_32, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_3(afl_cmplog_64, TCG_CALL_NO_RWG, void, tl, tl, tl) -+DEF_HELPER_FLAGS_1(afl_cmplog_rtn, TCG_CALL_NO_RWG, void, env) diff --git a/qemu_mode/patches/tcg-runtime.diff b/qemu_mode/patches/tcg-runtime.diff deleted file mode 100644 index 15456320..00000000 --- a/qemu_mode/patches/tcg-runtime.diff +++ /dev/null @@ -1,10 +0,0 @@ -diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c -index d0d44844..009ef15a 100644 ---- a/accel/tcg/tcg-runtime.c -+++ b/accel/tcg/tcg-runtime.c -@@ -167,3 +167,5 @@ void HELPER(exit_atomic)(CPUArchState *env) - { - cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC()); - } -+ -+#include "../../../patches/afl-qemu-tcg-runtime-inl.h" diff --git a/qemu_mode/patches/tcg.diff b/qemu_mode/patches/tcg.diff deleted file mode 100644 index 0aea5afb..00000000 --- a/qemu_mode/patches/tcg.diff +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/tcg/tcg.c b/tcg/tcg.c -index e85133ef..54b9b390 100644 ---- a/tcg/tcg.c -+++ b/tcg/tcg.c -@@ -1612,6 +1612,9 @@ bool tcg_op_supported(TCGOpcode op) - } - } - -+ -+#include "../../patches/afl-qemu-tcg-inl.h" -+ - /* Note: we convert the 64 bit args to 32 bit and do some alignment - and endian swap. Maybe it would be better to do the alignment - and endian swap in tcg_reg_alloc_call(). */ diff --git a/qemu_mode/patches/translate-all.diff b/qemu_mode/patches/translate-all.diff deleted file mode 100644 index ca310b11..00000000 --- a/qemu_mode/patches/translate-all.diff +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c -index 639f0b27..21a45494 100644 ---- a/accel/tcg/translate-all.c -+++ b/accel/tcg/translate-all.c -@@ -59,6 +59,8 @@ - #include "exec/log.h" - #include "sysemu/cpus.h" - -+#include "../patches/afl-qemu-translate-inl.h" -+ - /* #define DEBUG_TB_INVALIDATE */ - /* #define DEBUG_TB_FLUSH */ - /* make various TB consistency checks */ -@@ -1721,6 +1723,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, - tcg_func_start(tcg_ctx); - - tcg_ctx->cpu = ENV_GET_CPU(env); -+ afl_gen_trace(pc); - gen_intermediate_code(cpu, tb); - tcg_ctx->cpu = NULL; - diff --git a/qemu_mode/patches/translator.diff b/qemu_mode/patches/translator.diff deleted file mode 100644 index 842e861d..00000000 --- a/qemu_mode/patches/translator.diff +++ /dev/null @@ -1,25 +0,0 @@ -diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c -index afd0a49e..773ea712 100644 ---- a/accel/tcg/translator.c -+++ b/accel/tcg/translator.c -@@ -18,6 +18,8 @@ - #include "exec/log.h" - #include "exec/translator.h" - -+#include "../../../patches/afl-qemu-common.h" -+ - /* Pairs with tcg_clear_temp_count. - To be called by #TranslatorOps.{translate_insn,tb_stop} if - (1) the target is sufficiently clean to support reporting, -@@ -92,6 +94,11 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, - break; - } - } -+ -+ if (db->pc_next == afl_entry_point) { -+ afl_setup(); -+ gen_helper_afl_entry_routine(cpu_env); -+ } - - /* Disassemble one instruction. The translate_insn hook should - update db->pc_next and db->is_jmp to indicate what should be diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl new file mode 160000 +Subproject c688bac2ac4e5066fd174d5dc43bdbdffe59def diff --git a/qemu_mode/update_ref.sh b/qemu_mode/update_ref.sh new file mode 100755 index 00000000..53c004ec --- /dev/null +++ b/qemu_mode/update_ref.sh @@ -0,0 +1,46 @@ +#/bin/sh + +################################################## +# AFL++ internal tool to update qemuafl ref. +# Usage: ./update_ref.sh <new commit hash> +# If no commit hash was provided, it'll take HEAD. +################################################## + +UC_VERSION_FILE='./QEMUAFL_VERSION' + +NEW_VERSION="$1" + +if [ "$NEW_VERSION" = "-h" ]; then + echo "Internal script to update bound qemuafl version." + echo + echo "Usage: ./update_ref.sh <new commit hash>" + echo "If no commit hash is provided, will use HEAD." + echo "-h to show this help screen." + exit 1 +fi + +git submodule init && git submodule update || exit 1 +cd ./qemuafl || exit 1 +git fetch origin master 1>/dev/null || exit 1 +git stash 1>/dev/null 2>/dev/null +git stash drop 1>/dev/null 2>/dev/null +git checkout master + +if [ -z "$NEW_VERSION" ]; then + # No version provided, take HEAD. + NEW_VERSION=$(git rev-parse --short HEAD) +fi + +if [ -z "$NEW_VERSION" ]; then + echo "Error getting version." + exit 1 +fi + +git checkout "$NEW_VERSION" || exit 1 + +cd .. + +rm "$UC_VERSION_FILE" +echo "$NEW_VERSION" > "$UC_VERSION_FILE" + +echo "Done. New qemuafl version is $NEW_VERSION." |