diff options
-rwxr-xr-x | afl-cmin | 1 | ||||
-rw-r--r-- | docs/Changelog.md | 2 | ||||
-rw-r--r-- | docs/env_variables.md | 4 | ||||
-rw-r--r-- | src/afl-forkserver.c | 45 | ||||
-rw-r--r-- | src/afl-fuzz.c | 30 | ||||
-rw-r--r-- | src/afl-showmap.c | 37 | ||||
-rw-r--r-- | src/afl-tmin.c | 29 |
7 files changed, 104 insertions, 44 deletions
diff --git a/afl-cmin b/afl-cmin index eef2b7ef..726e90ab 100755 --- a/afl-cmin +++ b/afl-cmin @@ -120,6 +120,7 @@ function usage() { "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" \ "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the target to come up, initially\n" \ "AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \ +"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n" "AFL_PATH: path for the afl-showmap binary if not found anywhere else\n" \ "AFL_SKIP_BIN_CHECK: skip check for target binary\n" exit 1 diff --git a/docs/Changelog.md b/docs/Changelog.md index 03b8e036..81ac91b0 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -32,7 +32,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>. already building with all cores, the gcc plugin needs only one. - added dummy Makefile to instrumentation/ - Updated utils/afl_frida to be 5% faster - + - Added AFL_KILL_SIGNAL env variable for custom targets (thanks @v-p-b) ### Version ++3.00c (release) - llvm_mode/ and gcc_plugin/ moved to instrumentation/ diff --git a/docs/env_variables.md b/docs/env_variables.md index e6b9381b..26128b01 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -350,6 +350,10 @@ checks or alter some of the more exotic semantics of the tool: - Note that `AFL_POST_LIBRARY` is deprecated, use `AFL_CUSTOM_MUTATOR_LIBRARY` instead (see below). + - `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes on timeout. + Unless you implement your own targets or instrumentation, you likely don't have to set it. + By default, on timeout and on exit, `SIGKILL` (`AFL_KILL_SIGNAL=9`) will be delivered to the child. + - Setting `AFL_CUSTOM_MUTATOR_LIBRARY` to a shared library with afl_custom_fuzz() creates additional mutations through this library. If afl-fuzz is compiled with Python (which is autodetected during builing diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 70fb9572..b7aa87f8 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -84,6 +84,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->init_tmout = EXEC_TIMEOUT * FORK_WAIT_MULT; fsrv->mem_limit = MEM_LIMIT; fsrv->out_file = NULL; + fsrv->kill_signal = SIGKILL; /* exec related stuff */ fsrv->child_pid = -1; @@ -95,30 +96,6 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->uses_asan = false; fsrv->init_child_func = fsrv_exec_child; - fsrv->kill_signal = SIGKILL; - - char *kill_signal_env = get_afl_env("AFL_KILL_SIGNAL"); - if (kill_signal_env) { - - char *endptr; - u8 signal_code; - signal_code = (u8)strtoul(kill_signal_env, &endptr, 10); - /* Did we manage to parse the full string? */ - if (*endptr != '\0' || endptr == kill_signal_env) { - - FATAL("Invalid kill signal value!"); - - } - - fsrv->kill_signal = signal_code; - - } else { - - /* Using hardcoded code for SIGKILL for the sake of simplicity */ - setenv("AFL_KILL_SIGNAL", "9", 1); - - } - list_append(&fsrv_list, fsrv); } @@ -139,6 +116,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->no_unlink = from->no_unlink; fsrv_to->uses_crash_exitcode = from->uses_crash_exitcode; fsrv_to->crash_exitcode = from->crash_exitcode; + fsrv_to->kill_signal = from->kill_signal; // These are forkserver specific. fsrv_to->out_dir_fd = -1; @@ -149,8 +127,6 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->init_child_func = from->init_child_func; // Note: do not copy ->add_extra_func - fsrv_to->kill_signal = from->kill_signal; - list_append(&fsrv_list, fsrv_to); } @@ -1162,25 +1138,18 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, /* Report outcome to caller. */ - /* TODO We use SIGTERM here as an indicator of Xen mode, - although it's not equivalent! */ - if (fsrv->kill_signal == SIGTERM && !*stop_soon_p && - fsrv->last_run_timed_out) { + /* Did we timeout? */ + if (unlikely(fsrv->last_run_timed_out)) { + fsrv->last_kill_signal = fsrv->kill_signal; return FSRV_RUN_TMOUT; } - if (WIFSIGNALED(fsrv->child_status) && !*stop_soon_p) { + /* Did we crash? */ + if (unlikely(WIFSIGNALED(fsrv->child_status) && !*stop_soon_p)) { fsrv->last_kill_signal = WTERMSIG(fsrv->child_status); - - if (fsrv->last_run_timed_out && fsrv->last_kill_signal == SIGKILL) { - - return FSRV_RUN_TMOUT; - - } - return FSRV_RUN_CRASH; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 00625f2e..5c363c63 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -194,10 +194,11 @@ static void usage(u8 *argv0, int more_help) { "AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60 minutes and a cycle without finds)\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_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\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_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n" "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n" " the target was compiled for\n" "AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value\n" @@ -986,6 +987,33 @@ int main(int argc, char **argv_orig, char **envp) { #endif + afl->fsrv.kill_signal = SIGKILL; + if (afl->afl_env.afl_kill_signal) { + + char *endptr; + u8 signal_code; + signal_code = (u8)strtoul(afl->afl_env.afl_kill_signal, &endptr, 10); + /* Did we manage to parse the full string? */ + if (*endptr != '\0' || endptr == (char *)afl->afl_env.afl_kill_signal) { + + FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", + afl->afl_env.afl_kill_signal); + + } + + afl->fsrv.kill_signal = signal_code; + + } else { + + char *sigstr = alloc_printf("%d", (int)SIGKILL); + if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } + + /* Set the env for signal handler */ + setenv("AFL_KILL_SIGNAL", sigstr, 1); + free(sigstr); + + } + setup_signal_handlers(); check_asan_opts(afl); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index d50601fc..2c9c38ed 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -693,12 +693,13 @@ static void usage(u8 *argv0) { "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as " "crash\n" "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_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during " "startup (in milliseconds)\n" + "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, " + "etc. (default: SIGKILL)\n" + "AFL_MAP_SIZE: the shared memory size for that target. must be >= the " + "size 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\n", argv0, MEM_LIMIT, doc_path); @@ -1115,6 +1116,34 @@ int main(int argc, char **argv_orig, char **envp) { } + fsrv->kill_signal = SIGKILL; + char *afl_kill_signal_env = getenv("AFL_KILL_SIGNAL"); + if (afl_kill_signal_env && afl_kill_signal_env[0]) { + + char *endptr; + u8 signal_code; + signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10); + /* Did we manage to parse the full string? */ + if (*endptr != '\0' || endptr == afl_kill_signal_env) { + + FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", + afl_kill_signal_env); + + } + + fsrv->kill_signal = signal_code; + + } else { + + char *sigstr = alloc_printf("%d", (int)SIGKILL); + if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } + + /* Set the env for signal handler */ + setenv("AFL_KILL_SIGNAL", sigstr, 1); + free(sigstr); + + } + if (getenv("AFL_CRASH_EXITCODE")) { long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 09d97f58..342de9c8 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -855,6 +855,7 @@ static void usage(u8 *argv0) { "Environment variables used:\n" "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)\n" + "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\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" @@ -1134,6 +1135,34 @@ int main(int argc, char **argv_orig, char **envp) { } + fsrv->kill_signal = SIGKILL; + char *afl_kill_signal_env = getenv("AFL_KILL_SIGNAL"); + if (afl_kill_signal_env && afl_kill_signal_env[0]) { + + char *endptr; + u8 signal_code; + signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10); + /* Did we manage to parse the full string? */ + if (*endptr != '\0' || endptr == afl_kill_signal_env) { + + FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)", + afl_kill_signal_env); + + } + + fsrv->kill_signal = signal_code; + + } else { + + char *sigstr = alloc_printf("%d", (int)SIGKILL); + if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); } + + /* Set the env for signal handler */ + setenv("AFL_KILL_SIGNAL", sigstr, 1); + free(sigstr); + + } + if (getenv("AFL_CRASH_EXITCODE")) { long exitcode = strtol(getenv("AFL_CRASH_EXITCODE"), NULL, 10); |