diff options
author | Dominik Maier <domenukk@gmail.com> | 2020-04-17 11:01:20 +0200 |
---|---|---|
committer | Dominik Maier <domenukk@gmail.com> | 2020-04-17 11:01:20 +0200 |
commit | 90ff345d733caa51f6d2895dd229104c286b62c4 (patch) | |
tree | 9bf965a3e7f447ea0779848a6e09f9b356a0707e | |
parent | 8fa5d4c313372a337c7facf0428b0339babbe057 (diff) | |
parent | 2162fd8e1a1ceb745c1fcf87fb6a1053508591c4 (diff) | |
download | afl++-90ff345d733caa51f6d2895dd229104c286b62c4.tar.gz |
Merge branch 'dev' of github.com:aflplusplus/aflplusplus into dev
-rw-r--r-- | docs/Changelog.md | 6 | ||||
-rw-r--r-- | docs/env_variables.md | 5 | ||||
-rw-r--r-- | gcc_plugin/afl-gcc-fast.c | 10 | ||||
-rw-r--r-- | include/afl-fuzz.h | 2 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | include/forkserver.h | 2 | ||||
-rw-r--r-- | llvm_mode/afl-clang-fast.c | 60 | ||||
-rw-r--r-- | llvm_mode/afl-llvm-lto-instrumentation.so.cc | 30 | ||||
-rw-r--r-- | llvm_mode/afl-llvm-pass.so.cc | 68 | ||||
-rwxr-xr-x | qemu_mode/build_qemu_support.sh | 1 | ||||
-rw-r--r-- | src/afl-analyze.c | 26 | ||||
-rw-r--r-- | src/afl-common.c | 8 | ||||
-rw-r--r-- | src/afl-forkserver.c | 21 | ||||
-rw-r--r-- | src/afl-fuzz-bitmap.c | 16 | ||||
-rw-r--r-- | src/afl-fuzz-init.c | 21 | ||||
-rw-r--r-- | src/afl-fuzz-python.c | 2 | ||||
-rw-r--r-- | src/afl-fuzz-queue.c | 9 | ||||
-rw-r--r-- | src/afl-fuzz-run.c | 2 | ||||
-rw-r--r-- | src/afl-fuzz-state.c | 24 | ||||
-rw-r--r-- | src/afl-fuzz-stats.c | 31 | ||||
-rw-r--r-- | src/afl-fuzz.c | 62 | ||||
-rw-r--r-- | src/afl-gcc.c | 9 | ||||
-rw-r--r-- | src/afl-showmap.c | 42 | ||||
-rw-r--r-- | src/afl-tmin.c | 33 |
24 files changed, 323 insertions, 170 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md index e1e558b7..3ad80b7b 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -19,14 +19,18 @@ sending a mail to <afl-users+subscribe@googlegroups.com>. - snapshot feature usage now visible in UI - Now setting "-L -1" will enable MOpt in parallel to normal mutation. Additionally this allows to run dictionaries, radamsa and cmplog. + - fix for cmplog/redqueen mode if stdin was used + - fix for writing a better plot_data file + - qemu_mode: fix for persistent mode - compare-transform/AFL_LLVM_LAF_TRANSFORM_COMPARES now transforms also static global and local variable comparisons (cannot find all though) - extended forkserver: map_size and more information is communicated to afl-fuzz (and afl-fuzz acts accordingly) - - more refactoring + - new environment variable: AFL_MAP_SIZE to specify the size of the shared map - if AFL_CC/AFL_CXX is set but empty afl compilers did fail, fixed (this bug is in vanilla afl too) - added NO_PYTHON flag to disable python support when building afl-fuzz + - more refactoring ### Version ++2.63c (release): diff --git a/docs/env_variables.md b/docs/env_variables.md index 7890da35..21bf9fad 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -243,6 +243,11 @@ checks or alter some of the more exotic semantics of the tool: normally indicated by the cycle counter in the UI turning green. May be convenient for some types of automated jobs. + - AFL_MAP_SIZE sets the size of the shared map that afl-fuzz, afl-showmap, + afl-tmin and afl-analyze create to gather instrumentation data from + the target. This must be equal or larger than the size the target was + compiled with. + - Setting AFL_NO_AFFINITY disables attempts to bind to a specific CPU core on Linux systems. This slows things down, but lets you run more instances of afl-fuzz than would be prudent (if you really want to). diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c index 8953c523..0e51ee62 100644 --- a/gcc_plugin/afl-gcc-fast.c +++ b/gcc_plugin/afl-gcc-fast.c @@ -364,6 +364,16 @@ int main(int argc, char **argv, char **envp) { be_quiet = 1; + u8 *ptr; + if (!be_quiet && + ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE")))) { + + u32 map_size = atoi(ptr); + if (map_size != MAP_SIZE) + FATAL("AFL_MAP_SIZE is not supported by afl-gcc-fast"); + + } + check_environment_vars(envp); find_obj(argv[0]); diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 363776cb..88cacc4f 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -325,6 +325,8 @@ typedef struct afl_env_vars { *afl_python_module, *afl_path, *afl_hang_tmout, *afl_skip_crashes, *afl_preload; + uint32_t map_size; + } afl_env_vars_t; struct afl_pass_stat { diff --git a/include/config.h b/include/config.h index f0274fd3..fae97a42 100644 --- a/include/config.h +++ b/include/config.h @@ -407,8 +407,7 @@ #define FS_OPT_SNAPSHOT 0x20000000 #define FS_OPT_AUTODICT 0x10000000 #define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1) -#define FS_OPT_SET_MAPSIZE(x) \ - (x <= 1 || x > MAP_SIZE || x > 0x1000000 ? 0 : ((x - 1) << 1)) +#define FS_OPT_SET_MAPSIZE(x) (x <= 1 || x > 0x1000000 ? 0 : ((x - 1) << 1)) #endif /* ! _HAVE_CONFIG_H */ diff --git a/include/forkserver.h b/include/forkserver.h index ac89b681..d76dfc7a 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -61,7 +61,7 @@ typedef struct afl_forkserver { u64 total_execs; /* How often run_target was called */ u8 *out_file, /* File to fuzz, if any */ - *target_path; /* Path of the target */ + *target_path; /* Path of the target */ FILE *plot_file; /* Gnuplot output file */ diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c index c0471033..7466db26 100644 --- a/llvm_mode/afl-clang-fast.c +++ b/llvm_mode/afl-clang-fast.c @@ -716,30 +716,30 @@ int main(int argc, char **argv, char **envp) { "Environment variables used:\n" "AFL_CC: path to the C compiler to use\n" "AFL_CXX: path to the C++ compiler to use\n" - "AFL_PATH: path to instrumenting pass and runtime " - "(afl-llvm-rt.*o)\n" - "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" - "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" - "AFL_INST_RATIO: percentage of branches to instrument\n" - "AFL_QUIET: suppress verbose output\n" "AFL_DEBUG: enable developer debugging output\n" + "AFL_DONT_OPTIMIZE: disable optimization instead of -O3\n" "AFL_HARDEN: adds code hardening to catch memory bugs\n" - "AFL_USE_ASAN: activate address sanitizer\n" - "AFL_USE_MSAN: activate memory sanitizer\n" - "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n" - "AFL_USE_CFISAN: activate control flow sanitizer\n" - "AFL_LLVM_WHITELIST: enable whitelisting (selective " - "instrumentation)\n" + "AFL_INST_RATIO: percentage of branches to instrument\n" "AFL_LLVM_NOT_ZERO: use cycling trace counters that skip zero\n" "AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n" - "AFL_LLVM_LAF_SPLIT_SWITCHES: casc. comp. in 'switch'\n" - "AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison " - "function calls\n" - " to cascaded comparisons\n" "AFL_LLVM_LAF_SPLIT_FLOATS: transform floating point comp. to " "cascaded " "comp.\n" - "AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n", + "AFL_LLVM_LAF_SPLIT_SWITCHES: casc. comp. in 'switch'\n" + " to cascaded comparisons\n" + "AFL_LLVM_LAF_TRANSFORM_COMPARES: transform library comparison " + "function calls\n" + "AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n" + "AFL_LLVM_WHITELIST: enable whitelisting (selective " + "instrumentation)\n" + "AFL_NO_BUILTIN: compile for use with libtokencap.so\n" + "AFL_PATH: path to instrumenting pass and runtime " + "(afl-llvm-rt.*o)\n" + "AFL_QUIET: suppress verbose output\n" + "AFL_USE_ASAN: activate address sanitizer\n" + "AFL_USE_CFISAN: activate control flow sanitizer\n" + "AFL_USE_MSAN: activate memory sanitizer\n" + "AFL_USE_UBSAN: activate undefined behaviour sanitizer\n", callname, BIN_PATH, BIN_PATH); SAYF( @@ -747,21 +747,21 @@ int main(int argc, char **argv, char **envp) { "AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen mutator)\n" "AFL_LLVM_INSTRUMENT: set instrumentation mode: DEFAULT, CFG " "(INSTRIM), LTO, CTX, NGRAM-2 ... NGRAM-16\n" - "You can also use the old environment variables:" - "AFL_LLVM_CTX: use context sensitive coverage\n" - "AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" - "AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage\n" - "AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" - "AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed (sub " + " You can also use the old environment variables instead:" + " AFL_LLVM_CTX: use context sensitive coverage\n" + " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" + " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage\n" + " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" + " AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed (sub " "option to INSTRIM)\n"); #ifdef AFL_CLANG_FLTO SAYF( "\nafl-clang-lto specific environment variables:\n" - "AFL_LLVM_LTO_STARTID: from which ID to start counting from for a " - "bb\n" "AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a " "global var\n" + "AFL_LLVM_LTO_STARTID: from which ID to start counting from for a " + "bb\n" "AFL_REAL_LD: use this lld linker instead of the compiled in path\n" "\nafl-clang-lto was built with linker target \"%s\" and LTO flags " "\"%s\"\n" @@ -796,6 +796,16 @@ int main(int argc, char **argv, char **envp) { } + u8 *ptr2; + if (!be_quiet && instrument_mode != INSTRUMENT_LTO && + ((ptr2 = getenv("AFL_MAP_SIZE")) || (ptr2 = getenv("AFL_MAPSIZE")))) { + + u32 map_size = atoi(ptr2); + if (map_size != MAP_SIZE) + FATAL("AFL_MAP_SIZE is not supported by afl-clang-fast"); + + } + if (debug) { SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc index c5e7a2b7..ece3201f 100644 --- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc +++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc @@ -608,20 +608,22 @@ bool AFLLTOPass::runOnModule(Module &M) { } - // save highest location ID to global variable - // do this after each function to fail faster - if (afl_global_id > MAP_SIZE) { - - uint32_t pow2map = 1, map = afl_global_id; - while ((map = map >> 1)) - pow2map++; - FATAL( - "We have %u blocks to instrument but the map size is only %u! Edit " - "config.h and set MAP_SIZE_POW2 from %u to %u, then recompile " - "afl-fuzz and llvm_mode.", - afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map); + } - } + // save highest location ID to global variable + // do this after each function to fail faster + if (!be_quiet && afl_global_id > MAP_SIZE) { + + uint32_t pow2map = 1, map = afl_global_id; + while ((map = map >> 1)) + pow2map++; + WARNF( + "We have %u blocks to instrument but the map size is only %u. Either " + "edit config.h and set MAP_SIZE_POW2 from %u to %u, then recompile " + "afl-fuzz and llvm_mode and then make this target - or set " + "AFL_MAP_SIZE with at least size %u when running afl-fuzz with this " + "target.", + afl_global_id, MAP_SIZE, MAP_SIZE_POW2, pow2map, afl_global_id); } @@ -635,7 +637,7 @@ bool AFLLTOPass::runOnModule(Module &M) { if (!f) { fprintf(stderr, - "Error: init function could not be found (this hould not " + "Error: init function could not be found (this should not " "happen)\n"); exit(-1); diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index b4249802..71abcd05 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -125,6 +125,7 @@ class AFLCoverage : public ModulePass { std::list<std::string> myWhitelist; uint32_t ngram_size = 0; uint32_t debug = 0; + uint32_t map_size = MAP_SIZE; char * ctx_str = NULL; }; @@ -192,6 +193,19 @@ bool AFLCoverage::runOnModule(Module &M) { be_quiet = 1; + /* + char *ptr; + if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { + + map_size = atoi(ptr); + if (map_size < 8 || map_size > (1 << 29)) + FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", + map_size); if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3); + + } + + */ + /* Decide instrumentation ratio */ char * inst_ratio_str = getenv("AFL_INST_RATIO"); @@ -365,7 +379,7 @@ bool AFLCoverage::runOnModule(Module &M) { // if yes we store a context ID for this function in the global var if (has_calls) { - ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(MAP_SIZE)); + ConstantInt *NewCtx = ConstantInt::get(Int32Ty, AFL_R(map_size)); StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext); StoreCtx->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); @@ -509,7 +523,7 @@ bool AFLCoverage::runOnModule(Module &M) { /* Make up cur_loc */ // cur_loc++; - cur_loc = AFL_R(MAP_SIZE); + cur_loc = AFL_R(map_size); /* There is a problem with Ubuntu 18.04 and llvm 6.0 (see issue #63). The inline function successors() is not inlined and also not found at runtime @@ -705,6 +719,56 @@ bool AFLCoverage::runOnModule(Module &M) { } + /* + // This is currently disabled because we not only need to create/insert a + // function (easy), but also add it as a constructor with an ID < 5 + + if (getenv("AFL_LLVM_DONTWRITEID") == NULL) { + + // yes we could create our own function, insert it into ctors ... + // but this would be a pain in the butt ... so we use afl-llvm-rt.o + + Function *f = ... + + if (!f) { + + fprintf(stderr, + "Error: init function could not be created (this should not + happen)\n"); exit(-1); + + } + + ... constructor for f = 4 + + BasicBlock *bb = &f->getEntryBlock(); + if (!bb) { + + fprintf(stderr, + "Error: init function does not have an EntryBlock (this should + not happen)\n"); exit(-1); + + } + + BasicBlock::iterator IP = bb->getFirstInsertionPt(); + IRBuilder<> IRB(&(*IP)); + + if (map_size <= 0x800000) { + + GlobalVariable *AFLFinalLoc = new GlobalVariable( + M, Int32Ty, true, GlobalValue::ExternalLinkage, 0, + "__afl_final_loc", 0, GlobalVariable::GeneralDynamicTLSModel, 0, + false); + ConstantInt *const_loc = ConstantInt::get(Int32Ty, map_size); + StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc); + StoreFinalLoc->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); + + } + + } + + */ + /* Say something nice. */ if (!be_quiet) { diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index c512396a..b34a149b 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -233,6 +233,7 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then gcc test-instr.c -o test-instr || exit 1 unset AFL_INST_RATIO + export ASAN_OPTIONS=detect_leaks=0 echo "[*] Comparing two afl-showmap -Q outputs..." echo 0 | ./afl-showmap -m none -Q -q -o .test-instr0 ./test-instr || exit 1 diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 6f946ed5..8a84b781 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -84,6 +84,7 @@ static volatile u8 stop_soon, /* Ctrl-C pressed? */ static u8 *target_path; static u8 qemu_mode; +static u32 map_size = MAP_SIZE; /* Constants used for describing byte behavior. */ @@ -115,7 +116,7 @@ static u8 count_class_lookup[256] = { static void classify_counts(u8 *mem) { - u32 i = MAP_SIZE; + u32 i = map_size; if (edges_only) { @@ -144,7 +145,7 @@ static void classify_counts(u8 *mem) { static inline u8 anything_set(void) { u32 *ptr = (u32 *)trace_bits; - u32 i = (MAP_SIZE >> 2); + u32 i = (map_size >> 2); while (i--) if (*(ptr++)) return 1; @@ -217,7 +218,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) { s32 prog_in_fd; u32 cksum; - memset(trace_bits, 0, MAP_SIZE); + memset(trace_bits, 0, map_size); MEM_BARRIER(); prog_in_fd = write_to_file(prog_in, mem, len); @@ -311,7 +312,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) { } - cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST); + cksum = hash32(trace_bits, map_size, HASH_CONST); /* We don't actually care if the target is crashing or not, except that when it does, the checksum should be different. */ @@ -795,8 +796,10 @@ static void usage(u8 *argv0) { " (must contain abort_on_error=1 and symbolize=0)\n" "MSAN_OPTIONS: custom settings for MSAN\n" " (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n" - "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_ANALYZE_HEX: print file offsets in hexadecimal instead of decimal\n" + "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" + " the target was compiled for\n" + "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_SKIP_BIN_CHECK: skip checking the location of and the target\n" , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path); @@ -811,7 +814,7 @@ int main(int argc, char **argv, char **envp) { s32 opt; u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; - char **use_argv; + char **use_argv, *ptr; doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; @@ -931,12 +934,21 @@ int main(int argc, char **argv, char **envp) { if (optind == argc || !in_file) usage(argv[0]); + if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { + + map_size = atoi(ptr); + if (map_size < 8 || map_size > (1 << 29)) + FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size); + if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3); + + } + use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX"); check_environment_vars(envp); sharedmem_t shm = {0}; - trace_bits = afl_shm_init(&shm, MAP_SIZE, 0); + trace_bits = afl_shm_init(&shm, map_size, 0); atexit(at_exit_handler); setup_signal_handlers(); diff --git a/src/afl-common.c b/src/afl-common.c index 48efff2c..45868271 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -72,7 +72,7 @@ char *afl_environment_variables[] = { "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_X86", // not really an env but we dont want to warn on it - "AFL_PATH", "AFL_PERFORMANCE_FILE", + "AFL_MAP_SIZE", "AFL_MAPSIZE", "AFL_PATH", "AFL_PERFORMANCE_FILE", //"AFL_PERSISTENT", // not implemented anymore, so warn additionally "AFL_POST_LIBRARY", "AFL_PRELOAD", "AFL_PYTHON_MODULE", "AFL_QEMU_COMPCOV", "AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE", @@ -376,9 +376,13 @@ u8 *find_binary(u8 *fname) { target_path = ck_strdup(fname); if (stat(target_path, &st) || !S_ISREG(st.st_mode) || - !(st.st_mode & 0111) || st.st_size < 4) + !(st.st_mode & 0111) || st.st_size < 4) { + + free(target_path); FATAL("Program '%s' not found or not executable", fname); + } + } else { while (env_path) { diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 006764d9..9b915a7a 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -407,21 +407,26 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) { - fsrv->map_size = FS_OPT_GET_MAPSIZE(status); - if (unlikely(fsrv->map_size % 8)) { + u32 tmp_map_size = FS_OPT_GET_MAPSIZE(status); + + if (!fsrv->map_size) fsrv->map_size = MAP_SIZE; + + if (unlikely(tmp_map_size % 8)) { // should not happen - WARNF("Target reported non-aligned map size of %ud", fsrv->map_size); - fsrv->map_size = (((fsrv->map_size + 8) >> 3) << 3); + WARNF("Target reported non-aligned map size of %ud", tmp_map_size); + tmp_map_size = (((tmp_map_size + 8) >> 3) << 3); } - if (!be_quiet) ACTF("Target map size: %u", fsrv->map_size); - if (fsrv->map_size > MAP_SIZE) + if (!be_quiet) ACTF("Target map size: %u", tmp_map_size); + if (tmp_map_size > fsrv->map_size) FATAL( "Target's coverage map size of %u is larger than the one this " - "afl++ is compiled with (%u) (change MAP_SIZE and recompile)\n", - fsrv->map_size, MAP_SIZE); + "afl++ is set with (%u) (change MAP_SIZE_POW2 in config.h and " + "recompile or set AFL_MAP_SIZE)\n", + tmp_map_size, fsrv->map_size); + fsrv->map_size = tmp_map_size; } diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index be8f504e..0823deed 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -43,7 +43,7 @@ void write_bitmap(afl_state_t *afl) { if (fd < 0) PFATAL("Unable to open '%s'", fname); - ck_write(fd, afl->virgin_bits, MAP_SIZE, fname); + ck_write(fd, afl->virgin_bits, afl->fsrv.map_size, fname); close(fd); @@ -145,8 +145,6 @@ u32 count_bits(afl_state_t *afl, u8 *mem) { u32 i = (afl->fsrv.map_size >> 2); u32 ret = 0; - if (i == 0) i = 1; - while (i--) { u32 v = *(ptr++); @@ -181,8 +179,6 @@ u32 count_bytes(afl_state_t *afl, u8 *mem) { u32 i = (afl->fsrv.map_size >> 2); u32 ret = 0; - if (i == 0) i = 1; - while (i--) { u32 v = *(ptr++); @@ -208,8 +204,6 @@ u32 count_non_255_bytes(afl_state_t *afl, u8 *mem) { u32 i = (afl->fsrv.map_size >> 2); u32 ret = 0; - if (i == 0) i = 1; - while (i--) { u32 v = *(ptr++); @@ -246,8 +240,6 @@ void simplify_trace(afl_state_t *afl, u64 *mem) { u32 i = (afl->fsrv.map_size >> 3); - if (i == 0) i = 1; - while (i--) { /* Optimize for sparse bitmaps. */ @@ -281,8 +273,6 @@ void simplify_trace(afl_state_t *afl, u32 *mem) { u32 i = (afl->fsrv.map_size >> 2); - if (i == 0) i = 1; - while (i--) { /* Optimize for sparse bitmaps. */ @@ -347,8 +337,6 @@ void classify_counts(afl_forkserver_t *fsrv) { u32 i = (fsrv->map_size >> 3); - if (i == 0) i = 1; - while (i--) { /* Optimize for sparse bitmaps. */ @@ -378,8 +366,6 @@ void classify_counts(afl_forkserver_t *fsrv) { u32 i = (fsrv->map_size >> 2); - if (i == 0) i = 1; - while (i--) { /* Optimize for sparse bitmaps. */ diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 55f7ce53..3da348d2 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -442,23 +442,6 @@ void read_testcases(afl_state_t *afl) { } -/* Examine map coverage. Called once, for first test case. */ - -static void check_map_coverage(afl_state_t *afl) { - - u32 i; - - if (count_bytes(afl, afl->fsrv.trace_bits) < 100) return; - - for (i = (1 << (MAP_SIZE_POW2 - 1)); i < MAP_SIZE; ++i) - if (afl->fsrv.trace_bits[i]) return; - - if (afl->fsrv.map_size != MAP_SIZE) return; - - WARNF("Recompile binary with newer version of afl to improve coverage!"); - -} - /* Perform dry run of all test cases to confirm that the app is working as expected. This is done only for the initial inputs, and only once. */ @@ -501,8 +484,6 @@ void perform_dry_run(afl_state_t *afl) { case FSRV_RUN_OK: - if (q == afl->queue) check_map_coverage(afl); - if (afl->crash_mode) FATAL("Test case '%s' does *NOT* crash", fn); break; @@ -1419,6 +1400,8 @@ void setup_dirs_fds(afl_state_t *afl) { "# unix_time, cycles_done, cur_path, paths_total, " "pending_total, pending_favs, map_size, unique_crashes, " "unique_hangs, max_depth, execs_per_sec\n"); + fflush(afl->fsrv.plot_file); + /* ignore errors */ } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 33f01797..d4519c6d 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -42,7 +42,7 @@ it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */ &((py_mutator_t *)py_mutator)->name##_size static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf, - u8 *add_buf, size_t add_buf_size, size_t max_size) { + u8 *add_buf, size_t add_buf_size, size_t max_size) { size_t mutated_size; PyObject *py_args, *py_value; diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index d05eee08..373f12d8 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -249,7 +249,6 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { if (!q->trace_mini) { u32 len = (afl->fsrv.map_size >> 3); - if (len == 0) len = 1; q->trace_mini = ck_alloc(len); minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits); @@ -272,12 +271,12 @@ void cull_queue(afl_state_t *afl) { struct queue_entry *q; u32 len = (afl->fsrv.map_size >> 3); u32 i; - u8 temp_v[MAP_SIZE >> 3]; - - if (len == 0) len = 1; + u8 * temp_v; if (afl->dumb_mode || !afl->score_changed) return; + temp_v = ck_alloc(afl->fsrv.map_size >> 3); + afl->score_changed = 0; memset(temp_v, 255, len); @@ -325,6 +324,8 @@ void cull_queue(afl_state_t *afl) { } + ck_free(temp_v); + } /* Calculate case desirability score to adjust the length of havoc fuzzing. diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 6ad6444a..30ba0e65 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -34,7 +34,7 @@ information. The called program will update afl->fsrv->trace_bits. */ fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, - u32 timeout) { + u32 timeout) { fsrv_run_result_t res = afl_fsrv_run_target(fsrv, timeout, &afl->stop_soon); // TODO: Don't classify for faults? diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 7664c521..7d068258 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -99,7 +99,11 @@ void afl_state_init(afl_state_t *afl) { afl->fsrv.use_stdin = 1; - afl->fsrv.map_size = MAP_SIZE; + if (afl->afl_env.map_size > 8 && afl->afl_env.map_size <= (1 << 29)) + afl->fsrv.map_size = afl->afl_env.map_size; + else + afl->fsrv.map_size = MAP_SIZE; + afl->fsrv.function_opt = (u8 *)afl; afl->fsrv.function_ptr = &maybe_add_auto; @@ -324,6 +328,24 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_path = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_MAP_SIZE", + + afl_environment_variable_len) || + !strncmp(env, "AFL_MAPSIZE", + afl_environment_variable_len)) { + + afl->afl_env.map_size = + atoi((u8 *)get_afl_env(afl_environment_variables[i])); + + if (afl->afl_env.map_size < 8 || afl->afl_env.map_size > (1 << 29)) + FATAL( + "the specified AFL_MAP_SIZE size is illegal and must be " + "between 2^3 and 2^30: %u\n", + afl->afl_env.map_size); + + if (afl->afl_env.map_size % 8) + afl->afl_env.map_size = (((afl->afl_env.map_size >> 3) + 1) << 3); + } else if (!strncmp(env, "AFL_PRELOAD", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 7cc9b920..c507b7f7 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -145,14 +145,15 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability, void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) { - if (afl->plot_prev_qp == afl->queued_paths && - afl->plot_prev_pf == afl->pending_favored && - afl->plot_prev_pnf == afl->pending_not_fuzzed && - afl->plot_prev_ce == afl->current_entry && - afl->plot_prev_qc == afl->queue_cycle && - afl->plot_prev_uc == afl->unique_crashes && - afl->plot_prev_uh == afl->unique_hangs && - afl->plot_prev_md == afl->max_depth) + if (unlikely(afl->plot_prev_qp == afl->queued_paths && + afl->plot_prev_pf == afl->pending_favored && + afl->plot_prev_pnf == afl->pending_not_fuzzed && + afl->plot_prev_ce == afl->current_entry && + afl->plot_prev_qc == afl->queue_cycle && + afl->plot_prev_uc == afl->unique_crashes && + afl->plot_prev_uh == afl->unique_hangs && + afl->plot_prev_md == afl->max_depth) || + unlikely(!afl->queue_cycle)) return; afl->plot_prev_qp = afl->queued_paths; @@ -388,9 +389,9 @@ void show_stats(afl_state_t *afl) { /* Lord, forgive me this. */ - SAYF(SET_G1 bSTG bLT bH bSTOP cCYA + SAYF(SET_G1 bSTG bLT bH bSTOP cCYA " process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA - " overall results " bSTG bH2 bH2 bRT "\n"); + " overall results " bSTG bH2 bH2 bRT "\n"); if (afl->dumb_mode) { @@ -472,9 +473,9 @@ void show_stats(afl_state_t *afl) { " uniq hangs : " cRST "%-6s" bSTG bV "\n", time_tmp, tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA - " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); + " map coverage " bSTG bH bHT bH20 bH2 bVL "\n"); /* This gets funny because we want to print several variable-length variables together, but then cram them into a fixed-width field - so we need to @@ -504,9 +505,9 @@ void show_stats(afl_state_t *afl) { SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp); - SAYF(bVR bH bSTOP cCYA + SAYF(bVR bH bSTOP cCYA " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA - " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); + " findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n"); sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored), ((double)afl->queued_favored) * 100 / afl->queued_paths); @@ -580,7 +581,7 @@ void show_stats(afl_state_t *afl) { /* Aaaalmost there... hold on! */ - SAYF(bVR bH cCYA bSTOP + SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n"); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 925dbb1a..2a1387a9 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -150,44 +150,46 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) { if (more_help > 1) SAYF( "Environment variables used:\n" - "AFL_PATH: path to AFL support binaries\n" - "AFL_QUIET: suppress forkserver status messages\n" - "AFL_DEBUG_CHILD_OUTPUT: do not suppress stdout/stderr from target\n" "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n" + "ASAN_OPTIONS: custom settings for ASAN\n" + " (must contain abort_on_error=1 and symbolize=0)\n" + "MSAN_OPTIONS: custom settings for MSAN\n" + " (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n" + "AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists\n" "AFL_BENCH_JUST_ONE: run the target just once\n" - "AFL_DUMB_FORKSRV: use fork server without feedback from target\n" + "AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n" "AFL_CUSTOM_MUTATOR_LIBRARY: lib with afl_custom_fuzz() to mutate inputs\n" "AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators\n" - "AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n" "AFL_DEBUG: extra debugging output for Python mode trimming\n" + "AFL_DEBUG_CHILD_OUTPUT: do not suppress stdout/stderr from target\n" "AFL_DISABLE_TRIM: disable the trimming of test cases\n" - "AFL_NO_UI: switch status screen off\n" - "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n" - "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n" - "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" - "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n" - "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" - "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n" - "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n" + "AFL_DUMB_FORKSRV: use fork server without feedback from target\n" + "AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n" "AFL_FAST_CAL: limit the calibration stage to three cycles for speedup\n" + "AFL_FORCE_UI: force showing the status screen (for virtual consoles)\n" "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" - "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" - "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" + "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" + "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" + " the target was compiled for\n" "AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\n" + "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage\n" + "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage\n" + "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" + "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n" + "AFL_NO_UI: switch status screen off\n" + "AFL_PATH: path to AFL support binaries\n" "AFL_POST_LIBRARY: postprocess generated test cases before use as target input\n" - "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" - "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" - "ASAN_OPTIONS: custom settings for ASAN\n" - " (must contain abort_on_error=1 and symbolize=0)\n" - "MSAN_OPTIONS: custom settings for MSAN\n" - " (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n" + "AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module\n" + "AFL_QUIET: suppress forkserver status messages\n" + "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" + "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n" "AFL_SKIP_BIN_CHECK: skip the check, if the target is an excutable\n" + "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking\n" + "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs\n" + "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" //"AFL_PERSISTENT: not supported anymore -> no effect, just a warning\n" //"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n" - "AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found\n" - "AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found\n" - "AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists\n" "\n" ); else @@ -249,6 +251,7 @@ int main(int argc, char **argv_orig, char **envp) { if (get_afl_env("AFL_DEBUG")) afl->debug = 1; read_afl_environment(afl, envp); + if (afl->afl_env.map_size) afl->fsrv.map_size = afl->afl_env.map_size; exit_1 = !!afl->afl_env.afl_bench_just_one; SAYF(cCYA "afl-fuzz" VERSION cRST @@ -476,7 +479,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->in_bitmap) FATAL("Multiple -B options not supported"); afl->in_bitmap = optarg; - read_bitmap(afl->in_bitmap, afl->virgin_bits, MAP_SIZE); + read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size); break; case 'C': /* crash mode */ @@ -910,13 +913,14 @@ int main(int argc, char **argv_orig, char **envp) { check_crash_handling(); check_cpu_governor(afl); - afl->fsrv.trace_bits = afl_shm_init(&afl->shm, MAP_SIZE, afl->dumb_mode); + afl->fsrv.trace_bits = + afl_shm_init(&afl->shm, afl->fsrv.map_size, afl->dumb_mode); setup_post(afl); - if (!afl->in_bitmap) memset(afl->virgin_bits, 255, MAP_SIZE); - memset(afl->virgin_tmout, 255, MAP_SIZE); - memset(afl->virgin_crash, 255, MAP_SIZE); + if (!afl->in_bitmap) memset(afl->virgin_bits, 255, afl->fsrv.map_size); + memset(afl->virgin_tmout, 255, afl->fsrv.map_size); + memset(afl->virgin_crash, 255, afl->fsrv.map_size); init_count_class16(); diff --git a/src/afl-gcc.c b/src/afl-gcc.c index 32cd36cb..1ae10975 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -411,6 +411,15 @@ int main(int argc, char **argv) { } + u8 *ptr; + if (!be_quiet && + ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE")))) { + + u32 map_size = atoi(ptr); + if (map_size != MAP_SIZE) FATAL("AFL_MAP_SIZE is not supported by afl-gcc"); + + } + find_as(argv[0]); edit_params(argc, argv); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 61c1754f..a11c128a 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -72,6 +72,8 @@ static u32 total, highest; /* tuple content information */ static u32 in_len, /* Input data length */ arg_offset; /* Total number of execs */ +static u32 map_size = MAP_SIZE; + static u8 quiet_mode, /* Hide non-essential messages? */ edges_only, /* Ignore hit counts? */ raw_instr_output, /* Do not apply AFL filters */ @@ -112,7 +114,7 @@ static void classify_counts(afl_forkserver_t *fsrv) { u8 * mem = fsrv->trace_bits; const u8 *map = binary_mode ? count_class_binary : count_class_human; - u32 i = MAP_SIZE; + u32 i = map_size; if (edges_only) { @@ -175,10 +177,10 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { if (binary_mode) { - for (i = 0; i < MAP_SIZE; i++) + for (i = 0; i < map_size; i++) if (fsrv->trace_bits[i]) ret++; - ck_write(fd, fsrv->trace_bits, MAP_SIZE, outfile); + ck_write(fd, fsrv->trace_bits, map_size, outfile); close(fd); } else { @@ -187,7 +189,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { if (!f) PFATAL("fdopen() failed"); - for (i = 0; i < MAP_SIZE; i++) { + for (i = 0; i < map_size; i++) { if (!fsrv->trace_bits[i]) continue; ret++; @@ -218,8 +220,8 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { /* Execute target application. */ -static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem, - u32 len) { +static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv, + u8 *mem, u32 len) { afl_fsrv_write_to_testcase(fsrv, mem, len); @@ -513,14 +515,17 @@ static void usage(u8 *argv0) { "For additional help, consult %s/README.md.\n\n" "Environment variables used:\n" - "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" - "AFL_DEBUG: enable extra developer output\n" - "AFL_QUIET: do not print extra informational output" + "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n", "AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing " "inputs\n" "AFL_CMIN_ALLOW_ANY: (cmin_mode) write tuples for crashing inputs also\n" - "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n", - argv0, MEM_LIMIT, doc_path); + "AFL_DEBUG: enable extra developer output\n" + "AFL_MAP_SIZE: the shared memory size for that target. must be >= the " + "size\n" + " the target was compiled for\n" + "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" + "AFL_QUIET: do not print extra informational output" argv0, + MEM_LIMIT, doc_path); exit(1); @@ -535,7 +540,7 @@ int main(int argc, char **argv_orig, char **envp) { s32 opt, i; u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; u32 tcnt = 0; - char **use_argv; + char **use_argv, *ptr; char **argv = argv_cpy_dup(argc, argv_orig); @@ -543,6 +548,16 @@ int main(int argc, char **argv_orig, char **envp) { afl_forkserver_t *fsrv = &fsrv_var; afl_fsrv_init(fsrv); + if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { + + map_size = atoi(ptr); + if (map_size < 8 || map_size > (1 << 29)) + FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size); + if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3); + fsrv->map_size = map_size; + + } + doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; if (getenv("AFL_QUIET") != NULL) be_quiet = 1; @@ -715,7 +730,7 @@ int main(int argc, char **argv_orig, char **envp) { check_environment_vars(envp); sharedmem_t shm = {0}; - fsrv->trace_bits = afl_shm_init(&shm, MAP_SIZE, 0); + fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); setup_signal_handlers(); set_up_environment(fsrv); @@ -877,6 +892,7 @@ int main(int argc, char **argv_orig, char **envp) { if (stdin_file) ck_free(stdin_file); argv_cpy_free(argv); + if (fsrv->qemu_mode) free(use_argv[2]); exit(ret); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 431ff0c4..ad7d70c7 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -70,7 +70,8 @@ static u32 in_len, /* Input data length */ orig_cksum, /* Original checksum */ missed_hangs, /* Misses due to hangs */ missed_crashes, /* Misses due to crashes */ - missed_paths; /* Misses due to exec path diffs */ + missed_paths, /* Misses due to exec path diffs */ + map_size = MAP_SIZE; static u8 crash_mode, /* Crash-centric mode? */ hang_mode, /* Minimize as long as it hangs */ @@ -105,7 +106,7 @@ static const u8 count_class_lookup[256] = { static void apply_mask(u32 *mem, u32 *mask) { - u32 i = (MAP_SIZE >> 2); + u32 i = (map_size >> 2); if (!mask) return; @@ -122,7 +123,7 @@ static void apply_mask(u32 *mem, u32 *mask) { static void classify_counts(afl_forkserver_t *fsrv) { u8 *mem = fsrv->trace_bits; - u32 i = MAP_SIZE; + u32 i = map_size; if (edges_only) { @@ -151,7 +152,7 @@ static void classify_counts(afl_forkserver_t *fsrv) { static inline u8 anything_set(afl_forkserver_t *fsrv) { u32 *ptr = (u32 *)fsrv->trace_bits; - u32 i = (MAP_SIZE >> 2); + u32 i = (map_size >> 2); while (i--) if (*(ptr++)) return 1; @@ -215,7 +216,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) { 1 if they should be kept. */ static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, - u8 first_run) { + u8 first_run) { afl_fsrv_write_to_testcase(fsrv, mem, len); @@ -740,7 +741,9 @@ static void usage(u8 *argv0) { " (must contain abort_on_error=1 and symbolize=0)\n" "MSAN_OPTIONS: custom settings for MSAN\n" " (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n" - "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" + "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" + " the target was compiled for\n" + "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n" , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path); @@ -755,7 +758,7 @@ int main(int argc, char **argv_orig, char **envp) { s32 opt; u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; - char **use_argv; + char **use_argv, *ptr; char **argv = argv_cpy_dup(argc, argv_orig); @@ -763,6 +766,16 @@ int main(int argc, char **argv_orig, char **envp) { afl_forkserver_t *fsrv = &fsrv_var; afl_fsrv_init(fsrv); + if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) { + + map_size = atoi(ptr); + if (map_size < 8 || map_size > (1 << 29)) + FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size); + if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3); + fsrv->map_size = map_size; + + } + doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); @@ -910,8 +923,8 @@ int main(int argc, char **argv_orig, char **envp) { to be useful. */ if (mask_bitmap) FATAL("Multiple -B options not supported"); - mask_bitmap = ck_alloc(MAP_SIZE); - read_bitmap(optarg, mask_bitmap, MAP_SIZE); + mask_bitmap = ck_alloc(map_size); + read_bitmap(optarg, mask_bitmap, map_size); break; case 'h': @@ -928,7 +941,7 @@ int main(int argc, char **argv_orig, char **envp) { check_environment_vars(envp); sharedmem_t shm = {0}; - fsrv->trace_bits = afl_shm_init(&shm, MAP_SIZE, 0); + fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); atexit(at_exit_handler); setup_signal_handlers(); |