diff --git a/include/afl/config.h b/include/afl/config.h index b5137553..4630da0c 100644 --- a/include/afl/config.h +++ b/include/afl/config.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2020 AFLplusplus Project. All rights reserved. + Copyright 2019-2021 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. @@ -25,8 +25,8 @@ /* Version string: */ -// c = release, d = volatile github dev, e = experimental branch -#define VERSION "++3.01a" +// c = release, a = volatile github dev, e = experimental branch +#define VERSION "++3.15a" /****************************************************** * * @@ -34,6 +34,55 @@ * * ******************************************************/ +/* Default shared memory map size. Most targets just need a coverage map + between 20-250kb. Plus there is an auto-detection feature in afl-fuzz. + However if a target has problematic constructors and init arrays then + this can fail. Hence afl-fuzz deploys a larger default map. The largest + map seen so far is the xlsx fuzzer for libreoffice which is 5MB. + At runtime this value can be overriden via AFL_MAP_SIZE. + Default: 8MB (defined in bytes) */ +#define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024) + +/* Default file permission umode when creating files (default: 0600) */ +#define DEFAULT_PERMISSION 0600 + +/* CMPLOG/REDQUEEN TUNING + * + * Here you can modify tuning and solving options for CMPLOG. + * Note that these are run-time options for afl-fuzz, no target + * recompilation required. + * + */ + +/* if TRANSFORM is enabled with '-l T', this additionally enables base64 + encoding/decoding */ +// #define CMPLOG_SOLVE_TRANSFORM_BASE64 + +/* If a redqueen pass finds more than one solution, try to combine them? */ +#define CMPLOG_COMBINE + +/* Minimum % of the corpus to perform cmplog on. Default: 10% */ +#define CMPLOG_CORPUS_PERCENT 5U + +/* Number of potential positions from which we decide if cmplog becomes + useless, default 8096 */ +#define CMPLOG_POSITIONS_MAX (12 * 1024) + +/* Maximum allowed fails per CMP value. Default: 128 */ +#define CMPLOG_FAIL_MAX 96 + +/* -------------------------------------*/ +/* Now non-cmplog configuration options */ +/* -------------------------------------*/ + +/* If a persistent target keeps state and found crashes are not reproducable + then enable this option and set the AFL_PERSISTENT_RECORD env variable + to a number. These number of testcases prior and including the crash case + will be kept and written to the crash/ directory as RECORD:... files. + Note that every crash will be written, not only unique ones! */ + +//#define AFL_PERSISTENT_RECORD + /* console output colors: There are three ways to configure its behavior * 1. default: colored outputs fixed on: defined USE_COLOR && defined * ALWAYS_COLORED The env var. AFL_NO_COLOR will have no effect @@ -67,7 +116,7 @@ /* If you want to have the original afl internal memory corruption checks. Disabled by default for speed. it is better to use "make ASAN_BUILD=1". */ -//#define _WANT_ORIGINAL_AFL_ALLOC +// #define _WANT_ORIGINAL_AFL_ALLOC /* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */ @@ -105,7 +154,7 @@ cases that show variable behavior): */ #define CAL_CYCLES 8U -#define CAL_CYCLES_LONG 40U +#define CAL_CYCLES_LONG 20U /* Number of subsequent timeouts before abandoning an input file: */ @@ -114,7 +163,7 @@ /* Maximum number of unique hangs or crashes to record: */ #define KEEP_UNIQUE_HANG 500U -#define KEEP_UNIQUE_CRASH 5000U +#define KEEP_UNIQUE_CRASH 10000U /* Baseline number of random tweaks during a single 'havoc' stage: */ @@ -188,11 +237,11 @@ (note that if this value is changed, several areas in afl-cc.c, afl-fuzz.c and afl-fuzz-state.c have to be changed as well! */ -#define MAX_FILE (1 * 1024 * 1024U) +#define MAX_FILE (1 * 1024 * 1024L) /* The same, for the test case minimizer: */ -#define TMIN_MAX_FILE (10 * 1024 * 1024) +#define TMIN_MAX_FILE (10 * 1024 * 1024L) /* Block normalization steps for afl-tmin: */ @@ -253,6 +302,11 @@ #define SYNC_INTERVAL 8 +/* Sync time (minimum time between syncing in ms, time is halfed for -M main + nodes) - default is 30 minutes: */ + +#define SYNC_TIME (30 * 60 * 1000) + /* Output directory reuse grace period (minutes): */ #define OUTPUT_GRACE 25 @@ -352,6 +406,10 @@ #define MSAN_ERROR 86 +/* Distinctive exit code used to indicate LSAN trip condition: */ + +#define LSAN_ERROR 23 + /* Designated file descriptors for forkserver commands (the application will use FORKSRV_FD and FORKSRV_FD + 1): */ diff --git a/include/uc_priv.h b/include/uc_priv.h index b881a666..a148c10e 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -315,6 +315,7 @@ struct uc_struct { bool no_exit_request; // Disable check_exit_request temporarily. A workaround to treat the IT block as a whole block. #ifdef UNICORN_HAS_AFL + bool afl; uc_afl_forkserver_t afl_forkserver_start; // function to start afl forkserver uc_afl_ret_uc_bool_t afl_child_request_next; // function from child to ask for new testcase (if in child) int afl_child_pipe[2]; // pipe used to send information from child process to forkserver diff --git a/qemu/accel/tcg/translator.c b/qemu/accel/tcg/translator.c index 96f92873..0ee09488 100644 --- a/qemu/accel/tcg/translator.c +++ b/qemu/accel/tcg/translator.c @@ -61,7 +61,7 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, /* Reset the temp count so that we can identify leaks */ tcg_clear_temp_count(); - if (uc->mode & UC_MODE_AFL) { + if (uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = cpu->uc->exits; size_t exit_count = cpu->uc->exit_count; diff --git a/qemu/softmmu/cpus.c b/qemu/softmmu/cpus.c index acb7f14b..242b0279 100644 --- a/qemu/softmmu/cpus.c +++ b/qemu/softmmu/cpus.c @@ -194,7 +194,7 @@ void resume_all_vcpus(struct uc_struct* uc) tb_flush_jmp_cache(cpu, uc->addr_end); } - if (uc->mode & UC_MODE_AFL) { + if (uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = uc->exits; size_t exit_count = uc->exit_count; diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 5ab0e963..d3c4d5f2 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -14641,7 +14641,7 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) DisasContext *dc = container_of(dcbase, DisasContext, base); CPUARMState *env = cpu->env_ptr; - if (dc->uc->mode & UC_MODE_AFL) { + if (dc->uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = dc->uc->exits; size_t exit_count = dc->uc->exit_count; diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index fe325e1c..f7f77666 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -11420,7 +11420,7 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) return; } - if (dc->uc->mode & UC_MODE_AFL) { + if (dc->uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = dc->uc->exits; size_t exit_count = dc->uc->exit_count; diff --git a/qemu/target/i386/translate.c b/qemu/target/i386/translate.c index 4b44bafd..a82ec50d 100644 --- a/qemu/target/i386/translate.c +++ b/qemu/target/i386/translate.c @@ -4764,7 +4764,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) s->uc = env->uc; - if (s->uc->mode & UC_MODE_AFL) { + if (s->uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = s->uc->exits; size_t exit_count = s->uc->exit_count; diff --git a/qemu/target/m68k/translate.c b/qemu/target/m68k/translate.c index c1940270..44929992 100644 --- a/qemu/target/m68k/translate.c +++ b/qemu/target/m68k/translate.c @@ -6325,7 +6325,7 @@ static void m68k_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) CPUM68KState *env = cpu->env_ptr; uint16_t insn; - if (uc->mode & UC_MODE_AFL) { + if (uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = uc->exits; size_t exit_count = uc->exit_count; diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index ff36123b..c604056a 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -30931,7 +30931,7 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) is_slot = ctx->hflags & MIPS_HFLAG_BMASK; - if (uc->mode & UC_MODE_AFL) { + if (uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = uc->exits; size_t exit_count = uc->exit_count; diff --git a/qemu/target/ppc/translate.c b/qemu/target/ppc/translate.c index 623e8b4c..8394ac5f 100644 --- a/qemu/target/ppc/translate.c +++ b/qemu/target/ppc/translate.c @@ -7625,7 +7625,7 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n", ctx->base.pc_next, ctx->mem_idx, (int)msr_ir); - if (uc->mode & UC_MODE_AFL) { + if (uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = uc->exits; size_t exit_count = uc->exit_count; diff --git a/qemu/target/riscv/translate.c b/qemu/target/riscv/translate.c index 3e78dbfc..5ec8a16d 100644 --- a/qemu/target/riscv/translate.c +++ b/qemu/target/riscv/translate.c @@ -849,7 +849,7 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) TCGOp *tcg_op, *prev_op = NULL; bool insn_hook = false; - if (uc->mode & UC_MODE_AFL) { + if (uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = ctx->uc->exits; size_t exit_count = ctx->uc->exit_count; diff --git a/qemu/target/sparc/translate.c b/qemu/target/sparc/translate.c index 66f834d3..46061c32 100644 --- a/qemu/target/sparc/translate.c +++ b/qemu/target/sparc/translate.c @@ -5950,7 +5950,7 @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) CPUSPARCState *env = cs->env_ptr; unsigned int insn; - if (uc->mode & UC_MODE_AFL) { + if (uc->afl) { // UNICORN-AFL supports (and needs) multiple exits. uint64_t *exits = uc->exits; size_t exit_count = uc->exit_count; diff --git a/uc.c b/uc.c index 2ad8edc7..4ee3c8f2 100644 --- a/uc.c +++ b/uc.c @@ -162,6 +162,11 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result) return UC_ERR_NOMEM; } + if (mode & UC_MODE_AFL) { + uc->afl = true; + mode &= (~UC_MODE_AFL); + } + /* qemu/exec.c: phys_map_node_reserve() */ uc->alloc_hint = 16; uc->errnum = UC_ERR_OK; @@ -937,7 +942,7 @@ uc_err uc_afl_fuzz( UCLOG(stderr, "[!] Unicorn Engine passed to uc_afl_fuzz is NULL!\n"); return UC_ERR_AFL_RET_ERROR; } - if (!(uc->mode & UC_MODE_AFL)) { + if (!(uc->afl)) { return UC_ERR_MODE; } if (!input_file || input_file[0] == 0) {