about summary refs log tree commit diff
path: root/src/afl-forkserver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/afl-forkserver.c')
-rw-r--r--src/afl-forkserver.c140
1 files changed, 139 insertions, 1 deletions
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index b871ea8c..6604de3a 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -71,6 +71,17 @@ static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) {
 
 void afl_fsrv_init(afl_forkserver_t *fsrv) {
 
+#ifdef __linux__
+  fsrv->nyx_handlers = NULL;
+  fsrv->out_dir_path = NULL;
+  fsrv->nyx_mode = 0;
+  fsrv->nyx_parent = false;
+  fsrv->nyx_standalone = false;
+  fsrv->nyx_runner = NULL;
+  fsrv->nyx_id = 0xFFFFFFFF;
+  fsrv->nyx_bind_cpu_id = 0xFFFFFFFF;
+#endif
+
   // this structure needs default so we initialize it if this was not done
   // already
   fsrv->out_fd = -1;
@@ -375,6 +386,72 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
   s32   rlen;
   char *ignore_autodict = getenv("AFL_NO_AUTODICT");
 
+#ifdef __linux__
+  if (fsrv->nyx_mode) {
+
+    if(fsrv->nyx_runner != NULL){
+      return;
+    }
+
+    if (!be_quiet) { ACTF("Spinning up the NYX backend..."); }
+
+    if(fsrv->out_dir_path == NULL){
+        FATAL("Nyx workdir path not found...");
+    }
+
+    char *x = alloc_printf("%s/workdir", fsrv->out_dir_path);
+
+    if(fsrv->nyx_id == 0xFFFFFFFF){
+        FATAL("Nyx ID is not set..."); 
+    }
+
+    if(fsrv->nyx_bind_cpu_id == 0xFFFFFFFF){
+      FATAL("Nyx CPU ID is not set..."); 
+    }
+
+    if (fsrv->nyx_parent){
+      fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, !fsrv->nyx_standalone);
+    }
+    else{
+      fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, true);
+    }
+
+    if(fsrv->nyx_runner == NULL){
+      FATAL("Something went wrong ...");
+    }
+
+    fsrv->map_size = fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner);;
+    fsrv->real_map_size = fsrv->map_size;
+
+    fsrv->trace_bits = fsrv->nyx_handlers->nyx_get_bitmap_buffer(fsrv->nyx_runner);
+
+    fsrv->nyx_handlers->nyx_option_set_reload_mode(fsrv->nyx_runner, getenv("NYX_DISABLE_SNAPSHOT_MODE") == NULL);
+    fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
+
+    fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0);
+    fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
+
+    /* dry run */
+    fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, "INIT", 4);
+    switch(fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)){
+      case Abort:
+        fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
+        FATAL("Error: Nyx abort occured...");
+        break;
+      case IoError:
+        FATAL("Error: QEMU-Nyx has died...");
+        break;
+      case Error:
+        fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
+        FATAL("Error: Nyx runtime error has occured...");
+        break;
+      default:
+        break;
+    }
+    return;
+  }
+#endif
+
   if (!be_quiet) { ACTF("Spinning up the fork server..."); }
 
 #ifdef AFL_PERSISTENT_RECORD
@@ -1085,6 +1162,11 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) {
   fsrv->fsrv_pid = -1;
   fsrv->child_pid = -1;
 
+#ifdef __linux__
+  if(fsrv->nyx_mode){
+    fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
+  }
+#endif
 }
 
 /* Get the map size from the target forkserver */
@@ -1101,6 +1183,12 @@ u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv,
 
 void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
 
+#ifdef __linux__
+  if(fsrv->nyx_mode){
+    fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, buf, len);
+    return;
+  }
+#endif
 #ifdef AFL_PERSISTENT_RECORD
   if (unlikely(fsrv->persistent_record)) {
 
@@ -1214,12 +1302,62 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
   u32 exec_ms;
   u32 write_value = fsrv->last_run_timed_out;
 
+#ifdef __linux__
+  if(fsrv->nyx_mode){
+
+    static uint32_t last_timeout_value = 0;
+
+    if (last_timeout_value != timeout){
+      fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, timeout/1000, (timeout%1000) * 1000);
+      fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
+      last_timeout_value = timeout;
+    }
+
+    enum NyxReturnValue ret_val = fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner);
+
+    fsrv->total_execs++;
+
+    switch(ret_val){
+      case Normal:
+        return FSRV_RUN_OK;
+      case Crash:
+      case Asan:
+        return FSRV_RUN_CRASH;
+      case Timout:
+        return FSRV_RUN_TMOUT;
+      case InvalidWriteToPayload:
+        /* ??? */
+        FATAL("FixMe: Nyx InvalidWriteToPayload handler is missing");
+        break;
+      case Abort:
+        fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner);
+        FATAL("Error: Nyx abort occured...");
+      case IoError:
+        if (*stop_soon_p){
+          return 0;
+        }
+        else{
+          FATAL("Error: QEMU-Nyx has died...");
+        }
+        break;
+      case Error:
+        FATAL("Error: Nyx runtime error has occured...");
+        break;
+    }
+    return FSRV_RUN_OK;
+  }                           
+#endif
   /* After this memset, fsrv->trace_bits[] are effectively volatile, so we
      must prevent any earlier operations from venturing into that
      territory. */
 
+#ifdef __linux__
+  if(!fsrv->nyx_mode){
+    memset(fsrv->trace_bits, 0, fsrv->map_size);
+  }
+#else
   memset(fsrv->trace_bits, 0, fsrv->map_size);
-
+#endif
   MEM_BARRIER();
 
   /* we have the fork server (or faux server) up and running