about summary refs log tree commit diff
path: root/src/afl-fuzz.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/afl-fuzz.c')
-rw-r--r--src/afl-fuzz.c176
1 files changed, 173 insertions, 3 deletions
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index f59bb47c..1030dfdf 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -9,7 +9,7 @@
                         Andrea Fioraldi <andreafioraldi@gmail.com>
 
    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.
@@ -37,6 +37,7 @@
 
 #ifdef __APPLE__
   #include <sys/qos.h>
+  #include <pthread/qos.h>
 #endif
 
 #ifdef PROFILING
@@ -104,7 +105,7 @@ static void usage(u8 *argv0, int more_help) {
       "  -p schedule   - power schedules compute a seed's performance score:\n"
       "                  fast(default), explore, exploit, seek, rare, mmopt, "
       "coe, lin\n"
-      "                  quad -- see docs/power_schedules.md\n"
+      "                  quad -- see docs/FAQ.md for more information\n"
       "  -f file       - location read by the fuzzed program (default: stdin "
       "or @@)\n"
       "  -t msec       - timeout for each run (auto-scaled, default %u ms). "
@@ -123,6 +124,10 @@ static void usage(u8 *argv0, int more_help) {
       "  -W            - use qemu-based instrumentation with Wine (Wine "
       "mode)\n"
 #endif
+#if defined(__linux__)
+      "  -X            - use VM fuzzing (NYX mode - standalone mode)\n"
+      "  -Y            - use VM fuzzing (NYX mode - multiple instances mode)\n"
+#endif
       "\n"
 
       "Mutator settings:\n"
@@ -384,6 +389,60 @@ static void fasan_check_afl_preload(char *afl_preload) {
 
 }
 
+  #ifdef __linux__
+    #include <dlfcn.h>
+
+nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) {
+
+  void *                handle;
+  nyx_plugin_handler_t *plugin = calloc(1, sizeof(nyx_plugin_handler_t));
+
+  ACTF("Trying to load libnyx.so plugin...");
+  handle = dlopen((char *)libnyx_binary, RTLD_NOW);
+  if (!handle) { goto fail; }
+
+  plugin->nyx_new = dlsym(handle, "nyx_new");
+  if (plugin->nyx_new == NULL) { goto fail; }
+
+  plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown");
+  if (plugin->nyx_shutdown == NULL) { goto fail; }
+
+  plugin->nyx_option_set_reload_mode =
+      dlsym(handle, "nyx_option_set_reload_mode");
+  if (plugin->nyx_option_set_reload_mode == NULL) { goto fail; }
+
+  plugin->nyx_option_set_timeout = dlsym(handle, "nyx_option_set_timeout");
+  if (plugin->nyx_option_set_timeout == NULL) { goto fail; }
+
+  plugin->nyx_option_apply = dlsym(handle, "nyx_option_apply");
+  if (plugin->nyx_option_apply == NULL) { goto fail; }
+
+  plugin->nyx_set_afl_input = dlsym(handle, "nyx_set_afl_input");
+  if (plugin->nyx_set_afl_input == NULL) { goto fail; }
+
+  plugin->nyx_exec = dlsym(handle, "nyx_exec");
+  if (plugin->nyx_exec == NULL) { goto fail; }
+
+  plugin->nyx_get_bitmap_buffer = dlsym(handle, "nyx_get_bitmap_buffer");
+  if (plugin->nyx_get_bitmap_buffer == NULL) { goto fail; }
+
+  plugin->nyx_get_bitmap_buffer_size =
+      dlsym(handle, "nyx_get_bitmap_buffer_size");
+  if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; }
+
+  OKF("libnyx plugin is ready!");
+  return plugin;
+
+fail:
+
+  FATAL("failed to load libnyx: %s\n", dlerror());
+  free(plugin);
+  return NULL;
+
+}
+
+  #endif
+
 /* Main entry point */
 
 int main(int argc, char **argv_orig, char **envp) {
@@ -440,7 +499,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   while ((opt = getopt(
               argc, argv,
-              "+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:Wx:Z")) >
+              "+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOXYo:p:RQs:S:t:T:UV:Wx:Z")) >
          0) {
 
     switch (opt) {
@@ -844,6 +903,29 @@ int main(int argc, char **argv_orig, char **envp) {
         afl->use_banner = optarg;
         break;
 
+  #ifdef __linux__
+      case 'X':                                                 /* NYX mode */
+
+        if (afl->fsrv.nyx_mode) { FATAL("Multiple -X options not supported"); }
+
+        afl->fsrv.nyx_parent = true;
+        afl->fsrv.nyx_standalone = true;
+        afl->fsrv.nyx_mode = 1;
+        afl->fsrv.nyx_id = 0;
+
+        break;
+
+      case 'Y':                                     /* NYX distributed mode */
+        if (afl->fsrv.nyx_mode) { FATAL("Multiple -Y options not supported"); }
+        afl->fsrv.nyx_mode = 1;
+
+        break;
+  #else
+      case 'X':
+      case 'Y':
+        FATAL("Nyx mode is only availabe on linux...");
+        break;
+  #endif
       case 'A':                                           /* CoreSight mode */
 
   #if !defined(__aarch64__) || !defined(__linux__)
@@ -1184,6 +1266,16 @@ int main(int argc, char **argv_orig, char **envp) {
   OKF("NOTE: This is v3.x which changes defaults and behaviours - see "
       "README.md");
 
+  #ifdef __linux__
+  if (afl->fsrv.nyx_mode) {
+
+    OKF("afl++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
+    OKF("Nyx is open source, get it at "
+        "https://github.com/Nyx-Fuzz");
+
+  }
+
+  #endif
   if (afl->sync_id && afl->is_main_node &&
       afl->afl_env.afl_custom_mutator_only) {
 
@@ -1226,6 +1318,56 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  #ifdef __linux__
+  if (afl->fsrv.nyx_mode) {
+
+    if (afl->fsrv.nyx_standalone &&
+        strncmp(afl->sync_id, "default", strlen("default")) != 0) {
+
+      FATAL(
+          "distributed fuzzing is not supported in this Nyx mode (use -Y "
+          "instead)");
+
+    }
+
+    if (!afl->fsrv.nyx_standalone) {
+
+      if (afl->is_main_node) {
+
+        if (strncmp("0", afl->sync_id, strlen("0") != 0)) {
+
+          FATAL(
+              "for Nyx -Y mode, the Main (-M) parameter has to be set to 0 (-M "
+              "0)");
+
+        }
+
+        afl->fsrv.nyx_id = 0;
+
+      }
+
+      if (afl->is_secondary_node) {
+
+        long nyx_id = strtol(afl->sync_id, NULL, 10);
+
+        if (nyx_id == 0 || nyx_id == LONG_MAX) {
+
+          FATAL(
+              "for Nyx -Y mode, the Secondary (-S) parameter has to be a "
+              "numeric value and >= 1 (e.g. -S 1)");
+
+        }
+
+        afl->fsrv.nyx_id = nyx_id;
+
+      }
+
+    }
+
+  }
+
+  #endif
+
   if (afl->sync_id) {
 
     if (strlen(afl->sync_id) > 24) {
@@ -1449,8 +1591,28 @@ int main(int argc, char **argv_orig, char **envp) {
 
   afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver;
 
+  #ifdef __linux__
+  if (!afl->fsrv.nyx_mode) {
+
+    check_crash_handling();
+    check_cpu_governor(afl);
+
+  } else {
+
+    u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so");
+    afl->fsrv.nyx_handlers = afl_load_libnyx_plugin(libnyx_binary);
+    if (afl->fsrv.nyx_handlers == NULL) {
+
+      FATAL("failed to initialize libnyx.so...");
+
+    }
+
+  }
+
+  #else
   check_crash_handling();
   check_cpu_governor(afl);
+  #endif
 
   if (getenv("LD_PRELOAD")) {
 
@@ -1934,6 +2096,14 @@ int main(int argc, char **argv_orig, char **envp) {
 
   if (!afl->pending_not_fuzzed || !valid_seeds) {
 
+  #ifdef __linux__
+    if (afl->fsrv.nyx_mode) {
+
+      afl->fsrv.nyx_handlers->nyx_shutdown(afl->fsrv.nyx_runner);
+
+    }
+
+  #endif
     FATAL("We need at least one valid input seed that does not crash!");
 
   }