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.c172
1 files changed, 170 insertions, 2 deletions
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index b871ea8c..eebbb7c8 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -13,7 +13,7 @@
 
 
    Copyright 2016, 2017 Google Inc. All rights reserved.
-   Copyright 2019-2020 AFLplusplus Project. All rights reserved.
+   Copyright 2019-2022 AFLplusplus Project. All rights reserved.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -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,82 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
   s32   rlen;
   char *ignore_autodict = getenv("AFL_NO_AUTODICT");
 
+#ifdef __linux__
+  if (unlikely(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 ..."); }
+
+    u32 tmp_map_size =
+        fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner);
+    fsrv->real_map_size = fsrv->map_size;
+    fsrv->map_size = (((tmp_map_size + 63) >> 6) << 6);
+    if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_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 +1172,10 @@ 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 +1192,16 @@ 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 (unlikely(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,13 +1315,80 @@ 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. */
 
-  memset(fsrv->trace_bits, 0, fsrv->map_size);
+#ifdef __linux__
+  if (!fsrv->nyx_mode) {
+
+    memset(fsrv->trace_bits, 0, fsrv->map_size);
+    MEM_BARRIER();
+
+  }
 
+#else
+  memset(fsrv->trace_bits, 0, fsrv->map_size);
   MEM_BARRIER();
+#endif
 
   /* we have the fork server (or faux server) up and running
   First, tell it if the previous run timed out. */