about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-cc.c113
-rw-r--r--src/afl-common.c2
-rw-r--r--src/afl-forkserver.c17
-rw-r--r--src/afl-fuzz-bitmap.c81
-rw-r--r--src/afl-fuzz-init.c9
-rw-r--r--src/afl-fuzz-mutators.c7
-rw-r--r--src/afl-fuzz-one.c14
-rw-r--r--src/afl-fuzz-python.c38
-rw-r--r--src/afl-fuzz.c50
-rw-r--r--src/afl-gotcpu.c1
10 files changed, 250 insertions, 82 deletions
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 771a58f5..5d8d33a5 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -49,14 +49,14 @@ static u8 * obj_path;                  /* Path to runtime libraries         */
 static u8 **cc_params;                 /* Parameters passed to the real CC  */
 static u32  cc_par_cnt = 1;            /* Param count, including argv0      */
 static u8   llvm_fullpath[PATH_MAX];
-static u8   instrument_mode, instrument_opt_mode, ngram_size, lto_mode,
-    compiler_mode, plusplus_mode;
-static u8  have_gcc, have_llvm, have_gcc_plugin, have_lto;
-static u8 *lto_flag = AFL_CLANG_FLTO, *argvnull;
-static u8  debug;
-static u8  cwd[4096];
-static u8  cmplog_mode;
-u8         use_stdin;                                              /* dummy */
+static u8   instrument_mode, instrument_opt_mode, ngram_size, lto_mode;
+static u8   compiler_mode, plusplus_mode, have_instr_env = 0;
+static u8   have_gcc, have_llvm, have_gcc_plugin, have_lto, have_instr_list = 0;
+static u8 * lto_flag = AFL_CLANG_FLTO, *argvnull;
+static u8   debug;
+static u8   cwd[4096];
+static u8   cmplog_mode;
+u8          use_stdin;                                             /* dummy */
 // static u8 *march_opt = CFLAGS_OPT;
 
 enum {
@@ -354,19 +354,13 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     if (lto_mode && plusplus_mode)
       cc_params[cc_par_cnt++] = "-lc++";  // needed by fuzzbench, early
 
-    if (lto_mode) {
-
-      if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL ||
-          getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") ||
-          getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) {
+    if (lto_mode && have_instr_env) {
 
-        cc_params[cc_par_cnt++] = "-Xclang";
-        cc_params[cc_par_cnt++] = "-load";
-        cc_params[cc_par_cnt++] = "-Xclang";
-        cc_params[cc_par_cnt++] =
-            alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path);
-
-      }
+      cc_params[cc_par_cnt++] = "-Xclang";
+      cc_params[cc_par_cnt++] = "-load";
+      cc_params[cc_par_cnt++] = "-Xclang";
+      cc_params[cc_par_cnt++] =
+          alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path);
 
     }
 
@@ -508,11 +502,25 @@ static void edit_params(u32 argc, char **argv, char **envp) {
       if (instrument_mode == INSTRUMENT_PCGUARD) {
 
 #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0)
-        cc_params[cc_par_cnt++] = "-Xclang";
-        cc_params[cc_par_cnt++] = "-load";
-        cc_params[cc_par_cnt++] = "-Xclang";
-        cc_params[cc_par_cnt++] =
-            alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path);
+        if (have_instr_list) {
+
+          if (!be_quiet)
+            SAYF(
+                "Using unoptimized trace-pc-guard, due usage of "
+                "-fsanitize-coverage-allow/denylist, you can use "
+                "AFL_LLVM_ALLOWLIST/AFL_LLMV_DENYLIST instead.\n");
+          cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+
+        } else {
+
+          cc_params[cc_par_cnt++] = "-Xclang";
+          cc_params[cc_par_cnt++] = "-load";
+          cc_params[cc_par_cnt++] = "-Xclang";
+          cc_params[cc_par_cnt++] =
+              alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path);
+
+        }
+
 #else
   #if LLVM_MAJOR >= 4
         if (!be_quiet)
@@ -590,6 +598,9 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
     if (!strcmp(cur, "-m64")) bit_mode = 64;
 
+    if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list="))
+      have_instr_list = 1;
+
     if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
       asan_set = 1;
 
@@ -856,6 +867,14 @@ int main(int argc, char **argv, char **envp) {
 
     be_quiet = 1;
 
+  if (getenv("AFL_LLVM_INSTRUMENT_FILE") || getenv("AFL_LLVM_WHITELIST") ||
+      getenv("AFL_LLVM_ALLOWLIST") || getenv("AFL_LLVM_DENYLIST") ||
+      getenv("AFL_LLVM_BLOCKLIST")) {
+
+    have_instr_env = 1;
+
+  }
+
   if ((ptr = strrchr(callname, '/')) != NULL) callname = ptr + 1;
   argvnull = (u8 *)argv[0];
   check_environment_vars(envp);
@@ -1015,14 +1034,14 @@ int main(int argc, char **argv, char **envp) {
 
   }
 
-  if ((getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL ||
-       getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") ||
-       getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) &&
-      getenv("AFL_DONT_OPTIMIZE"))
+  if (have_instr_env && getenv("AFL_DONT_OPTIMIZE")) {
+
     WARNF(
         "AFL_LLVM_ALLOWLIST/DENYLIST and AFL_DONT_OPTIMIZE cannot be combined "
         "for file matching, only function matching!");
 
+  }
+
   if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") ||
       getenv("INSTRIM_LIB")) {
 
@@ -1426,22 +1445,20 @@ int main(int argc, char **argv, char **envp) {
 #if LLVM_MAJOR <= 6
     instrument_mode = INSTRUMENT_AFL;
 #else
-    if (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL ||
-        getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") ||
-        getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")) {
+  #if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1)
+    if (have_instr_env) {
 
       instrument_mode = INSTRUMENT_AFL;
-      WARNF(
-          "switching to classic instrumentation because "
-          "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD. Use "
-          "-fsanitize-coverage-allowlist=allowlist.txt or "
-          "-fsanitize-coverage-blocklist=denylist.txt if you want to use "
-          "PCGUARD. Requires llvm 12+. See https://clang.llvm.org/docs/ "
-          "SanitizerCoverage.html#partially-disabling-instrumentation");
+      if (!be_quiet)
+        WARNF(
+            "Switching to classic instrumentation because "
+            "AFL_LLVM_ALLOWLIST/DENYLIST does not work with PCGUARD < 10.0.1.");
 
     } else
 
+  #endif
       instrument_mode = INSTRUMENT_PCGUARD;
+
 #endif
 
   }
@@ -1487,18 +1504,16 @@ int main(int argc, char **argv, char **envp) {
         "AFL_LLVM_NOT_ZERO and AFL_LLVM_SKIP_NEVERZERO can not be set "
         "together");
 
-  if (instrument_mode == INSTRUMENT_PCGUARD &&
-      (getenv("AFL_LLVM_INSTRUMENT_FILE") != NULL ||
-       getenv("AFL_LLVM_WHITELIST") || getenv("AFL_LLVM_ALLOWLIST") ||
-       getenv("AFL_LLVM_DENYLIST") || getenv("AFL_LLVM_BLOCKLIST")))
+#if LLVM_MAJOR < 11 && (LLVM_MAJOR < 10 || LLVM_MINOR < 1)
+  if (instrument_mode == INSTRUMENT_PCGUARD && have_instr_env) {
+
     FATAL(
         "Instrumentation type PCGUARD does not support "
-        "AFL_LLVM_ALLOWLIST/DENYLIST! Use "
-        "-fsanitize-coverage-allowlist=allowlist.txt or "
-        "-fsanitize-coverage-blocklist=denylist.txt instead (requires llvm "
-        "12+), see "
-        "https://clang.llvm.org/docs/"
-        "SanitizerCoverage.html#partially-disabling-instrumentation");
+        "AFL_LLVM_ALLOWLIST/DENYLIST! Use LLVM 10.0.1+ instead.");
+
+  }
+
+#endif
 
   u8 *ptr2;
 
diff --git a/src/afl-common.c b/src/afl-common.c
index 19c9419b..8cf1a444 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -342,7 +342,7 @@ u8 *find_binary(u8 *fname) {
     if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||
         !(st.st_mode & 0111) || st.st_size < 4) {
 
-      free(target_path);
+      ck_free(target_path);
       FATAL("Program '%s' not found or not executable", fname);
 
     }
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 45be2abd..3814a77e 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -116,7 +116,7 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
   fsrv_to->use_fauxsrv = 0;
   fsrv_to->last_run_timed_out = 0;
 
-  fsrv_to->init_child_func = fsrv_exec_child;
+  fsrv_to->init_child_func = from->init_child_func;
   // Note: do not copy ->add_extra_func
 
   list_append(&fsrv_list, fsrv_to);
@@ -272,7 +272,8 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
 
       *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG;
 
-      PFATAL("Execv failed in fauxserver.");
+      WARNF("Execv failed in fauxserver.");
+      break;
 
     }
 
@@ -286,13 +287,13 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
     if (waitpid(child_pid, &status, 0) < 0) {
 
       // Zombie Child could not be collected. Scary!
-      PFATAL("Fauxserver could not determin child's exit code. ");
+      WARNF("Fauxserver could not determine child's exit code. ");
 
     }
 
     /* Relay wait status to AFL pipe, then loop back. */
 
-    if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(0); }
+    if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(1); }
 
   }
 
@@ -330,7 +331,7 @@ static void report_error_and_exit(int error) {
           "memory failed.");
       break;
     default:
-      FATAL("unknown error code %u from fuzzing target!", error);
+      FATAL("unknown error code %d from fuzzing target!", error);
 
   }
 
@@ -355,7 +356,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
   if (fsrv->use_fauxsrv) {
 
-    /* TODO: Come up with sone nice way to initialize this all */
+    /* TODO: Come up with some nice way to initialize this all */
 
     if (fsrv->init_child_func != fsrv_exec_child) {
 
@@ -520,7 +521,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
     *(u32 *)fsrv->trace_bits = EXEC_FAIL_SIG;
     fprintf(stderr, "Error: execv to target failed\n");
-    exit(0);
+    exit(1);
 
   }
 
@@ -1137,7 +1138,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
   }
 
   // Fauxserver should handle this now.
-  // if (tb4 == EXEC_FAIL_SIG) return FSRV_RUN_ERROR;
+  if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) return FSRV_RUN_ERROR;
 
   return FSRV_RUN_OK;
 
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 4b29672a..2d14b04e 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -591,8 +591,32 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
     add_to_queue(afl, queue_fn, len, 0);
 
 #ifdef INTROSPECTION
-    fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation,
-            afl->queue_top->fname);
+    if (afl->custom_mutators_count && afl->current_custom_fuzz) {
+
+      LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
+
+        if (afl->current_custom_fuzz == el && el->afl_custom_introspection) {
+
+          const char *ptr = el->afl_custom_introspection(el->data);
+
+          if (ptr != NULL && *ptr != 0) {
+
+            fprintf(afl->introspection_file, "QUEUE CUSTOM %s = %s\n", ptr,
+                    afl->queue_top->fname);
+
+          }
+
+        }
+
+      });
+
+    } else if (afl->mutation[0] != 0) {
+
+      fprintf(afl->introspection_file, "QUEUE %s = %s\n", afl->mutation,
+              afl->queue_top->fname);
+
+    }
+
 #endif
 
     if (hnb == 2) {
@@ -663,7 +687,32 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
       ++afl->unique_tmouts;
 #ifdef INTROSPECTION
-      fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation);
+      if (afl->custom_mutators_count && afl->current_custom_fuzz) {
+
+        LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
+
+          if (afl->current_custom_fuzz == el && el->afl_custom_introspection) {
+
+            const char *ptr = el->afl_custom_introspection(el->data);
+
+            if (ptr != NULL && *ptr != 0) {
+
+              fprintf(afl->introspection_file,
+                      "UNIQUE_TIMEOUT CUSTOM %s = %s\n", ptr,
+                      afl->queue_top->fname);
+
+            }
+
+          }
+
+        });
+
+      } else if (afl->mutation[0] != 0) {
+
+        fprintf(afl->introspection_file, "UNIQUE_TIMEOUT %s\n", afl->mutation);
+
+      }
+
 #endif
 
       /* Before saving, we make sure that it's a genuine hang by re-running
@@ -749,7 +798,31 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
       ++afl->unique_crashes;
 #ifdef INTROSPECTION
-      fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation);
+      if (afl->custom_mutators_count && afl->current_custom_fuzz) {
+
+        LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
+
+          if (afl->current_custom_fuzz == el && el->afl_custom_introspection) {
+
+            const char *ptr = el->afl_custom_introspection(el->data);
+
+            if (ptr != NULL && *ptr != 0) {
+
+              fprintf(afl->introspection_file, "UNIQUE_CRASH CUSTOM %s = %s\n",
+                      ptr, afl->queue_top->fname);
+
+            }
+
+          }
+
+        });
+
+      } else if (afl->mutation[0] != 0) {
+
+        fprintf(afl->introspection_file, "UNIQUE_CRASH %s\n", afl->mutation);
+
+      }
+
 #endif
       if (unlikely(afl->infoexec)) {
 
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 19a8d77b..6884bb1d 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -2300,12 +2300,6 @@ void fix_up_sync(afl_state_t *afl) {
 
   u8 *x = afl->sync_id;
 
-  if (afl->non_instrumented_mode) {
-
-    FATAL("-S / -M and -n are mutually exclusive");
-
-  }
-
   while (*x) {
 
     if (!isalnum(*x) && *x != '_' && *x != '-') {
@@ -2503,7 +2497,8 @@ void check_binary(afl_state_t *afl, u8 *fname) {
 
   }
 
-  if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode) {
+  if (afl->afl_env.afl_skip_bin_check || afl->use_wine || afl->unicorn_mode ||
+      afl->non_instrumented_mode) {
 
     return;
 
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index c4d7233c..1d14f657 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -166,6 +166,13 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
 
   }
 
+  /* "afl_custom_introspection", optional */
+#ifdef INTROSPECTION
+  mutator->afl_custom_introspection = dlsym(dh, "afl_custom_introspection");
+  if (!mutator->afl_custom_introspection)
+    ACTF("optional symbol 'afl_custom_introspection' not found.");
+#endif
+
   /* "afl_custom_fuzz_count", optional */
   mutator->afl_custom_fuzz_count = dlsym(dh, "afl_custom_fuzz_count");
   if (!mutator->afl_custom_fuzz_count)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 91bbced6..0adc3719 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1780,10 +1780,16 @@ custom_mutator_stage:
 
   orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
 
+#ifdef INTROSPECTION
+  afl->mutation[0] = 0;
+#endif
+
   LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
 
     if (el->afl_custom_fuzz) {
 
+      afl->current_custom_fuzz = el;
+
       if (el->afl_custom_fuzz_count)
         afl->stage_max = el->afl_custom_fuzz_count(el->data, out_buf, len);
       else
@@ -1840,12 +1846,6 @@ custom_mutator_stage:
 
           if (mutated_size > 0) {
 
-#ifdef INTROSPECTION
-            snprintf(afl->mutation, sizeof(afl->mutation), "%s CUSTOM-%s",
-                     afl->queue_cur->fname,
-                     target != NULL ? (char *)target->fname : "none");
-#endif
-
             if (common_fuzz_stuff(afl, mutated_buf, (u32)mutated_size)) {
 
               goto abandon_entry;
@@ -1889,6 +1889,8 @@ custom_mutator_stage:
 
   });
 
+  afl->current_custom_fuzz = NULL;
+
   if (!has_custom_fuzz) goto havoc_stage;
 
   new_hit_cnt = afl->queued_paths + afl->unique_crashes;
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index adb92649..cfaf055d 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -163,6 +163,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
         PyObject_GetAttrString(py_module, "queue_get");
     py_functions[PY_FUNC_QUEUE_NEW_ENTRY] =
         PyObject_GetAttrString(py_module, "queue_new_entry");
+    py_functions[PY_FUNC_INTROSPECTION] =
+        PyObject_GetAttrString(py_module, "introspection");
     py_functions[PY_FUNC_DEINIT] = PyObject_GetAttrString(py_module, "deinit");
     if (!py_functions[PY_FUNC_DEINIT])
       FATAL("deinit function not found in python module");
@@ -212,6 +214,7 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
 
     PyErr_Print();
     fprintf(stderr, "Failed to load \"%s\"\n", module_name);
+    free(py);
     return NULL;
 
   }
@@ -326,9 +329,7 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
 
   if (py_functions[PY_FUNC_DEINIT]) { mutator->afl_custom_deinit = deinit_py; }
 
-  /* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
-     is quite different from the custom mutator. */
-  mutator->afl_custom_fuzz = fuzz_py;
+  if (py_functions[PY_FUNC_FUZZ]) { mutator->afl_custom_fuzz = fuzz_py; }
 
   if (py_functions[PY_FUNC_POST_PROCESS]) {
 
@@ -381,6 +382,15 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
 
   }
 
+  #ifdef INTROSPECTION
+  if (py_functions[PY_FUNC_INTROSPECTION]) {
+
+    mutator->afl_custom_introspection = introspection_py;
+
+  }
+
+  #endif
+
   OKF("Python mutator '%s' installed successfully.", module_name);
 
   /* Initialize the custom mutator */
@@ -679,6 +689,28 @@ u8 havoc_mutation_probability_py(void *py_mutator) {
 
 }
 
+const char *introspection_py(void *py_mutator) {
+
+  PyObject *py_args, *py_value;
+
+  py_args = PyTuple_New(0);
+  py_value = PyObject_CallObject(
+      ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_INTROSPECTION],
+      py_args);
+  Py_DECREF(py_args);
+
+  if (py_value == NULL) {
+
+    return NULL;
+
+  } else {
+
+    return PyByteArray_AsString(py_value);
+
+  }
+
+}
+
 u8 queue_get_py(void *py_mutator, const u8 *filename) {
 
   PyObject *py_args, *py_value;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 269ce1bf..cedfdf8f 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -435,9 +435,26 @@ int main(int argc, char **argv_orig, char **envp) {
 
         u8 *c;
 
+        if (afl->non_instrumented_mode) {
+
+          FATAL("-M is not supported in non-instrumented mode");
+
+        }
+
         if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
+
+        /* sanity check for argument: should not begin with '-' (possible
+         * option) */
+        if (optarg && *optarg == '-') {
+
+          FATAL(
+              "argument for -M started with a dash '-', which is used for "
+              "options");
+
+        }
+
         afl->sync_id = ck_strdup(optarg);
-        afl->skip_deterministic = 0;  // force determinsitic fuzzing
+        afl->skip_deterministic = 0;  // force deterministic fuzzing
         afl->old_seed_selection = 1;  // force old queue walking seed selection
 
         if ((c = strchr(afl->sync_id, ':'))) {
@@ -464,7 +481,24 @@ int main(int argc, char **argv_orig, char **envp) {
 
       case 'S':                                        /* secondary sync id */
 
+        if (afl->non_instrumented_mode) {
+
+          FATAL("-S is not supported in non-instrumented mode");
+
+        }
+
         if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
+
+        /* sanity check for argument: should not begin with '-' (possible
+         * option) */
+        if (optarg && *optarg == '-') {
+
+          FATAL(
+              "argument for -M started with a dash '-', which is used for "
+              "options");
+
+        }
+
         afl->sync_id = ck_strdup(optarg);
         afl->is_secondary_node = 1;
         break;
@@ -620,6 +654,12 @@ int main(int argc, char **argv_orig, char **envp) {
 
       case 'n':                                                /* dumb mode */
 
+        if (afl->is_main_node || afl->is_secondary_node) {
+
+          FATAL("Non instrumented mode is not supported with -M / -S");
+
+        }
+
         if (afl->non_instrumented_mode) {
 
           FATAL("Multiple -n options not supported");
@@ -906,7 +946,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   afl->power_name = power_names[afl->schedule];
 
-  if (!afl->sync_id) {
+  if (!afl->non_instrumented_mode && !afl->sync_id) {
 
     auto_sync = 1;
     afl->sync_id = ck_strdup("default");
@@ -1338,7 +1378,11 @@ int main(int argc, char **argv_orig, char **envp) {
 
     }
 
-    if (!afl->fsrv.qemu_mode) { check_binary(afl, afl->cmplog_binary); }
+    if (!afl->fsrv.qemu_mode && !afl->non_instrumented_mode) {
+
+      check_binary(afl, afl->cmplog_binary);
+
+    }
 
   }
 
diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c
index bd0f7de6..1aea3e40 100644
--- a/src/afl-gotcpu.c
+++ b/src/afl-gotcpu.c
@@ -65,7 +65,6 @@
     #define cpu_set_t cpuset_t
   #elif defined(__NetBSD__)
     #include <pthread.h>
-    #include <sched.h>
   #elif defined(__APPLE__)
     #include <pthread.h>
     #include <mach/thread_act.h>