about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile2
-rw-r--r--GNUmakefile.gcc_plugin13
-rw-r--r--GNUmakefile.llvm2
-rw-r--r--README.md2
-rw-r--r--docs/Changelog.md4
-rw-r--r--docs/binaryonly_fuzzing.md3
-rw-r--r--docs/ideas.md6
-rw-r--r--dynamic_list.txt62
-rw-r--r--instrumentation/afl-compiler-rt.o.c143
-rw-r--r--src/afl-analyze.c17
-rw-r--r--src/afl-cc.c12
-rw-r--r--src/afl-fuzz-init.c17
-rw-r--r--src/afl-fuzz-stats.c52
-rw-r--r--src/afl-fuzz.c3
-rwxr-xr-xtest/test-llvm.sh8
15 files changed, 243 insertions, 103 deletions
diff --git a/GNUmakefile b/GNUmakefile
index a45f6d5c..6df7ea1d 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -572,7 +572,7 @@ clean:
 	$(MAKE) -C qemu_mode/unsigaction clean
 	$(MAKE) -C qemu_mode/libcompcov clean
 	$(MAKE) -C qemu_mode/libqasan clean
-	$(MAKE) -C frida_mode clean
+	-$(MAKE) -C frida_mode clean
 ifeq "$(IN_REPO)" "1"
 	test -e qemu_mode/qemuafl/Makefile && $(MAKE) -C qemu_mode/qemuafl clean || true
 	test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index b0f90f1b..bce97b2f 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -100,7 +100,7 @@ ifeq "$(SYS)" "SunOS"
 endif
 
 
-PROGS        = ./afl-gcc-pass.so
+PROGS        = ./afl-gcc-pass.so ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o
 
 .PHONY: all
 all: test_shm test_deps $(PROGS) test_build all_done
@@ -130,6 +130,17 @@ test_deps:
 afl-common.o: ./src/afl-common.c
 	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ $(LDFLAGS)
 
+./afl-compiler-rt.o: instrumentation/afl-compiler-rt.o.c
+	$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -fPIC -c $< -o $@
+
+./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c
+	@printf "[*] Building 32-bit variant of the runtime (-m32)... "
+	@$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-32.o afl-llvm-rt-32.o; else echo "failed (that's fine)"; fi
+
+./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c
+	@printf "[*] Building 64-bit variant of the runtime (-m64)... "
+	@$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi
+
 ./afl-gcc-pass.so: instrumentation/afl-gcc-pass.so.cc | test_deps
 	$(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@
 	ln -sf afl-cc afl-gcc-fast
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 2d50badc..64ba73f4 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -57,7 +57,7 @@ LLVM_APPLE_XCODE = $(shell clang -v 2>&1 | grep -q Apple && echo 1 || echo 0)
 LLVM_LTO   = 0
 
 ifeq "$(LLVMVER)" ""
-  $(warning [!] llvm_mode needs llvm-config, which was not found)
+  $(warning [!] llvm_mode needs llvm-config, which was not found. Set LLVM_CONFIG to its path and retry.)
 endif
 
 ifeq "$(LLVM_UNSUPPORTED)" "1"
diff --git a/README.md b/README.md
index ba612edb..383d71c4 100644
--- a/README.md
+++ b/README.md
@@ -801,7 +801,7 @@ Alternatively you can use frida_mode, just switch `-Q` with `-O` and remove the
 LAF instance.
 
 Then run as many instances as you have cores left with either -Q mode or - better -
-use a binary rewriter like afl-dyninst, retrowrite, zaflr, etc.
+use a binary rewriter like afl-dyninst, retrowrite, zafl, etc.
 
 For Qemu and Frida mode, check out the persistent mode, it gives a huge speed
 improvement if it is possible to use.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index a49c0672..b70ba022 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -10,6 +10,10 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
 
 ### Version ++3.14a (release)
   - Fix for llvm 13
+  - afl-fuzz:
+    - fix -F when a '/' was part of the parameter
+    - removed implied -D determinstic from -M main
+  - ensure afl-compiler-rt is built for gcc_module
 
 
 ### Version ++3.13c (release)
diff --git a/docs/binaryonly_fuzzing.md b/docs/binaryonly_fuzzing.md
index 11e1dbeb..3b32f5ed 100644
--- a/docs/binaryonly_fuzzing.md
+++ b/docs/binaryonly_fuzzing.md
@@ -122,7 +122,7 @@
   [https://github.com/vanhauser-thc/afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst)
 
 
-## RETROWRITE
+## RETROWRITE, ZAFL, ... other binary rewriter
 
   If you have an x86/x86_64 binary that still has its symbols, is compiled
   with position independant code (PIC/PIE) and does not use most of the C++
@@ -131,6 +131,7 @@
 
   It is at about 80-85% performance.
 
+  [https://git.zephyr-software.com/opensrc/zafl](https://git.zephyr-software.com/opensrc/zafl)
   [https://github.com/HexHive/retrowrite](https://github.com/HexHive/retrowrite)
 
 
diff --git a/docs/ideas.md b/docs/ideas.md
index e25d3ba6..0ee69851 100644
--- a/docs/ideas.md
+++ b/docs/ideas.md
@@ -34,6 +34,12 @@ Mentor: any
 Other programming languages also use llvm hence they could (easily?) supported
 for fuzzing, e.g. mono, swift, go, kotlin native, fortran, ...
 
+GCC also supports: Objective-C, Fortran, Ada, Go, and D
+(according to [Gcc homepage](https://gcc.gnu.org/))
+
+LLVM is also used by: Rust, LLGo (Go), kaleidoscope (Haskell), flang (Fortran), emscripten (JavaScript, WASM), ilwasm (CIL (C#))
+(according to [LLVM frontends](https://gist.github.com/axic/62d66fb9d8bccca6cc48fa9841db9241))
+
 Mentor: vanhauser-thc
 
 ## Machine Learning
diff --git a/dynamic_list.txt b/dynamic_list.txt
index d1905d43..7293ae77 100644
--- a/dynamic_list.txt
+++ b/dynamic_list.txt
@@ -1,48 +1,56 @@
 {
+  "__afl_already_initialized_first";
+  "__afl_already_initialized_forkserver";
+  "__afl_already_initialized_second";
+  "__afl_already_initialized_shm";
   "__afl_area_ptr";
+  "__afl_auto_early";
+  "__afl_auto_first";
+  "__afl_auto_init";
+  "__afl_auto_second";
+  "__afl_coverage_discard";
+  "__afl_coverage_interesting";
+  "__afl_coverage_off";
+  "__afl_coverage_on";
+  "__afl_coverage_skip";
+  "__afl_dictionary";
+  "__afl_dictionary_len";
+  "__afl_final_loc";
+  "__afl_fuzz_len";
+  "__afl_fuzz_ptr";
   "__afl_manual_init";
+  "__afl_map_addr";
   "__afl_persistent_loop";
-  "__afl_auto_init";
-  "__afl_area_initial";
-  "__afl_prev_loc";
   "__afl_prev_caller";
   "__afl_prev_ctx";
-  "__afl_final_loc";
-  "__afl_map_addr";
-  "__afl_dictionary";
-  "__afl_dictionary_len";
+  "__afl_prev_loc";
   "__afl_selective_coverage";
   "__afl_selective_coverage_start_off";
   "__afl_selective_coverage_temp";
-  "__afl_coverage_discard";
-  "__afl_coverage_skip";
-  "__afl_coverage_on";
-  "__afl_coverage_off";
-  "__afl_coverage_interesting";
-  "__afl_fuzz_len";
-  "__afl_fuzz_ptr";
   "__afl_sharedmem_fuzzing";
-  "__sanitizer_cov_trace_pc_guard";
-  "__sanitizer_cov_trace_pc_guard_init";
+  "__afl_trace";
   "__cmplog_ins_hook1";
+  "__cmplog_ins_hook16";
   "__cmplog_ins_hook2";
   "__cmplog_ins_hook4";
+  "__cmplog_ins_hook8";
   "__cmplog_ins_hookN";
-  "__cmplog_ins_hook16";
+  "__cmplog_rtn_gcc_stdstring_cstring";
+  "__cmplog_rtn_gcc_stdstring_stdstring";
+  "__cmplog_rtn_hook";
+  "__cmplog_rtn_llvm_stdstring_cstring";
+  "__cmplog_rtn_llvm_stdstring_stdstring";
   "__sanitizer_cov_trace_cmp1";
-  "__sanitizer_cov_trace_const_cmp1";
+  "__sanitizer_cov_trace_cmp16";
   "__sanitizer_cov_trace_cmp2";
-  "__sanitizer_cov_trace_const_cmp2";
   "__sanitizer_cov_trace_cmp4";
-  "__sanitizer_cov_trace_const_cmp4";
   "__sanitizer_cov_trace_cmp8";
-  "__sanitizer_cov_trace_const_cmp8";
-  "__sanitizer_cov_trace_cmp16";
+  "__sanitizer_cov_trace_const_cmp1";
   "__sanitizer_cov_trace_const_cmp16";
+  "__sanitizer_cov_trace_const_cmp2";
+  "__sanitizer_cov_trace_const_cmp4";
+  "__sanitizer_cov_trace_const_cmp8";
+  "__sanitizer_cov_trace_pc_guard";
+  "__sanitizer_cov_trace_pc_guard_init";
   "__sanitizer_cov_trace_switch";
-  "__cmplog_rtn_hook";
-  "__cmplog_rtn_gcc_stdstring_cstring";
-  "__cmplog_rtn_gcc_stdstring_stdstring";
-  "__cmplog_rtn_llvm_stdstring_cstring";
-  "__cmplog_rtn_llvm_stdstring_stdstring";
 };
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 2089ce78..a4760153 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -83,14 +83,15 @@ extern ssize_t _kern_write(int fd, off_t pos, const void *buffer,
                            size_t bufferSize);
 #endif  // HAIKU
 
-u8   __afl_area_initial[MAP_INITIAL_SIZE];
-u8 * __afl_area_ptr_dummy = __afl_area_initial;
-u8 * __afl_area_ptr = __afl_area_initial;
-u8 * __afl_area_ptr_backup = __afl_area_initial;
-u8 * __afl_dictionary;
-u8 * __afl_fuzz_ptr;
-u32  __afl_fuzz_len_dummy;
-u32 *__afl_fuzz_len = &__afl_fuzz_len_dummy;
+static u8  __afl_area_initial[MAP_INITIAL_SIZE];
+static u8 *__afl_area_ptr_dummy = __afl_area_initial;
+static u8 *__afl_area_ptr_backup = __afl_area_initial;
+
+u8 *       __afl_area_ptr = __afl_area_initial;
+u8 *       __afl_dictionary;
+u8 *       __afl_fuzz_ptr;
+static u32 __afl_fuzz_len_dummy;
+u32 *      __afl_fuzz_len = &__afl_fuzz_len_dummy;
 
 u32 __afl_final_loc;
 u32 __afl_map_size = MAP_SIZE;
@@ -98,9 +99,9 @@ u32 __afl_dictionary_len;
 u64 __afl_map_addr;
 
 // for the __AFL_COVERAGE_ON/__AFL_COVERAGE_OFF features to work:
-int __afl_selective_coverage __attribute__((weak));
-int __afl_selective_coverage_start_off __attribute__((weak));
-int __afl_selective_coverage_temp = 1;
+int        __afl_selective_coverage __attribute__((weak));
+int        __afl_selective_coverage_start_off __attribute__((weak));
+static int __afl_selective_coverage_temp = 1;
 
 #if defined(__ANDROID__) || defined(__HAIKU__)
 PREV_LOC_T __afl_prev_loc[NGRAM_SIZE_MAX];
@@ -147,7 +148,7 @@ static int __afl_dummy_fd[2] = {2, 2};
 
 /* ensure we kill the child on termination */
 
-void at_exit(int signal) {
+static void at_exit(int signal) {
 
   if (child_pid > 0) { kill(child_pid, SIGKILL); }
 
@@ -179,7 +180,7 @@ void __afl_trace(const u32 x) {
 
 /* Error reporting to forkserver controller */
 
-void send_forkserver_error(int error) {
+static void send_forkserver_error(int error) {
 
   u32 status;
   if (!error || error > 0xffff) return;
@@ -629,6 +630,30 @@ static void __afl_unmap_shm(void) {
 
 }
 
+void write_error(char *text) {
+
+  u8 *  o = getenv("__AFL_OUT_DIR");
+  char *e = strerror(errno);
+
+  if (o) {
+
+    char buf[4096];
+    snprintf(buf, sizeof(buf), "%s/error.txt", o);
+    FILE *f = fopen(buf, "a");
+
+    if (f) {
+
+      fprintf(f, "Error(%s): %s\n", text, e);
+      fclose(f);
+
+    }
+
+  }
+
+  fprintf(stderr, "Error(%s): %s\n", text, e);
+
+}
+
 #ifdef __linux__
 static void __afl_start_snapshots(void) {
 
@@ -655,7 +680,12 @@ static void __afl_start_snapshots(void) {
 
   if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) {
 
-    if (read(FORKSRV_FD, &was_killed, 4) != 4) { _exit(1); }
+    if (read(FORKSRV_FD, &was_killed, 4) != 4) {
+
+      write_error("read to afl-fuzz");
+      _exit(1);
+
+    }
 
     if (__afl_debug) {
 
@@ -724,7 +754,12 @@ static void __afl_start_snapshots(void) {
     } else {
 
       /* Wait for parent by reading from the pipe. Abort if read fails. */
-      if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
+      if (read(FORKSRV_FD, &was_killed, 4) != 4) {
+
+        write_error("reading from afl-fuzz");
+        _exit(1);
+
+      }
 
     }
 
@@ -761,7 +796,12 @@ static void __afl_start_snapshots(void) {
     if (child_stopped && was_killed) {
 
       child_stopped = 0;
-      if (waitpid(child_pid, &status, 0) < 0) _exit(1);
+      if (waitpid(child_pid, &status, 0) < 0) {
+
+        write_error("child_stopped && was_killed");
+        _exit(1);  // TODO why exit?
+
+      }
 
     }
 
@@ -770,7 +810,12 @@ static void __afl_start_snapshots(void) {
       /* Once woken up, create a clone of our process. */
 
       child_pid = fork();
-      if (child_pid < 0) _exit(1);
+      if (child_pid < 0) {
+
+        write_error("fork");
+        _exit(1);
+
+      }
 
       /* In child process: close fds, resume execution. */
 
@@ -810,9 +855,19 @@ static void __afl_start_snapshots(void) {
 
     /* In parent process: write PID to pipe, then wait for child. */
 
-    if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1);
+    if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) {
+
+      write_error("write to afl-fuzz");
+      _exit(1);
+
+    }
+
+    if (waitpid(child_pid, &status, WUNTRACED) < 0) {
+
+      write_error("waitpid");
+      _exit(1);
 
-    if (waitpid(child_pid, &status, WUNTRACED) < 0) _exit(1);
+    }
 
     /* In persistent mode, the child stops itself with SIGSTOP to indicate
        a successful run. In this case, we want to wake it up without forking
@@ -822,7 +877,12 @@ static void __afl_start_snapshots(void) {
 
     /* Relay wait status to pipe, then loop back. */
 
-    if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1);
+    if (write(FORKSRV_FD + 1, &status, 4) != 4) {
+
+      write_error("writing to afl-fuzz");
+      _exit(1);
+
+    }
 
   }
 
@@ -955,7 +1015,12 @@ static void __afl_start_forkserver(void) {
 
     } else {
 
-      if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
+      if (read(FORKSRV_FD, &was_killed, 4) != 4) {
+
+        write_error("read from afl-fuzz");
+        _exit(1);
+
+      }
 
     }
 
@@ -992,7 +1057,12 @@ static void __afl_start_forkserver(void) {
     if (child_stopped && was_killed) {
 
       child_stopped = 0;
-      if (waitpid(child_pid, &status, 0) < 0) _exit(1);
+      if (waitpid(child_pid, &status, 0) < 0) {
+
+        write_error("child_stopped && was_killed");
+        _exit(1);
+
+      }
 
     }
 
@@ -1001,7 +1071,12 @@ static void __afl_start_forkserver(void) {
       /* Once woken up, create a clone of our process. */
 
       child_pid = fork();
-      if (child_pid < 0) _exit(1);
+      if (child_pid < 0) {
+
+        write_error("fork");
+        _exit(1);
+
+      }
 
       /* In child process: close fds, resume execution. */
 
@@ -1030,11 +1105,20 @@ static void __afl_start_forkserver(void) {
 
     /* In parent process: write PID to pipe, then wait for child. */
 
-    if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1);
+    if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) {
+
+      write_error("write to afl-fuzz");
+      _exit(1);
+
+    }
+
+    if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0) {
 
-    if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0)
+      write_error("waitpid");
       _exit(1);
 
+    }
+
     /* In persistent mode, the child stops itself with SIGSTOP to indicate
        a successful run. In this case, we want to wake it up without forking
        again. */
@@ -1043,7 +1127,12 @@ static void __afl_start_forkserver(void) {
 
     /* Relay wait status to pipe, then loop back. */
 
-    if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1);
+    if (write(FORKSRV_FD + 1, &status, 4) != 4) {
+
+      write_error("writing to afl-fuzz");
+      _exit(1);
+
+    }
 
   }
 
@@ -1668,7 +1757,7 @@ void __sanitizer_cov_trace_cmp4(uint32_t arg1, uint32_t arg2) {
 
 }
 
-void __sanitizer_cov_trace_cost_cmp4(uint32_t arg1, uint32_t arg2) {
+void __sanitizer_cov_trace_const_cmp4(uint32_t arg1, uint32_t arg2) {
 
   __cmplog_ins_hook4(arg1, arg2, 0);
 
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index aabdbf1a..d43278b9 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -225,6 +225,18 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
 
 }
 
+/* Handle timeout signal. */
+
+static void handle_timeout(int sig) {
+
+  (void)sig;
+
+  child_timed_out = 1;
+
+  if (child_pid > 0) kill(child_pid, SIGKILL);
+
+}
+
 /* Execute target application. Returns exec checksum, or 0 if program
    times out. */
 
@@ -904,6 +916,11 @@ static void setup_signal_handlers(void) {
   sigaction(SIGINT, &sa, NULL);
   sigaction(SIGTERM, &sa, NULL);
 
+  /* Exec timeout notifications. */
+
+  sa.sa_handler = handle_timeout;
+  sigaction(SIGALRM, &sa, NULL);
+
 }
 
 /* Display usage hints. */
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 486f7468..980e5d86 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -315,7 +315,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0,
      preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0,
-     have_c = 0;
+     have_c = 0, partial_linking = 0;
 
   cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
 
@@ -767,6 +767,8 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     if (!strcmp(cur, "-x")) x_set = 1;
     if (!strcmp(cur, "-E")) preprocessor_only = 1;
     if (!strcmp(cur, "-shared")) shared_linking = 1;
+    if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
+    if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
     if (!strcmp(cur, "-c")) have_c = 1;
 
     if (!strncmp(cur, "-O", 2)) have_o = 1;
@@ -996,7 +998,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     switch (bit_mode) {
 
       case 0:
-        if (!shared_linking)
+        if (!shared_linking && !partial_linking)
           cc_params[cc_par_cnt++] =
               alloc_printf("%s/afl-compiler-rt.o", obj_path);
         if (lto_mode)
@@ -1005,7 +1007,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
         break;
 
       case 32:
-        if (!shared_linking) {
+        if (!shared_linking && !partial_linking) {
 
           cc_params[cc_par_cnt++] =
               alloc_printf("%s/afl-compiler-rt-32.o", obj_path);
@@ -1026,7 +1028,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
         break;
 
       case 64:
-        if (!shared_linking) {
+        if (!shared_linking && !partial_linking) {
 
           cc_params[cc_par_cnt++] =
               alloc_printf("%s/afl-compiler-rt-64.o", obj_path);
@@ -1049,7 +1051,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
     }
 
   #if !defined(__APPLE__) && !defined(__sun)
-    if (!shared_linking)
+    if (!shared_linking && !partial_linking)
       cc_params[cc_par_cnt++] =
           alloc_printf("-Wl,--dynamic-list=%s/dynamic_list.txt", obj_path);
   #endif
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 88b5bc02..872e3a32 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -480,13 +480,22 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
 
   for (iter = 0; iter < afl->foreign_sync_cnt; iter++) {
 
-    if (afl->foreign_syncs[iter].dir != NULL &&
-        afl->foreign_syncs[iter].dir[0] != 0) {
+    if (afl->foreign_syncs[iter].dir && afl->foreign_syncs[iter].dir[0]) {
 
       if (first) ACTF("Scanning '%s'...", afl->foreign_syncs[iter].dir);
       time_t mtime_max = 0;
-      u8 *   name = strrchr(afl->foreign_syncs[iter].dir, '/');
-      if (!name) { name = afl->foreign_syncs[iter].dir; }
+
+      u8 *name = strrchr(afl->foreign_syncs[iter].dir, '/');
+      if (!name) {
+
+        name = afl->foreign_syncs[iter].dir;
+
+      } else {
+
+        ++name;
+
+      }
+
       if (!strcmp(name, "queue") || !strcmp(name, "out") ||
           !strcmp(name, "default")) {
 
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 4884b942..9648d795 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -766,9 +766,9 @@ void show_stats(afl_state_t *afl) {
                 "   uniq hangs : " cRST "%-6s" bSTG         bV "\n",
        time_tmp, tmp);
 
-  SAYF(bVR bH bSTOP                                          cCYA
-       " cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
-       " map coverage " bSTG bH bHT bH20 bH2                 bVL "\n");
+  SAYF(bVR bH bSTOP                                              cCYA
+       " cycle progress " bSTG bH10 bH5 bH2 bH2 bH2 bHB bH bSTOP cCYA
+       " map coverage" bSTG bHT bH20 bH2                         bVL "\n");
 
   /* This gets funny because we want to print several variable-length variables
      together, but then cram them into a fixed-width field - so we need to
@@ -778,13 +778,13 @@ void show_stats(afl_state_t *afl) {
           afl->queue_cur->favored ? "." : "*", afl->queue_cur->fuzz_level,
           ((double)afl->current_entry * 100) / afl->queued_paths);
 
-  SAYF(bV bSTOP "  now processing : " cRST "%-16s " bSTG bV bSTOP, tmp);
+  SAYF(bV bSTOP "  now processing : " cRST "%-18s " bSTG bV bSTOP, tmp);
 
   sprintf(tmp, "%0.02f%% / %0.02f%%",
           ((double)afl->queue_cur->bitmap_size) * 100 / afl->fsrv.map_size,
           t_byte_ratio);
 
-  SAYF("    map density : %s%-21s" bSTG bV "\n",
+  SAYF("    map density : %s%-19s" bSTG bV "\n",
        t_byte_ratio > 70
            ? cLRD
            : ((t_bytes < 200 && !afl->non_instrumented_mode) ? cPIN : cRST),
@@ -793,23 +793,23 @@ void show_stats(afl_state_t *afl) {
   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->cur_skipped_paths),
           ((double)afl->cur_skipped_paths * 100) / afl->queued_paths);
 
-  SAYF(bV bSTOP " paths timed out : " cRST "%-16s " bSTG bV, tmp);
+  SAYF(bV bSTOP " paths timed out : " cRST "%-18s " bSTG bV, tmp);
 
   sprintf(tmp, "%0.02f bits/tuple", t_bytes ? (((double)t_bits) / t_bytes) : 0);
 
-  SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
+  SAYF(bSTOP " count coverage : " cRST "%-19s" bSTG bV "\n", tmp);
 
-  SAYF(bVR bH bSTOP                                         cCYA
-       " stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
-       " findings in depth " bSTG bH10 bH5 bH2 bH2          bVL "\n");
+  SAYF(bVR bH bSTOP                                             cCYA
+       " stage progress " bSTG bH10 bH5 bH2 bH2 bH2 bX bH bSTOP cCYA
+       " findings in depth " bSTG bH10 bH5 bH2                  bVL "\n");
 
   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
           ((double)afl->queued_favored) * 100 / afl->queued_paths);
 
   /* Yeah... it's still going on... halp? */
 
-  SAYF(bV bSTOP "  now trying : " cRST "%-20s " bSTG bV bSTOP
-                " favored paths : " cRST "%-22s" bSTG   bV "\n",
+  SAYF(bV bSTOP "  now trying : " cRST "%-22s " bSTG bV bSTOP
+                " favored paths : " cRST "%-20s" bSTG   bV "\n",
        afl->stage_name, tmp);
 
   if (!afl->stage_max) {
@@ -824,12 +824,12 @@ void show_stats(afl_state_t *afl) {
 
   }
 
-  SAYF(bV bSTOP " stage execs : " cRST "%-21s" bSTG bV bSTOP, tmp);
+  SAYF(bV bSTOP " stage execs : " cRST "%-23s" bSTG bV bSTOP, tmp);
 
   sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_with_cov),
           ((double)afl->queued_with_cov) * 100 / afl->queued_paths);
 
-  SAYF("  new edges on : " cRST "%-22s" bSTG bV "\n", tmp);
+  SAYF("  new edges on : " cRST "%-20s" bSTG bV "\n", tmp);
 
   sprintf(tmp, "%s (%s%s unique)", u_stringify_int(IB(0), afl->total_crashes),
           u_stringify_int(IB(1), afl->unique_crashes),
@@ -837,14 +837,14 @@ void show_stats(afl_state_t *afl) {
 
   if (afl->crash_mode) {
 
-    SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP
-                  "   new crashes : %s%-22s" bSTG         bV "\n",
+    SAYF(bV bSTOP " total execs : " cRST "%-22s " bSTG bV bSTOP
+                  "   new crashes : %s%-20s" bSTG         bV "\n",
          u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
 
   } else {
 
-    SAYF(bV bSTOP " total execs : " cRST "%-20s " bSTG bV bSTOP
-                  " total crashes : %s%-22s" bSTG         bV "\n",
+    SAYF(bV bSTOP " total execs : " cRST "%-22s " bSTG bV bSTOP
+                  " total crashes : %s%-20s" bSTG         bV "\n",
          u_stringify_int(IB(0), afl->fsrv.total_execs), crash_color, tmp);
 
   }
@@ -856,12 +856,12 @@ void show_stats(afl_state_t *afl) {
     sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec),
             afl->stats_avg_exec < 20 ? "zzzz..." : "slow!");
 
-    SAYF(bV bSTOP "  exec speed : " cLRD "%-20s ", tmp);
+    SAYF(bV bSTOP "  exec speed : " cLRD "%-22s ", tmp);
 
   } else {
 
     sprintf(tmp, "%s/sec", u_stringify_float(IB(0), afl->stats_avg_exec));
-    SAYF(bV bSTOP "  exec speed : " cRST "%-20s ", tmp);
+    SAYF(bV bSTOP "  exec speed : " cRST "%-22s ", tmp);
 
   }
 
@@ -869,13 +869,12 @@ void show_stats(afl_state_t *afl) {
           u_stringify_int(IB(1), afl->unique_tmouts),
           (afl->unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
 
-  SAYF(bSTG bV bSTOP "  total tmouts : " cRST "%-22s" bSTG bV "\n", tmp);
+  SAYF(bSTG bV bSTOP "  total tmouts : " cRST "%-20s" bSTG bV "\n", tmp);
 
   /* Aaaalmost there... hold on! */
 
-  SAYF(bVR bH cCYA                                                     bSTOP
-       " fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
-       " path geometry " bSTG bH5 bH2 bVL "\n");
+  SAYF(bVR bH cCYA bSTOP " fuzzing strategy yields " bSTG bH10 bH2 bHT bH10 bH2
+           bH bHB bH bSTOP cCYA " path geometry " bSTG bH5 bH2 bVL "\n");
 
   if (unlikely(afl->custom_only)) {
 
@@ -1017,9 +1016,10 @@ void show_stats(afl_state_t *afl) {
   if (unlikely(afl->afl_env.afl_custom_mutator_library)) {
 
     strcat(tmp, " ");
-    strcat(tmp, u_stringify_int(IB(2), afl->stage_finds[STAGE_PYTHON]));
+    strcat(tmp, u_stringify_int(IB(2), afl->stage_finds[STAGE_CUSTOM_MUTATOR]));
     strcat(tmp, "/");
-    strcat(tmp, u_stringify_int(IB(3), afl->stage_cycles[STAGE_PYTHON]));
+    strcat(tmp,
+           u_stringify_int(IB(3), afl->stage_cycles[STAGE_CUSTOM_MUTATOR]));
     strcat(tmp, ",");
 
   } else {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 196547f4..9a3780fb 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -575,7 +575,6 @@ int main(int argc, char **argv_orig, char **envp) {
         }
 
         afl->sync_id = ck_strdup(optarg);
-        afl->skip_deterministic = 0;  // force deterministic fuzzing
         afl->old_seed_selection = 1;  // force old queue walking seed selection
         afl->disable_trim = 1;        // disable trimming
 
@@ -1206,6 +1205,8 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  setenv("__AFL_OUT_DIR", afl->out_dir, 1);
+
   if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; }
 
   if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI")) {
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index 1152cc4e..7cdc83cb 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -4,14 +4,6 @@
 
 $ECHO "$BLUE[*] Testing: llvm_mode, afl-showmap, afl-fuzz, afl-cmin and afl-tmin"
 test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
-  # on FreeBSD need to set AFL_CC
-  test `uname -s` = 'FreeBSD' && {
-    if type clang >/dev/null; then
-      export AFL_CC=`command -v clang`
-    else
-      export AFL_CC=`$LLVM_CONFIG --bindir`/clang
-    fi
-  }
   ../afl-clang-fast -o test-instr.plain ../test-instr.c > /dev/null 2>&1
   AFL_HARDEN=1 ../afl-clang-fast -o test-compcov.harden test-compcov.c > /dev/null 2>&1
   test -e test-instr.plain && {