about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbuherator <buherator@silentsignal.hu>2021-01-07 22:35:34 +0100
committerGitHub <noreply@github.com>2021-01-07 22:35:34 +0100
commit9cdf5c415015e4e80b577c021b8b9fcf8a3d58fb (patch)
treedc0880273395088beffa376627606074c950ed07
parent52c221fc484317d2cd3926ae31ac891bad8cc93a (diff)
downloadafl++-9cdf5c415015e4e80b577c021b8b9fcf8a3d58fb.tar.gz
User defined kill signal value (#678)
* Adding AFL_KILL_SIGNAL environment variable

Controlling the kill signal used to end forked processes.

* Checking validity of AFL_KILL_SIGNAL env variable

This commit also sets a valid value in the environment to avoid
duplicating code in at_exit(). Changing data type of
fsrv->kill_signal to u8 to match last_kill_signal.

* Adding afl_kill_signal to AFL (environment) state

This commit simply introduces a struct member for future use. The
env variable is not used from the afl struct but from fsrv, where
its validity is checked, resulting in a FATAL in case of errors.
-rw-r--r--include/afl-fuzz.h2
-rw-r--r--include/envs.h1
-rw-r--r--include/forkserver.h2
-rw-r--r--src/afl-forkserver.c44
-rw-r--r--src/afl-fuzz-state.c11
-rw-r--r--src/afl-fuzz.c13
6 files changed, 63 insertions, 10 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index ede54f0e..988a907d 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -381,7 +381,7 @@ typedef struct afl_env_vars {
       *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_skip_crashes, *afl_preload,
       *afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
       *afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
-      *afl_testcache_entries;
+      *afl_testcache_entries, *afl_kill_signal;
 
 } afl_env_vars_t;
 
diff --git a/include/envs.h b/include/envs.h
index e4e49c4d..97367fae 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -61,6 +61,7 @@ static char *afl_environment_variables[] = {
     "AFL_IMPORT_FIRST",
     "AFL_INST_LIBS",
     "AFL_INST_RATIO",
+    "AFL_KILL_SIGNAL",
     "AFL_KEEP_TRACES",
     "AFL_KEEP_ASSEMBLY",
     "AFL_LD_HARD_FAIL",
diff --git a/include/forkserver.h b/include/forkserver.h
index 8e029266..3019e289 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -99,6 +99,8 @@ typedef struct afl_forkserver {
 
   void (*add_extra_func)(void *afl_ptr, u8 *mem, u32 len);
 
+  u8 kill_signal;
+
 } afl_forkserver_t;
 
 typedef enum fsrv_run_result {
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index d6195cb5..70fb9572 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -95,6 +95,29 @@ 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);
 
@@ -126,6 +149,8 @@ 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);
 
 }
@@ -559,12 +584,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
     if (!time_ms) {
 
-      kill(fsrv->fsrv_pid, SIGKILL);
+      kill(fsrv->fsrv_pid, fsrv->kill_signal);
 
     } else if (time_ms > fsrv->init_tmout) {
 
       fsrv->last_run_timed_out = 1;
-      kill(fsrv->fsrv_pid, SIGKILL);
+      kill(fsrv->fsrv_pid, fsrv->kill_signal);
 
     } else {
 
@@ -944,10 +969,10 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
 static void afl_fsrv_kill(afl_forkserver_t *fsrv) {
 
-  if (fsrv->child_pid > 0) { kill(fsrv->child_pid, SIGKILL); }
+  if (fsrv->child_pid > 0) { kill(fsrv->child_pid, fsrv->kill_signal); }
   if (fsrv->fsrv_pid > 0) {
 
-    kill(fsrv->fsrv_pid, SIGKILL);
+    kill(fsrv->fsrv_pid, fsrv->kill_signal);
     if (waitpid(fsrv->fsrv_pid, NULL, 0) <= 0) { WARNF("error waitpid\n"); }
 
   }
@@ -1091,7 +1116,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
     /* If there was no response from forkserver after timeout seconds,
     we kill the child. The forkserver should inform us afterwards */
 
-    kill(fsrv->child_pid, SIGKILL);
+    kill(fsrv->child_pid, fsrv->kill_signal);
     fsrv->last_run_timed_out = 1;
     if (read(fsrv->fsrv_st_fd, &fsrv->child_status, 4) < 4) { exec_ms = 0; }
 
@@ -1137,6 +1162,15 @@ 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) {
+
+    return FSRV_RUN_TMOUT;
+
+  }
+
   if (WIFSIGNALED(fsrv->child_status) && !*stop_soon_p) {
 
     fsrv->last_kill_signal = WTERMSIG(fsrv->child_status);
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 34456c0d..60c9684c 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -418,6 +418,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
                 (u8 *)get_afl_env(afl_environment_variables[i]);
 #endif
 
+          } else if (!strncmp(env, "AFL_KILL_SIGNAL",
+
+                              afl_environment_variable_len)) {
+
+            afl->afl_env.afl_kill_signal =
+                (u8 *)get_afl_env(afl_environment_variables[i]);
+
           }
 
         } else {
@@ -524,8 +531,8 @@ void afl_states_stop(void) {
 
   LIST_FOREACH(&afl_states, afl_state_t, {
 
-    if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, SIGKILL);
-    if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, SIGKILL);
+    if (el->fsrv.child_pid > 0) kill(el->fsrv.child_pid, el->fsrv.kill_signal);
+    if (el->fsrv.fsrv_pid > 0) kill(el->fsrv.fsrv_pid, el->fsrv.kill_signal);
 
   });
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 063134fb..00625f2e 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -76,8 +76,17 @@ static void at_exit() {
 
   }
 
-  if (pid1 > 0) { kill(pid1, SIGKILL); }
-  if (pid2 > 0) { kill(pid2, SIGKILL); }
+  u8 kill_signal = SIGKILL;
+
+  /* AFL_KILL_SIGNAL should already be initialized by afl_fsrv_init() */
+  if (getenv("AFL_KILL_SIGNAL")) {
+
+    kill_signal = atoi(getenv("AFL_KILL_SIGNAL"));
+
+  }
+
+  if (pid1 > 0) { kill(pid1, kill_signal); }
+  if (pid2 > 0) { kill(pid2, kill_signal); }
 
 }