mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 02:58:08 +00:00
Add AFL_FORK_SERVER_KILL_SIGNAL environment variable.
The AFL_FORK_SERVER_KILL_SIGNAL variable allows to configure the signal used to kill the fork server on termination.
This commit is contained in:
2
afl-cmin
2
afl-cmin
@ -123,6 +123,8 @@ function usage() {
|
|||||||
"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \
|
"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \
|
||||||
"AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \
|
"AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \
|
||||||
"AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \
|
"AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \
|
||||||
|
"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on termination\n"
|
||||||
|
" (default: SIGTERM)\n"
|
||||||
"AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" \
|
"AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" \
|
||||||
"AFL_CMIN_ALLOW_ANY: write tuples for crashing inputs also\n" \
|
"AFL_CMIN_ALLOW_ANY: write tuples for crashing inputs also\n" \
|
||||||
"AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \
|
"AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \
|
||||||
|
@ -409,11 +409,18 @@ checks or alter some of the more exotic semantics of the tool:
|
|||||||
the afl-fuzz -g/-G command line option to control the minimum/maximum
|
the afl-fuzz -g/-G command line option to control the minimum/maximum
|
||||||
of fuzzing input generated.
|
of fuzzing input generated.
|
||||||
|
|
||||||
- `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes on
|
- `AFL_KILL_SIGNAL`: Set the signal ID to be delivered to child processes
|
||||||
timeout. Unless you implement your own targets or instrumentation, you
|
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`
|
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.
|
(`AFL_KILL_SIGNAL=9`) will be delivered to the child.
|
||||||
|
|
||||||
|
- `AFL_FORK_SERVER_KILL_SIGNAL`: Set the signal ID to be delivered to the
|
||||||
|
fork server when AFL++ is terminated. Unless you implement your
|
||||||
|
fork server, you likely do not have to set it. By default, `SIGTERM`
|
||||||
|
(`AFL_FORK_SERVER_KILL_SIGNAL=15`) will be delivered to the fork server.
|
||||||
|
NOTE: Uncatchable signals, such as `SIGKILL`, cause child processes of
|
||||||
|
the fork server to be orphaned and leaves them in a zombie state.
|
||||||
|
|
||||||
- `AFL_MAP_SIZE` sets the size of the shared map that afl-analyze, afl-fuzz,
|
- `AFL_MAP_SIZE` sets the size of the shared map that afl-analyze, afl-fuzz,
|
||||||
afl-showmap, and afl-tmin create to gather instrumentation data from the
|
afl-showmap, and afl-tmin create to gather instrumentation data from the
|
||||||
target. This must be equal or larger than the size the target was compiled
|
target. This must be equal or larger than the size the target was compiled
|
||||||
|
@ -393,8 +393,8 @@ typedef struct afl_env_vars {
|
|||||||
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
|
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
|
||||||
*afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
|
*afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
|
||||||
*afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
|
*afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
|
||||||
*afl_testcache_entries, *afl_kill_signal, *afl_target_env,
|
*afl_testcache_entries, *afl_child_kill_signal, *afl_fsrv_kill_signal,
|
||||||
*afl_persistent_record, *afl_exit_on_time;
|
*afl_target_env, *afl_persistent_record, *afl_exit_on_time;
|
||||||
|
|
||||||
} afl_env_vars_t;
|
} afl_env_vars_t;
|
||||||
|
|
||||||
@ -1268,4 +1268,3 @@ void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q, u8 *mem);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -67,10 +67,11 @@ u8 *find_binary(u8 *fname);
|
|||||||
|
|
||||||
u8 *find_afl_binary(u8 *own_loc, u8 *fname);
|
u8 *find_afl_binary(u8 *own_loc, u8 *fname);
|
||||||
|
|
||||||
/* Parses the kill signal environment variable, FATALs on error.
|
/* Parses the (numeric) kill signal environment variable passed
|
||||||
If the env is not set, sets the env to default_signal for the signal handlers
|
via `numeric_signal_as_str`.
|
||||||
and returns the default_signal. */
|
If NULL is passed, the `default_signal` value is returned.
|
||||||
int parse_afl_kill_signal_env(u8 *afl_kill_signal_env, int default_signal);
|
FATALs if `numeric_signal_as_str` is not a valid integer .*/
|
||||||
|
int parse_afl_kill_signal(u8 *numeric_signal_as_str, int default_signal);
|
||||||
|
|
||||||
/* Read a bitmap from file fname to memory
|
/* Read a bitmap from file fname to memory
|
||||||
This is for the -B option again. */
|
This is for the -B option again. */
|
||||||
@ -133,4 +134,3 @@ FILE *create_ffile(u8 *fn);
|
|||||||
s32 create_file(u8 *fn);
|
s32 create_file(u8 *fn);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_INST_RATIO",
|
"AFL_INST_RATIO",
|
||||||
"AFL_KEEP_TIMEOUTS",
|
"AFL_KEEP_TIMEOUTS",
|
||||||
"AFL_KILL_SIGNAL",
|
"AFL_KILL_SIGNAL",
|
||||||
|
"AFL_FORK_SERVER_KILL_SIGNAL",
|
||||||
"AFL_KEEP_TRACES",
|
"AFL_KEEP_TRACES",
|
||||||
"AFL_KEEP_ASSEMBLY",
|
"AFL_KEEP_ASSEMBLY",
|
||||||
"AFL_LD_HARD_FAIL",
|
"AFL_LD_HARD_FAIL",
|
||||||
@ -239,4 +240,3 @@ static char *afl_environment_variables[] = {
|
|||||||
extern char *afl_environment_variables[];
|
extern char *afl_environment_variables[];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -164,6 +164,8 @@ typedef struct afl_forkserver {
|
|||||||
void (*add_extra_func)(void *afl_ptr, u8 *mem, u32 len);
|
void (*add_extra_func)(void *afl_ptr, u8 *mem, u32 len);
|
||||||
|
|
||||||
u8 child_kill_signal;
|
u8 child_kill_signal;
|
||||||
|
u8 fsrv_kill_signal;
|
||||||
|
|
||||||
u8 persistent_mode;
|
u8 persistent_mode;
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
@ -1116,7 +1116,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fsrv.child_kill_signal =
|
fsrv.child_kill_signal =
|
||||||
parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
|
parse_afl_kill_signal(getenv("AFL_KILL_SIGNAL"), SIGKILL);
|
||||||
|
fsrv.fsrv_kill_signal =
|
||||||
|
parse_afl_kill_signal(getenv("AFL_FORK_SERVER_KILL_SIGNAL"), SIGTERM);
|
||||||
|
|
||||||
|
|
||||||
read_initial_file();
|
read_initial_file();
|
||||||
(void)check_binary_signatures(fsrv.target_path);
|
(void)check_binary_signatures(fsrv.target_path);
|
||||||
|
@ -456,38 +456,24 @@ u8 *find_afl_binary(u8 *own_loc, u8 *fname) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parses the kill signal environment variable, FATALs on error.
|
|
||||||
If the env is not set, sets the env to default_signal for the signal handlers
|
|
||||||
and returns the default_signal. */
|
|
||||||
int parse_afl_kill_signal_env(u8 *afl_kill_signal_env, int default_signal) {
|
|
||||||
|
|
||||||
if (afl_kill_signal_env && afl_kill_signal_env[0]) {
|
int parse_afl_kill_signal(u8 *numeric_signal_as_str, int default_signal) {
|
||||||
|
|
||||||
|
if (numeric_signal_as_str && numeric_signal_as_str[0]) {
|
||||||
|
|
||||||
char *endptr;
|
char *endptr;
|
||||||
u8 signal_code;
|
u8 signal_code;
|
||||||
signal_code = (u8)strtoul(afl_kill_signal_env, &endptr, 10);
|
signal_code = (u8)strtoul(numeric_signal_as_str, &endptr, 10);
|
||||||
/* Did we manage to parse the full string? */
|
/* Did we manage to parse the full string? */
|
||||||
if (*endptr != '\0' || endptr == (char *)afl_kill_signal_env) {
|
if (*endptr != '\0' || endptr == (char *)numeric_signal_as_str) {
|
||||||
|
FATAL("Invalid signal name: %s", numeric_signal_as_str);
|
||||||
FATAL("Invalid AFL_KILL_SIGNAL: %s (expected unsigned int)",
|
} else {
|
||||||
afl_kill_signal_env);
|
return signal_code;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return signal_code;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
char *sigstr = alloc_printf("%d", default_signal);
|
|
||||||
if (!sigstr) { FATAL("Failed to alloc mem for signal buf"); }
|
|
||||||
|
|
||||||
/* Set the env for signal handler */
|
|
||||||
setenv("AFL_KILL_SIGNAL", sigstr, 1);
|
|
||||||
free(sigstr);
|
|
||||||
return default_signal;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return default_signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int helper_min3(unsigned int a, unsigned int b,
|
static inline unsigned int helper_min3(unsigned int a, unsigned int b,
|
||||||
@ -1253,4 +1239,3 @@ s32 create_file(u8 *fn) {
|
|||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1245,8 +1245,8 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) {
|
|||||||
if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->child_kill_signal); }
|
if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->child_kill_signal); }
|
||||||
if (fsrv->fsrv_pid > 0) {
|
if (fsrv->fsrv_pid > 0) {
|
||||||
|
|
||||||
kill(fsrv->fsrv_pid, SIGTERM);
|
kill(fsrv->fsrv_pid, fsrv->fsrv_kill_signal);
|
||||||
if (waitpid(fsrv->fsrv_pid, NULL, 0) <= 0) { WARNF("error waitpid\n"); }
|
waitpid(fsrv->fsrv_pid, NULL, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,10 +485,15 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
} else if (!strncmp(env, "AFL_KILL_SIGNAL",
|
} else if (!strncmp(env, "AFL_KILL_SIGNAL",
|
||||||
|
|
||||||
afl_environment_variable_len)) {
|
afl_environment_variable_len)) {
|
||||||
|
|
||||||
afl->afl_env.afl_kill_signal =
|
afl->afl_env.afl_child_kill_signal =
|
||||||
|
(u8 *)get_afl_env(afl_environment_variables[i]);
|
||||||
|
|
||||||
|
} else if (!strncmp(env, "AFL_FORK_SERVER_KILL_SIGNAL",
|
||||||
|
afl_environment_variable_len)) {
|
||||||
|
|
||||||
|
afl->afl_env.afl_fsrv_kill_signal =
|
||||||
(u8 *)get_afl_env(afl_environment_variables[i]);
|
(u8 *)get_afl_env(afl_environment_variables[i]);
|
||||||
|
|
||||||
} else if (!strncmp(env, "AFL_TARGET_ENV",
|
} else if (!strncmp(env, "AFL_TARGET_ENV",
|
||||||
@ -657,8 +662,7 @@ void afl_states_stop(void) {
|
|||||||
/* NOTE: We need to make sure that the parent (the forkserver) reap the child (see below). */
|
/* NOTE: We need to make sure that the parent (the forkserver) reap the child (see below). */
|
||||||
if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, el->fsrv.child_kill_signal);
|
if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, el->fsrv.child_kill_signal);
|
||||||
if (el->fsrv.fsrv_pid > 0) {
|
if (el->fsrv.fsrv_pid > 0) {
|
||||||
/* This must be SIGTERM, to allow the forkserver to reap the child before exiting. */
|
kill(el->fsrv.fsrv_pid, el->fsrv.fsrv_kill_signal);
|
||||||
kill(el->fsrv.fsrv_pid, SIGTERM);
|
|
||||||
/* Make sure the forkserver does not end up as zombie. */
|
/* Make sure the forkserver does not end up as zombie. */
|
||||||
waitpid(el->fsrv.fsrv_pid, NULL, 0);
|
waitpid(el->fsrv.fsrv_pid, NULL, 0);
|
||||||
}
|
}
|
||||||
|
@ -1359,7 +1359,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
afl->fsrv.child_kill_signal =
|
afl->fsrv.child_kill_signal =
|
||||||
parse_afl_kill_signal_env(afl->afl_env.afl_kill_signal, SIGKILL);
|
parse_afl_kill_signal(afl->afl_env.afl_child_kill_signal, SIGKILL);
|
||||||
|
afl->fsrv.fsrv_kill_signal =
|
||||||
|
parse_afl_kill_signal(afl->afl_env.afl_fsrv_kill_signal, SIGTERM);
|
||||||
|
|
||||||
setup_signal_handlers();
|
setup_signal_handlers();
|
||||||
check_asan_opts(afl);
|
check_asan_opts(afl);
|
||||||
|
@ -866,6 +866,8 @@ static void usage(u8 *argv0) {
|
|||||||
"startup (in milliseconds)\n"
|
"startup (in milliseconds)\n"
|
||||||
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, "
|
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, "
|
||||||
"etc. (default: SIGKILL)\n"
|
"etc. (default: SIGKILL)\n"
|
||||||
|
"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on termination"
|
||||||
|
" (default: SIGTERM)\n"
|
||||||
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the "
|
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the "
|
||||||
"size the target was compiled for\n"
|
"size the target was compiled for\n"
|
||||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||||
@ -1259,7 +1261,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
be_quiet = save_be_quiet;
|
be_quiet = save_be_quiet;
|
||||||
|
|
||||||
fsrv->child_kill_signal =
|
fsrv->child_kill_signal =
|
||||||
parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
|
parse_afl_kill_signal(getenv("AFL_KILL_SIGNAL"), SIGKILL);
|
||||||
|
fsrv->fsrv_kill_signal =
|
||||||
|
parse_afl_kill_signal(getenv("AFL_FORK_SERVER_KILL_SIGNAL"), SIGTERM);
|
||||||
|
|
||||||
if (new_map_size) {
|
if (new_map_size) {
|
||||||
|
|
||||||
|
@ -881,6 +881,8 @@ static void usage(u8 *argv0) {
|
|||||||
"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\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_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_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)\n"
|
||||||
|
"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on termination\n"
|
||||||
|
" (default: SIGTERM)\n"
|
||||||
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
"AFL_MAP_SIZE: the shared memory size for that target. must be >= the size\n"
|
||||||
" the target was compiled for\n"
|
" the target was compiled for\n"
|
||||||
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
|
||||||
@ -1196,7 +1198,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fsrv->child_kill_signal =
|
fsrv->child_kill_signal =
|
||||||
parse_afl_kill_signal_env(getenv("AFL_KILL_SIGNAL"), SIGKILL);
|
parse_afl_kill_signal(getenv("AFL_KILL_SIGNAL"), SIGKILL);
|
||||||
|
fsrv->fsrv_kill_signal =
|
||||||
|
parse_afl_kill_signal(getenv("AFL_FORK_SERVER_KILL_SIGNAL"), SIGTERM);
|
||||||
|
|
||||||
|
|
||||||
if (getenv("AFL_CRASH_EXITCODE")) {
|
if (getenv("AFL_CRASH_EXITCODE")) {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user