Merge branch 'dev' of github.com:aflplusplus/aflplusplus into dev

This commit is contained in:
Dominik Maier
2020-04-17 11:01:20 +02:00
24 changed files with 328 additions and 175 deletions

View File

@ -19,14 +19,18 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- snapshot feature usage now visible in UI - snapshot feature usage now visible in UI
- Now setting "-L -1" will enable MOpt in parallel to normal mutation. - Now setting "-L -1" will enable MOpt in parallel to normal mutation.
Additionally this allows to run dictionaries, radamsa and cmplog. 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 - compare-transform/AFL_LLVM_LAF_TRANSFORM_COMPARES now transforms also
static global and local variable comparisons (cannot find all though) static global and local variable comparisons (cannot find all though)
- extended forkserver: map_size and more information is communicated to - extended forkserver: map_size and more information is communicated to
afl-fuzz (and afl-fuzz acts accordingly) 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 - if AFL_CC/AFL_CXX is set but empty afl compilers did fail, fixed
(this bug is in vanilla afl too) (this bug is in vanilla afl too)
- added NO_PYTHON flag to disable python support when building afl-fuzz - added NO_PYTHON flag to disable python support when building afl-fuzz
- more refactoring
### Version ++2.63c (release): ### Version ++2.63c (release):

View File

@ -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 normally indicated by the cycle counter in the UI turning green. May be
convenient for some types of automated jobs. 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 - 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 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). of afl-fuzz than would be prudent (if you really want to).

View File

@ -364,6 +364,16 @@ int main(int argc, char **argv, char **envp) {
be_quiet = 1; 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); check_environment_vars(envp);
find_obj(argv[0]); find_obj(argv[0]);

View File

@ -325,6 +325,8 @@ typedef struct afl_env_vars {
*afl_python_module, *afl_path, *afl_hang_tmout, *afl_skip_crashes, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_skip_crashes,
*afl_preload; *afl_preload;
uint32_t map_size;
} afl_env_vars_t; } afl_env_vars_t;
struct afl_pass_stat { struct afl_pass_stat {

View File

@ -407,8 +407,7 @@
#define FS_OPT_SNAPSHOT 0x20000000 #define FS_OPT_SNAPSHOT 0x20000000
#define FS_OPT_AUTODICT 0x10000000 #define FS_OPT_AUTODICT 0x10000000
#define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1) #define FS_OPT_GET_MAPSIZE(x) (((x & 0x00fffffe) >> 1) + 1)
#define FS_OPT_SET_MAPSIZE(x) \ #define FS_OPT_SET_MAPSIZE(x) (x <= 1 || x > 0x1000000 ? 0 : ((x - 1) << 1))
(x <= 1 || x > MAP_SIZE || x > 0x1000000 ? 0 : ((x - 1) << 1))
#endif /* ! _HAVE_CONFIG_H */ #endif /* ! _HAVE_CONFIG_H */

View File

@ -61,7 +61,7 @@ typedef struct afl_forkserver {
u64 total_execs; /* How often run_target was called */ u64 total_execs; /* How often run_target was called */
u8 *out_file, /* File to fuzz, if any */ 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 */ FILE *plot_file; /* Gnuplot output file */

View File

@ -716,30 +716,30 @@ int main(int argc, char **argv, char **envp) {
"Environment variables used:\n" "Environment variables used:\n"
"AFL_CC: path to the C compiler to use\n" "AFL_CC: path to the C compiler to use\n"
"AFL_CXX: 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_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_HARDEN: adds code hardening to catch memory bugs\n"
"AFL_USE_ASAN: activate address sanitizer\n" "AFL_INST_RATIO: percentage of branches to instrument\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_LLVM_NOT_ZERO: use cycling trace counters that skip zero\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_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 " "AFL_LLVM_LAF_SPLIT_FLOATS: transform floating point comp. to "
"cascaded " "cascaded "
"comp.\n" "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); callname, BIN_PATH, BIN_PATH);
SAYF( 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_CMPLOG: log operands of comparisons (RedQueen mutator)\n"
"AFL_LLVM_INSTRUMENT: set instrumentation mode: DEFAULT, CFG " "AFL_LLVM_INSTRUMENT: set instrumentation mode: DEFAULT, CFG "
"(INSTRIM), LTO, CTX, NGRAM-2 ... NGRAM-16\n" "(INSTRIM), LTO, CTX, NGRAM-2 ... NGRAM-16\n"
"You can also use the old environment variables:" " You can also use the old environment variables instead:"
"AFL_LLVM_CTX: use context sensitive coverage\n" " AFL_LLVM_CTX: use context sensitive coverage\n"
"AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\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_NGRAM_SIZE: use ngram prev_loc count coverage\n"
"AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n"
"AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed (sub " " AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed (sub "
"option to INSTRIM)\n"); "option to INSTRIM)\n");
#ifdef AFL_CLANG_FLTO #ifdef AFL_CLANG_FLTO
SAYF( SAYF(
"\nafl-clang-lto specific environment variables:\n" "\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 " "AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a "
"global var\n" "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" "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 " "\nafl-clang-lto was built with linker target \"%s\" and LTO flags "
"\"%s\"\n" "\"%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) { if (debug) {
SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd()); SAYF(cMGN "[D]" cRST " cd \"%s\";", getthecwd());

View File

@ -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; // save highest location ID to global variable
while ((map = map >> 1)) // do this after each function to fail faster
pow2map++; if (!be_quiet && afl_global_id > MAP_SIZE) {
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);
} 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) { if (!f) {
fprintf(stderr, fprintf(stderr,
"Error: init function could not be found (this hould not " "Error: init function could not be found (this should not "
"happen)\n"); "happen)\n");
exit(-1); exit(-1);

View File

@ -125,6 +125,7 @@ class AFLCoverage : public ModulePass {
std::list<std::string> myWhitelist; std::list<std::string> myWhitelist;
uint32_t ngram_size = 0; uint32_t ngram_size = 0;
uint32_t debug = 0; uint32_t debug = 0;
uint32_t map_size = MAP_SIZE;
char * ctx_str = NULL; char * ctx_str = NULL;
}; };
@ -192,6 +193,19 @@ bool AFLCoverage::runOnModule(Module &M) {
be_quiet = 1; 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 */ /* Decide instrumentation ratio */
char * inst_ratio_str = getenv("AFL_INST_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 yes we store a context ID for this function in the global var
if (has_calls) { 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); StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext);
StoreCtx->setMetadata(M.getMDKindID("nosanitize"), StoreCtx->setMetadata(M.getMDKindID("nosanitize"),
MDNode::get(C, None)); MDNode::get(C, None));
@ -509,7 +523,7 @@ bool AFLCoverage::runOnModule(Module &M) {
/* Make up cur_loc */ /* Make up cur_loc */
// 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). /* 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 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. */ /* Say something nice. */
if (!be_quiet) { if (!be_quiet) {

View File

@ -233,6 +233,7 @@ if [ "$ORIG_CPU_TARGET" = "" ]; then
gcc test-instr.c -o test-instr || exit 1 gcc test-instr.c -o test-instr || exit 1
unset AFL_INST_RATIO unset AFL_INST_RATIO
export ASAN_OPTIONS=detect_leaks=0
echo "[*] Comparing two afl-showmap -Q outputs..." echo "[*] Comparing two afl-showmap -Q outputs..."
echo 0 | ./afl-showmap -m none -Q -q -o .test-instr0 ./test-instr || exit 1 echo 0 | ./afl-showmap -m none -Q -q -o .test-instr0 ./test-instr || exit 1

View File

@ -84,6 +84,7 @@ static volatile u8 stop_soon, /* Ctrl-C pressed? */
static u8 *target_path; static u8 *target_path;
static u8 qemu_mode; static u8 qemu_mode;
static u32 map_size = MAP_SIZE;
/* Constants used for describing byte behavior. */ /* Constants used for describing byte behavior. */
@ -115,7 +116,7 @@ static u8 count_class_lookup[256] = {
static void classify_counts(u8 *mem) { static void classify_counts(u8 *mem) {
u32 i = MAP_SIZE; u32 i = map_size;
if (edges_only) { if (edges_only) {
@ -144,7 +145,7 @@ static void classify_counts(u8 *mem) {
static inline u8 anything_set(void) { static inline u8 anything_set(void) {
u32 *ptr = (u32 *)trace_bits; u32 *ptr = (u32 *)trace_bits;
u32 i = (MAP_SIZE >> 2); u32 i = (map_size >> 2);
while (i--) while (i--)
if (*(ptr++)) return 1; 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; s32 prog_in_fd;
u32 cksum; u32 cksum;
memset(trace_bits, 0, MAP_SIZE); memset(trace_bits, 0, map_size);
MEM_BARRIER(); MEM_BARRIER();
prog_in_fd = write_to_file(prog_in, mem, len); 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, /* We don't actually care if the target is crashing or not,
except that when it does, the checksum should be different. */ 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" " (must contain abort_on_error=1 and symbolize=0)\n"
"MSAN_OPTIONS: custom settings for MSAN\n" "MSAN_OPTIONS: custom settings for MSAN\n"
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\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_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" "AFL_SKIP_BIN_CHECK: skip checking the location of and the target\n"
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path); , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
@ -811,7 +814,7 @@ int main(int argc, char **argv, char **envp) {
s32 opt; s32 opt;
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; 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; 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 (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"); use_hex_offsets = !!get_afl_env("AFL_ANALYZE_HEX");
check_environment_vars(envp); check_environment_vars(envp);
sharedmem_t shm = {0}; 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); atexit(at_exit_handler);
setup_signal_handlers(); setup_signal_handlers();

View File

@ -72,7 +72,7 @@ char *afl_environment_variables[] = {
"AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN", "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN",
"AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI", "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_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_PERSISTENT", // not implemented anymore, so warn additionally
"AFL_POST_LIBRARY", "AFL_PRELOAD", "AFL_PYTHON_MODULE", "AFL_QEMU_COMPCOV", "AFL_POST_LIBRARY", "AFL_PRELOAD", "AFL_PYTHON_MODULE", "AFL_QEMU_COMPCOV",
"AFL_QEMU_COMPCOV_DEBUG", "AFL_QEMU_DEBUG_MAPS", "AFL_QEMU_DISABLE_CACHE", "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); target_path = ck_strdup(fname);
if (stat(target_path, &st) || !S_ISREG(st.st_mode) || 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); FATAL("Program '%s' not found or not executable", fname);
}
} else { } else {
while (env_path) { while (env_path) {

View File

@ -407,21 +407,26 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) { if ((status & FS_OPT_MAPSIZE) == FS_OPT_MAPSIZE) {
fsrv->map_size = FS_OPT_GET_MAPSIZE(status); u32 tmp_map_size = FS_OPT_GET_MAPSIZE(status);
if (unlikely(fsrv->map_size % 8)) {
if (!fsrv->map_size) fsrv->map_size = MAP_SIZE;
if (unlikely(tmp_map_size % 8)) {
// should not happen // should not happen
WARNF("Target reported non-aligned map size of %ud", fsrv->map_size); WARNF("Target reported non-aligned map size of %ud", tmp_map_size);
fsrv->map_size = (((fsrv->map_size + 8) >> 3) << 3); tmp_map_size = (((tmp_map_size + 8) >> 3) << 3);
} }
if (!be_quiet) ACTF("Target map size: %u", fsrv->map_size); if (!be_quiet) ACTF("Target map size: %u", tmp_map_size);
if (fsrv->map_size > MAP_SIZE) if (tmp_map_size > fsrv->map_size)
FATAL( FATAL(
"Target's coverage map size of %u is larger than the one this " "Target's coverage map size of %u is larger than the one this "
"afl++ is compiled with (%u) (change MAP_SIZE and recompile)\n", "afl++ is set with (%u) (change MAP_SIZE_POW2 in config.h and "
fsrv->map_size, MAP_SIZE); "recompile or set AFL_MAP_SIZE)\n",
tmp_map_size, fsrv->map_size);
fsrv->map_size = tmp_map_size;
} }

View File

@ -43,7 +43,7 @@ void write_bitmap(afl_state_t *afl) {
if (fd < 0) PFATAL("Unable to open '%s'", fname); 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); close(fd);
@ -145,8 +145,6 @@ u32 count_bits(afl_state_t *afl, u8 *mem) {
u32 i = (afl->fsrv.map_size >> 2); u32 i = (afl->fsrv.map_size >> 2);
u32 ret = 0; u32 ret = 0;
if (i == 0) i = 1;
while (i--) { while (i--) {
u32 v = *(ptr++); u32 v = *(ptr++);
@ -181,8 +179,6 @@ u32 count_bytes(afl_state_t *afl, u8 *mem) {
u32 i = (afl->fsrv.map_size >> 2); u32 i = (afl->fsrv.map_size >> 2);
u32 ret = 0; u32 ret = 0;
if (i == 0) i = 1;
while (i--) { while (i--) {
u32 v = *(ptr++); 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 i = (afl->fsrv.map_size >> 2);
u32 ret = 0; u32 ret = 0;
if (i == 0) i = 1;
while (i--) { while (i--) {
u32 v = *(ptr++); u32 v = *(ptr++);
@ -246,8 +240,6 @@ void simplify_trace(afl_state_t *afl, u64 *mem) {
u32 i = (afl->fsrv.map_size >> 3); u32 i = (afl->fsrv.map_size >> 3);
if (i == 0) i = 1;
while (i--) { while (i--) {
/* Optimize for sparse bitmaps. */ /* Optimize for sparse bitmaps. */
@ -281,8 +273,6 @@ void simplify_trace(afl_state_t *afl, u32 *mem) {
u32 i = (afl->fsrv.map_size >> 2); u32 i = (afl->fsrv.map_size >> 2);
if (i == 0) i = 1;
while (i--) { while (i--) {
/* Optimize for sparse bitmaps. */ /* Optimize for sparse bitmaps. */
@ -347,8 +337,6 @@ void classify_counts(afl_forkserver_t *fsrv) {
u32 i = (fsrv->map_size >> 3); u32 i = (fsrv->map_size >> 3);
if (i == 0) i = 1;
while (i--) { while (i--) {
/* Optimize for sparse bitmaps. */ /* Optimize for sparse bitmaps. */
@ -378,8 +366,6 @@ void classify_counts(afl_forkserver_t *fsrv) {
u32 i = (fsrv->map_size >> 2); u32 i = (fsrv->map_size >> 2);
if (i == 0) i = 1;
while (i--) { while (i--) {
/* Optimize for sparse bitmaps. */ /* Optimize for sparse bitmaps. */

View File

@ -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 /* 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. */ 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: case FSRV_RUN_OK:
if (q == afl->queue) check_map_coverage(afl);
if (afl->crash_mode) FATAL("Test case '%s' does *NOT* crash", fn); if (afl->crash_mode) FATAL("Test case '%s' does *NOT* crash", fn);
break; break;
@ -1419,6 +1400,8 @@ void setup_dirs_fds(afl_state_t *afl) {
"# unix_time, cycles_done, cur_path, paths_total, " "# unix_time, cycles_done, cur_path, paths_total, "
"pending_total, pending_favs, map_size, unique_crashes, " "pending_total, pending_favs, map_size, unique_crashes, "
"unique_hangs, max_depth, execs_per_sec\n"); "unique_hangs, max_depth, execs_per_sec\n");
fflush(afl->fsrv.plot_file);
/* ignore errors */ /* ignore errors */
} }

View File

@ -42,7 +42,7 @@ it just fills in `&py_mutator->something_buf, &py_mutator->something_size`. */
&((py_mutator_t *)py_mutator)->name##_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, 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; size_t mutated_size;
PyObject *py_args, *py_value; PyObject *py_args, *py_value;

View File

@ -249,7 +249,6 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
if (!q->trace_mini) { if (!q->trace_mini) {
u32 len = (afl->fsrv.map_size >> 3); u32 len = (afl->fsrv.map_size >> 3);
if (len == 0) len = 1;
q->trace_mini = ck_alloc(len); q->trace_mini = ck_alloc(len);
minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits); 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; struct queue_entry *q;
u32 len = (afl->fsrv.map_size >> 3); u32 len = (afl->fsrv.map_size >> 3);
u32 i; u32 i;
u8 temp_v[MAP_SIZE >> 3]; u8 * temp_v;
if (len == 0) len = 1;
if (afl->dumb_mode || !afl->score_changed) return; if (afl->dumb_mode || !afl->score_changed) return;
temp_v = ck_alloc(afl->fsrv.map_size >> 3);
afl->score_changed = 0; afl->score_changed = 0;
memset(temp_v, 255, len); 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. /* Calculate case desirability score to adjust the length of havoc fuzzing.

View File

@ -34,7 +34,7 @@
information. The called program will update afl->fsrv->trace_bits. */ 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, 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); fsrv_run_result_t res = afl_fsrv_run_target(fsrv, timeout, &afl->stop_soon);
// TODO: Don't classify for faults? // TODO: Don't classify for faults?

View File

@ -99,7 +99,11 @@ void afl_state_init(afl_state_t *afl) {
afl->fsrv.use_stdin = 1; 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_opt = (u8 *)afl;
afl->fsrv.function_ptr = &maybe_add_auto; 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 = afl->afl_env.afl_path =
(u8 *)get_afl_env(afl_environment_variables[i]); (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", } else if (!strncmp(env, "AFL_PRELOAD",
afl_environment_variable_len)) { afl_environment_variable_len)) {

View File

@ -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) { void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
if (afl->plot_prev_qp == afl->queued_paths && if (unlikely(afl->plot_prev_qp == afl->queued_paths &&
afl->plot_prev_pf == afl->pending_favored && afl->plot_prev_pf == afl->pending_favored &&
afl->plot_prev_pnf == afl->pending_not_fuzzed && afl->plot_prev_pnf == afl->pending_not_fuzzed &&
afl->plot_prev_ce == afl->current_entry && afl->plot_prev_ce == afl->current_entry &&
afl->plot_prev_qc == afl->queue_cycle && afl->plot_prev_qc == afl->queue_cycle &&
afl->plot_prev_uc == afl->unique_crashes && afl->plot_prev_uc == afl->unique_crashes &&
afl->plot_prev_uh == afl->unique_hangs && afl->plot_prev_uh == afl->unique_hangs &&
afl->plot_prev_md == afl->max_depth) afl->plot_prev_md == afl->max_depth) ||
unlikely(!afl->queue_cycle))
return; return;
afl->plot_prev_qp = afl->queued_paths; afl->plot_prev_qp = afl->queued_paths;
@ -388,9 +389,9 @@ void show_stats(afl_state_t *afl) {
/* Lord, forgive me this. */ /* 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 " 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) { if (afl->dumb_mode) {
@ -472,9 +473,9 @@ void show_stats(afl_state_t *afl) {
" uniq hangs : " cRST "%-6s" bSTG bV "\n", " uniq hangs : " cRST "%-6s" bSTG bV "\n",
time_tmp, tmp); time_tmp, tmp);
SAYF(bVR bH bSTOP cCYA SAYF(bVR bH bSTOP cCYA
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB 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 /* 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 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(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 " 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), sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
((double)afl->queued_favored) * 100 / afl->queued_paths); ((double)afl->queued_favored) * 100 / afl->queued_paths);
@ -580,7 +581,7 @@ void show_stats(afl_state_t *afl) {
/* Aaaalmost there... hold on! */ /* 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 " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
" path geometry " bSTG bH5 bH2 bVL "\n"); " path geometry " bSTG bH5 bH2 bVL "\n");

View File

@ -150,44 +150,46 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
if (more_help > 1) if (more_help > 1)
SAYF( SAYF(
"Environment variables used:\n" "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" "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n"
"AFL_BENCH_JUST_ONE: run the target just once\n"
"AFL_DUMB_FORKSRV: use fork server without feedback from target\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_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_FAST_CAL: limit the calibration stage to three cycles for speedup\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_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
"AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing\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" "ASAN_OPTIONS: custom settings for ASAN\n"
" (must contain abort_on_error=1 and symbolize=0)\n" " (must contain abort_on_error=1 and symbolize=0)\n"
"MSAN_OPTIONS: custom settings for MSAN\n" "MSAN_OPTIONS: custom settings for MSAN\n"
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\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_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_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_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_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_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_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_PERSISTENT: not supported anymore -> no effect, just a warning\n"
//"AFL_DEFER_FORKSRV: 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" "\n"
); );
else else
@ -249,6 +251,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (get_afl_env("AFL_DEBUG")) afl->debug = 1; if (get_afl_env("AFL_DEBUG")) afl->debug = 1;
read_afl_environment(afl, envp); 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; exit_1 = !!afl->afl_env.afl_bench_just_one;
SAYF(cCYA "afl-fuzz" VERSION cRST 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"); if (afl->in_bitmap) FATAL("Multiple -B options not supported");
afl->in_bitmap = optarg; 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; break;
case 'C': /* crash mode */ case 'C': /* crash mode */
@ -910,13 +913,14 @@ int main(int argc, char **argv_orig, char **envp) {
check_crash_handling(); check_crash_handling();
check_cpu_governor(afl); 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); setup_post(afl);
if (!afl->in_bitmap) memset(afl->virgin_bits, 255, MAP_SIZE); if (!afl->in_bitmap) memset(afl->virgin_bits, 255, afl->fsrv.map_size);
memset(afl->virgin_tmout, 255, MAP_SIZE); memset(afl->virgin_tmout, 255, afl->fsrv.map_size);
memset(afl->virgin_crash, 255, MAP_SIZE); memset(afl->virgin_crash, 255, afl->fsrv.map_size);
init_count_class16(); init_count_class16();

View File

@ -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]); find_as(argv[0]);
edit_params(argc, argv); edit_params(argc, argv);

View File

@ -72,6 +72,8 @@ static u32 total, highest; /* tuple content information */
static u32 in_len, /* Input data length */ static u32 in_len, /* Input data length */
arg_offset; /* Total number of execs */ arg_offset; /* Total number of execs */
static u32 map_size = MAP_SIZE;
static u8 quiet_mode, /* Hide non-essential messages? */ static u8 quiet_mode, /* Hide non-essential messages? */
edges_only, /* Ignore hit counts? */ edges_only, /* Ignore hit counts? */
raw_instr_output, /* Do not apply AFL filters */ 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; u8 * mem = fsrv->trace_bits;
const u8 *map = binary_mode ? count_class_binary : count_class_human; const u8 *map = binary_mode ? count_class_binary : count_class_human;
u32 i = MAP_SIZE; u32 i = map_size;
if (edges_only) { if (edges_only) {
@ -175,10 +177,10 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
if (binary_mode) { if (binary_mode) {
for (i = 0; i < MAP_SIZE; i++) for (i = 0; i < map_size; i++)
if (fsrv->trace_bits[i]) ret++; 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); close(fd);
} else { } else {
@ -187,7 +189,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
if (!f) PFATAL("fdopen() failed"); 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; if (!fsrv->trace_bits[i]) continue;
ret++; ret++;
@ -218,8 +220,8 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
/* Execute target application. */ /* Execute target application. */
static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv, u8 *mem, static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, char **argv,
u32 len) { u8 *mem, u32 len) {
afl_fsrv_write_to_testcase(fsrv, mem, 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" "For additional help, consult %s/README.md.\n\n"
"Environment variables used:\n" "Environment variables used:\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n",
"AFL_DEBUG: enable extra developer output\n"
"AFL_QUIET: do not print extra informational output"
"AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing " "AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing "
"inputs\n" "inputs\n"
"AFL_CMIN_ALLOW_ANY: (cmin_mode) write tuples for crashing inputs also\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", "AFL_DEBUG: enable extra developer output\n"
argv0, MEM_LIMIT, doc_path); "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); exit(1);
@ -535,7 +540,7 @@ int main(int argc, char **argv_orig, char **envp) {
s32 opt, i; s32 opt, i;
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0;
u32 tcnt = 0; u32 tcnt = 0;
char **use_argv; char **use_argv, *ptr;
char **argv = argv_cpy_dup(argc, argv_orig); 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_forkserver_t *fsrv = &fsrv_var;
afl_fsrv_init(fsrv); 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; doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
if (getenv("AFL_QUIET") != NULL) be_quiet = 1; 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); check_environment_vars(envp);
sharedmem_t shm = {0}; 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(); setup_signal_handlers();
set_up_environment(fsrv); set_up_environment(fsrv);
@ -877,6 +892,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (stdin_file) ck_free(stdin_file); if (stdin_file) ck_free(stdin_file);
argv_cpy_free(argv); argv_cpy_free(argv);
if (fsrv->qemu_mode) free(use_argv[2]);
exit(ret); exit(ret);

View File

@ -70,7 +70,8 @@ static u32 in_len, /* Input data length */
orig_cksum, /* Original checksum */ orig_cksum, /* Original checksum */
missed_hangs, /* Misses due to hangs */ missed_hangs, /* Misses due to hangs */
missed_crashes, /* Misses due to crashes */ 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? */ static u8 crash_mode, /* Crash-centric mode? */
hang_mode, /* Minimize as long as it hangs */ 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) { static void apply_mask(u32 *mem, u32 *mask) {
u32 i = (MAP_SIZE >> 2); u32 i = (map_size >> 2);
if (!mask) return; if (!mask) return;
@ -122,7 +123,7 @@ static void apply_mask(u32 *mem, u32 *mask) {
static void classify_counts(afl_forkserver_t *fsrv) { static void classify_counts(afl_forkserver_t *fsrv) {
u8 *mem = fsrv->trace_bits; u8 *mem = fsrv->trace_bits;
u32 i = MAP_SIZE; u32 i = map_size;
if (edges_only) { if (edges_only) {
@ -151,7 +152,7 @@ static void classify_counts(afl_forkserver_t *fsrv) {
static inline u8 anything_set(afl_forkserver_t *fsrv) { static inline u8 anything_set(afl_forkserver_t *fsrv) {
u32 *ptr = (u32 *)fsrv->trace_bits; u32 *ptr = (u32 *)fsrv->trace_bits;
u32 i = (MAP_SIZE >> 2); u32 i = (map_size >> 2);
while (i--) while (i--)
if (*(ptr++)) return 1; 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. */ 1 if they should be kept. */
static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len, 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); 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" " (must contain abort_on_error=1 and symbolize=0)\n"
"MSAN_OPTIONS: custom settings for MSAN\n" "MSAN_OPTIONS: custom settings for MSAN\n"
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\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" "AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n"
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path); , argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
@ -755,7 +758,7 @@ int main(int argc, char **argv_orig, char **envp) {
s32 opt; s32 opt;
u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0; 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); 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_forkserver_t *fsrv = &fsrv_var;
afl_fsrv_init(fsrv); 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; doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); 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. */ to be useful. */
if (mask_bitmap) FATAL("Multiple -B options not supported"); if (mask_bitmap) FATAL("Multiple -B options not supported");
mask_bitmap = ck_alloc(MAP_SIZE); mask_bitmap = ck_alloc(map_size);
read_bitmap(optarg, mask_bitmap, MAP_SIZE); read_bitmap(optarg, mask_bitmap, map_size);
break; break;
case 'h': case 'h':
@ -928,7 +941,7 @@ int main(int argc, char **argv_orig, char **envp) {
check_environment_vars(envp); check_environment_vars(envp);
sharedmem_t shm = {0}; 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); atexit(at_exit_handler);
setup_signal_handlers(); setup_signal_handlers();