about summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-x.custom-format.py2
-rw-r--r--Dockerfile4
-rw-r--r--docs/Changelog.md6
-rw-r--r--docs/afl-fuzz_approach.md1
-rw-r--r--docs/env_variables.md2
-rw-r--r--include/afl-fuzz.h10
-rw-r--r--instrumentation/SanitizerCoverageLTO.so.cc6
-rw-r--r--instrumentation/afl-compiler-rt.o.c11
-rw-r--r--instrumentation/afl-llvm-common.cc3
-rw-r--r--src/afl-as.c22
-rw-r--r--src/afl-fuzz-bitmap.c10
-rw-r--r--src/afl-fuzz-mutators.c16
-rw-r--r--src/afl-fuzz-one.c9
-rw-r--r--src/afl-fuzz-python.c13
-rw-r--r--src/afl-fuzz-queue.c42
-rw-r--r--src/afl-fuzz-state.c10
-rw-r--r--src/afl-fuzz-stats.c52
-rw-r--r--src/afl-fuzz.c30
-rwxr-xr-xtest/test-basic.sh2
-rw-r--r--utils/aflpp_driver/GNUmakefile4
-rw-r--r--utils/aflpp_driver/aflpp_driver.c37
21 files changed, 213 insertions, 79 deletions
diff --git a/.custom-format.py b/.custom-format.py
index d07c26df..1295ce55 100755
--- a/.custom-format.py
+++ b/.custom-format.py
@@ -40,7 +40,7 @@ def check_clang_format_pip_version():
     if importlib.util.find_spec('clang_format'):
         # Check if the installed version is the expected LLVM version
         if importlib.metadata.version('clang-format')\
-                .startswith(CURRENT_LLVM+'.'):
+                .startswith(str(CURRENT_LLVM)+'.'):
             return True
         else:
             # Return False, because the clang-format version does not match
diff --git a/Dockerfile b/Dockerfile
index 59ce8778..4e53de40 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -67,6 +67,8 @@ RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_VERSION} 0
 RUN wget -qO- https://sh.rustup.rs | CARGO_HOME=/etc/cargo sh -s -- -y -q --no-modify-path
 ENV PATH=$PATH:/etc/cargo/bin
 
+RUN apt clean -y
+
 ENV LLVM_CONFIG=llvm-config-${LLVM_VERSION}
 ENV AFL_SKIP_CPUFREQ=1
 ENV AFL_TRY_AFFINITY=1
@@ -92,4 +94,4 @@ RUN sed -i.bak 's/^	-/	/g' GNUmakefile && \
 RUN echo "set encoding=utf-8" > /root/.vimrc && \
     echo ". /etc/bash_completion" >> ~/.bashrc && \
     echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \
-    echo "export PS1='"'[afl++ \h] \w$(__git_ps1) \$ '"'" >> ~/.bashrc
+    echo "export PS1='"'[afl++ \h] \w \$ '"'" >> ~/.bashrc
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 25c1f6bc..40c328ec 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -8,6 +8,12 @@
     - ensure temporary file descriptor is closed when not used
     - added `AFL_NO_WARN_INSTABILITY`
     - added `AFL_FRIDA_STATS_INTERVAL`
+    - added time_wo_finds to fuzzer_stats
+    - fixed a crash in pizza (1st april easter egg) mode. Sorry for
+      everyone who was affected!
+    - allow pizza mode to be disabled when AFL_PIZZA_MODE is set to -1
+    - add -z switch to prefer new coverage findings in seed selection
+    - print name of custom mutator in UI
   - afl-cc:
     - add CFI sanitizer variant to gcc targets
     - llvm 16 support (thanks to @devnexen!)
diff --git a/docs/afl-fuzz_approach.md b/docs/afl-fuzz_approach.md
index 6af39769..cb173f10 100644
--- a/docs/afl-fuzz_approach.md
+++ b/docs/afl-fuzz_approach.md
@@ -483,6 +483,7 @@ directory. This includes:
 - `fuzzer_pid`        - PID of the fuzzer process
 - `cycles_done`       - queue cycles completed so far
 - `cycles_wo_finds`   - number of cycles without any new paths found
+- `time_wo_finds`     - longest time in seconds no new path was found
 - `execs_done`        - number of execve() calls attempted
 - `execs_per_sec`     - overall number of execs per second
 - `corpus_count`      - total number of entries in the queue
diff --git a/docs/env_variables.md b/docs/env_variables.md
index c9dc1bbd..a6a0ae44 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -581,7 +581,7 @@ checks or alter some of the more exotic semantics of the tool:
     constructors in your target, you can set `AFL_EARLY_FORKSERVER`.
     Note that this is not a compile time option but a runtime option :-)
 
-  - Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to 0
+  - Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to -1
     to disable although it is 1st of April.
 
   - If you need a specific interval to update fuzzer_stats file, you can
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 6a8e8b5d..7ff3315b 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -398,8 +398,8 @@ typedef struct afl_env_vars {
       afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast,
       afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new,
       afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems,
-      afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme,
-      afl_ignore_timeouts, afl_no_startup_calibration, afl_no_warn_instability;
+      afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts,
+      afl_no_startup_calibration, afl_no_warn_instability;
 
   u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
       *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
@@ -408,6 +408,8 @@ typedef struct afl_env_vars {
       *afl_testcache_entries, *afl_child_kill_signal, *afl_fsrv_kill_signal,
       *afl_target_env, *afl_persistent_record, *afl_exit_on_time;
 
+  s32 afl_pizza_mode;
+
 } afl_env_vars_t;
 
 struct afl_pass_stat {
@@ -499,7 +501,8 @@ typedef struct afl_state {
       custom_splice_optout,             /* Custom mutator no splice buffer  */
       is_main_node,                     /* if this is the main node         */
       is_secondary_node,                /* if this is a secondary instance  */
-      pizza_is_served;                  /* pizza mode                       */
+      pizza_is_served,                  /* pizza mode                       */
+      prefer_new;                       /* prefer new queue entries         */
 
   u32 stats_update_freq;                /* Stats update frequency (execs)   */
 
@@ -591,6 +594,7 @@ typedef struct afl_state {
       last_find_time,                   /* Time for most recent path (ms)   */
       last_crash_time,                  /* Time for most recent crash (ms)  */
       last_hang_time,                   /* Time for most recent hang (ms)   */
+      longest_find_time,                /* Longest time taken for a find    */
       exit_on_time,                     /* Delay to exit if no new paths    */
       sync_time;                        /* Sync time (ms)                   */
 
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index f82224ed..9691f17f 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -431,6 +431,8 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
     if ((afl_global_id = atoi(ptr)) < 0)
       FATAL("AFL_LLVM_LTO_STARTID value of \"%s\" is negative\n", ptr);
 
+  if (afl_global_id < 4) { afl_global_id = 4; }
+
   if ((ptr = getenv("AFL_LLVM_DOCUMENT_IDS")) != NULL) {
 
     dFile.open(ptr, std::ofstream::out | std::ofstream::app);
@@ -1787,14 +1789,16 @@ static void registerLTOPass(const PassManagerBuilder &,
 
 }
 
+#if LLVM_VERSION_MAJOR < 16
 static RegisterStandardPasses RegisterCompTransPass(
     PassManagerBuilder::EP_OptimizerLast, registerLTOPass);
 
 static RegisterStandardPasses RegisterCompTransPass0(
     PassManagerBuilder::EP_EnabledOnOptLevel0, registerLTOPass);
 
-#if LLVM_VERSION_MAJOR >= 11
+  #if LLVM_VERSION_MAJOR >= 11
 static RegisterStandardPasses RegisterCompTransPassLTO(
     PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerLTOPass);
+  #endif
 #endif
 
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index a88396d4..26fc7256 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1536,7 +1536,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
 
   }
 
-  if (start == stop || *start) return;
+  if (start == stop || *start) { return; }
 
   x = getenv("AFL_INST_RATIO");
   if (x) {
@@ -1563,12 +1563,13 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
           "[-] FATAL: forkserver is already up, but an instrumented dlopen() "
           "library loaded afterwards. You must AFL_PRELOAD such libraries to "
           "be able to fuzz them or LD_PRELOAD to run outside of afl-fuzz.\n"
-          "To ignore this set AFL_IGNORE_PROBLEMS=1.\n");
+          "To ignore this set AFL_IGNORE_PROBLEMS=1 but this will be bad for "
+          "coverage.\n");
       abort();
 
     } else {
 
-      static u32 offset = 4;
+      static u32 offset = 5;
 
       while (start < stop) {
 
@@ -1582,7 +1583,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
 
         }
 
-        if (unlikely(++offset >= __afl_final_loc)) { offset = 4; }
+        if (unlikely(++offset >= __afl_final_loc)) { offset = 5; }
 
       }
 
@@ -1596,7 +1597,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
      to avoid duplicate calls (which can happen as an artifact of the underlying
      implementation in LLVM). */
 
-  if (__afl_final_loc < 3) __afl_final_loc = 3;  // we skip the first 4 entries
+  if (__afl_final_loc < 5) __afl_final_loc = 5;  // we skip the first 5 entries
 
   *(start++) = ++__afl_final_loc;
 
diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc
index dc34d191..de334fb7 100644
--- a/instrumentation/afl-llvm-common.cc
+++ b/instrumentation/afl-llvm-common.cc
@@ -289,6 +289,9 @@ void scanForDangerousFunctions(llvm::Module *M) {
 
     StringRef ifunc_name = IF.getName();
     Constant *r = IF.getResolver();
+    if(r->getNumOperands() == 0){
+      continue ;
+    }
     StringRef r_name = cast<Function>(r->getOperand(0))->getName();
     if (!be_quiet)
       fprintf(stderr,
diff --git a/src/afl-as.c b/src/afl-as.c
index a0eb612f..772e31b3 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -93,7 +93,7 @@ static u8 use_64bit = 0;
 static void edit_params(int argc, char **argv) {
 
   u8 *tmp_dir = getenv("TMPDIR"), *afl_as = getenv("AFL_AS");
-  u32 i;
+  u32 i, input_index;
 
 #ifdef __APPLE__
 
@@ -142,7 +142,23 @@ static void edit_params(int argc, char **argv) {
 
   as_params[argc] = 0;
 
-  for (i = 1; (s32)i < argc - 1; i++) {
+  /* Find the input file.  It's usually located near the end.
+     Assume there won't be any arguments referring to files after the input
+     file, e.g. as input.s -o output.o */
+  for (input_index = argc - 1; input_index > 0; input_index--) {
+
+    input_file = argv[input_index];
+    /* Clang may add debug arguments after the input file. */
+    if (strncmp(input_file, "-g", 2)) break;
+
+  }
+
+  if (input_index == 0)
+    FATAL("Could not find input file (not called through afl-gcc?)");
+
+  for (i = 1; (s32)i < argc; i++) {
+
+    if (i == input_index) continue;
 
     if (!strcmp(argv[i], "--64")) {
 
@@ -194,8 +210,6 @@ static void edit_params(int argc, char **argv) {
 
 #endif                                                         /* __APPLE__ */
 
-  input_file = argv[argc - 1];
-
   if (input_file[0] == '-') {
 
     if (!strcmp(input_file + 1, "-version")) {
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index d9c792d1..556bb5d1 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -465,7 +465,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
   u8  fn[PATH_MAX];
   u8 *queue_fn = "";
-  u8  new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0;
+  u8  new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0,
+     need_hash = 1;
   s32 fd;
   u64 cksum = 0;
 
@@ -477,6 +478,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
     classify_counts(&afl->fsrv);
     classified = 1;
+    need_hash = 0;
 
     cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
@@ -499,6 +501,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
       new_bits = has_new_bits_unclassified(afl, afl->virgin_bits);
 
+      if (unlikely(new_bits)) { classified = 1; }
+
     }
 
     if (likely(!new_bits)) {
@@ -565,12 +569,12 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
     }
 
-    if (unlikely(!classified && new_bits)) {
+    if (unlikely(need_hash && new_bits)) {
 
       /* due to classify counts we have to recalculate the checksum */
       afl->queue_top->exec_cksum =
           hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
-      classified = 1;
+      need_hash = 0;
 
     }
 
diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c
index 9ea46e7a..64dbe7c6 100644
--- a/src/afl-fuzz-mutators.c
+++ b/src/afl-fuzz-mutators.c
@@ -179,11 +179,19 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
   void                  *dh;
   struct custom_mutator *mutator = ck_alloc(sizeof(struct custom_mutator));
 
-  mutator->name = fn;
-  if (memchr(fn, '/', strlen(fn)))
-    mutator->name_short = strrchr(fn, '/') + 1;
-  else
+  if (memchr(fn, '/', strlen(fn))) {
+
+    mutator->name_short = strdup(strrchr(fn, '/') + 1);
+
+  } else {
+
     mutator->name_short = strdup(fn);
+
+  }
+
+  if (strlen(mutator->name_short) > 22) { mutator->name_short[21] = 0; }
+
+  mutator->name = fn;
   ACTF("Loading custom mutator library from '%s'...", fn);
 
   dh = dlopen(fn, RTLD_NOW);
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index be526dbd..ee562f96 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1931,6 +1931,7 @@ custom_mutator_stage:
     if (el->afl_custom_fuzz) {
 
       afl->current_custom_fuzz = el;
+      afl->stage_name = el->name_short;
 
       if (el->afl_custom_fuzz_count) {
 
@@ -2071,7 +2072,7 @@ havoc_stage:
     afl->stage_short = "havoc";
     afl->stage_max = ((doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) *
                       perf_score / afl->havoc_div) >>
-                     7;
+                     8;
 
   } else {
 
@@ -2080,11 +2081,11 @@ havoc_stage:
     snprintf(afl->stage_name_buf, STAGE_BUF_SIZE, "splice %u", splice_cycle);
     afl->stage_name = afl->stage_name_buf;
     afl->stage_short = "splice";
-    afl->stage_max = (SPLICE_HAVOC * perf_score / afl->havoc_div) >> 7;
+    afl->stage_max = (SPLICE_HAVOC * perf_score / afl->havoc_div) >> 8;
 
   }
 
-  if (afl->stage_max < HAVOC_MIN) { afl->stage_max = HAVOC_MIN; }
+  if (unlikely(afl->stage_max < HAVOC_MIN)) { afl->stage_max = HAVOC_MIN; }
 
   temp_len = len;
 
@@ -4640,7 +4641,7 @@ pacemaker_fuzzing:
              MOpt_globals.splice_stageformat, splice_cycle);
     afl->stage_name = afl->stage_name_buf;
     afl->stage_short = MOpt_globals.splice_stagenameshort;
-    afl->stage_max = (SPLICE_HAVOC * perf_score / afl->havoc_div) >> 7;
+    afl->stage_max = (SPLICE_HAVOC * perf_score / afl->havoc_div) >> 8;
 
   }
 
diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c
index 2799268b..673e5a6c 100644
--- a/src/afl-fuzz-python.c
+++ b/src/afl-fuzz-python.c
@@ -414,10 +414,21 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl,
   struct custom_mutator *mutator;
 
   mutator = ck_alloc(sizeof(struct custom_mutator));
-
   mutator->name = module_name;
   ACTF("Loading Python mutator library from '%s'...", module_name);
 
+  if (memchr(module_name, '/', strlen(module_name))) {
+
+    mutator->name_short = strdup(strrchr(module_name, '/') + 1);
+
+  } else {
+
+    mutator->name_short = strdup(module_name);
+
+  }
+
+  if (strlen(mutator->name_short) > 22) { mutator->name_short[21] = 0; }
+
   py_mutator_t *py_mutator;
   py_mutator = init_py_module(afl, module_name);
   mutator->data = py_mutator;
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 4eb55bb3..6fc3c743 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -74,7 +74,8 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q,
   if (likely(afl->schedule < RARE)) { weight *= (avg_exec_us / q->exec_us); }
   weight *= (log(q->bitmap_size) / avg_bitmap_size);
   weight *= (1 + (q->tc_ref / avg_top_size));
-  if (unlikely(weight < 1.0)) { weight = 1.0; }
+
+  if (unlikely(weight < 0.1)) { weight = 0.1; }
   if (unlikely(q->favored)) { weight *= 5; }
   if (unlikely(!q->was_fuzzed)) { weight *= 2; }
 
@@ -148,6 +149,26 @@ void create_alias_table(afl_state_t *afl) {
 
     }
 
+    if (unlikely(afl->prefer_new) && afl->queued_discovered) {
+
+      double avg_weight = sum / active;
+
+      for (i = n - afl->queued_discovered; i < n; i++) {
+
+        struct queue_entry *q = afl->queue_buf[i];
+
+        if (likely(!q->disabled) && q->weight > avg_weight) {
+
+          double prev_weight = q->weight;
+          q->weight *= (2.0 * (i / n));
+          sum += (q->weight - prev_weight);
+
+        }
+
+      }
+
+    }
+
     for (i = 0; i < n; i++) {
 
       // weight is always 0 for disabled entries
@@ -577,7 +598,24 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
   queue_buf[afl->queued_items - 1] = q;
   q->id = afl->queued_items - 1;
 
-  afl->last_find_time = get_cur_time();
+  u64 cur_time = get_cur_time();
+
+  if (likely(afl->start_time) &&
+      unlikely(afl->longest_find_time < cur_time - afl->last_find_time)) {
+
+    if (unlikely(!afl->last_find_time)) {
+
+      afl->longest_find_time = cur_time - afl->start_time;
+
+    } else {
+
+      afl->longest_find_time = cur_time - afl->last_find_time;
+
+    }
+
+  }
+
+  afl->last_find_time = cur_time;
 
   if (afl->custom_mutators_count) {
 
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index f9aa5cfe..46b67def 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -648,7 +648,15 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
 
   }
 
-  if (afl->afl_env.afl_pizza_mode) { afl->pizza_is_served = 1; }
+  if (afl->afl_env.afl_pizza_mode > 0) {
+
+    afl->pizza_is_served = 1;
+
+  } else if (afl->afl_env.afl_pizza_mode < 0) {
+
+    OKF("Pizza easter egg mode is now disabled.");
+
+  }
 
   if (issue_detected) { sleep(2); }
 
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index f53fd610..07157bf7 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -251,6 +251,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
       "fuzzer_pid        : %u\n"
       "cycles_done       : %llu\n"
       "cycles_wo_finds   : %llu\n"
+      "time_wo_finds     : %llu\n"
       "execs_done        : %llu\n"
       "execs_per_sec     : %0.02f\n"
       "execs_ps_last_min : %0.02f\n"
@@ -291,6 +292,11 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
       (afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000,
       (afl->prev_run_time + cur_time - afl->start_time) / 1000, (u32)getpid(),
       afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds,
+      afl->longest_find_time > cur_time - afl->last_find_time
+          ? afl->longest_find_time / 1000
+          : ((afl->start_time == 0 || afl->last_find_time == 0)
+                 ? 0
+                 : (cur_time - afl->last_find_time) / 1000),
       afl->fsrv.total_execs,
       afl->fsrv.total_execs /
           ((double)(afl->prev_run_time + get_cur_time() - afl->start_time) /
@@ -747,20 +753,20 @@ void show_stats_normal(afl_state_t *afl) {
 #ifdef __linux__
     if (afl->fsrv.nyx_mode) {
 
-      sprintf(banner + banner_pad,
-              "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
-              afl->crash_mode ? cPIN "peruvian were-rabbit"
-                              : cYEL "american fuzzy lop",
-              si, afl->use_banner, afl->power_name);
+      snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
+               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
+               afl->crash_mode ? cPIN "peruvian were-rabbit"
+                               : cYEL "american fuzzy lop",
+               si, afl->use_banner, afl->power_name);
 
     } else {
 
 #endif
-      sprintf(banner + banner_pad,
-              "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
-              afl->crash_mode ? cPIN "peruvian were-rabbit"
-                              : cYEL "american fuzzy lop",
-              si, afl->use_banner, afl->power_name);
+      snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
+               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
+               afl->crash_mode ? cPIN "peruvian were-rabbit"
+                               : cYEL "american fuzzy lop",
+               si, afl->use_banner, afl->power_name);
 
 #ifdef __linux__
 
@@ -1551,20 +1557,22 @@ void show_stats_pizza(afl_state_t *afl) {
 #ifdef __linux__
     if (afl->fsrv.nyx_mode) {
 
-      sprintf(banner + banner_pad,
-              "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
-              afl->crash_mode ? cPIN "Mozzarbella Pizzeria table booking system"
-                              : cYEL "Mozzarbella Pizzeria management system",
-              si, afl->use_banner, afl->power_name);
+      snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
+               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
+               afl->crash_mode ? cPIN
+                   "Mozzarbella Pizzeria table booking system"
+                               : cYEL "Mozzarbella Pizzeria management system",
+               si, afl->use_banner, afl->power_name);
 
     } else {
 
 #endif
-      sprintf(banner + banner_pad,
-              "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
-              afl->crash_mode ? cPIN "Mozzarbella Pizzeria table booking system"
-                              : cYEL "Mozzarbella Pizzeria management system",
-              si, afl->use_banner, afl->power_name);
+      snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
+               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
+               afl->crash_mode ? cPIN
+                   "Mozzarbella Pizzeria table booking system"
+                               : cYEL "Mozzarbella Pizzeria management system",
+               si, afl->use_banner, afl->power_name);
 
 #ifdef __linux__
 
@@ -1795,10 +1803,10 @@ void show_stats_pizza(afl_state_t *afl) {
 
   /* Show a warning about slow execution. */
 
-  if (afl->stats_avg_exec < 100) {
+  if (afl->stats_avg_exec < 20) {
 
     sprintf(tmp, "%s/sec (%s)", u_stringify_float(IB(0), afl->stats_avg_exec),
-            afl->stats_avg_exec < 20 ? "zzzz..." : "Gennarino is at it again!");
+            "zzzz...");
 
     SAYF(bV bSTOP "                pizza making speed : " cLRD
                   "%-22s                ",
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index d7708fdf..c7eb985c 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -132,6 +132,7 @@ static void usage(u8 *argv0, int more_help) {
       "                  fast(default), explore, exploit, seek, rare, mmopt, "
       "coe, lin\n"
       "                  quad -- see docs/FAQ.md for more information\n"
+      "  -z            - prefer new coverage findings when fuzzing\n"
       "  -f file       - location read by the fuzzed program (default: stdin "
       "or @@)\n"
       "  -t msec       - timeout for each run (auto-scaled, default %u ms). "
@@ -556,7 +557,7 @@ int main(int argc, char **argv_orig, char **envp) {
   while (
       (opt = getopt(
            argc, argv,
-           "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) >
+           "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YzZ")) >
       0) {
 
     switch (opt) {
@@ -569,6 +570,10 @@ int main(int argc, char **argv_orig, char **envp) {
         afl->max_length = atoi(optarg);
         break;
 
+      case 'z':
+        afl->prefer_new = 1;
+        break;
+
       case 'Z':
         afl->old_seed_selection = 1;
         break;
@@ -1344,8 +1349,7 @@ int main(int argc, char **argv_orig, char **envp) {
       "Eißfeldt, Andrea Fioraldi and Dominik Maier");
   OKF("afl++ is open source, get it at "
       "https://github.com/AFLplusplus/AFLplusplus");
-  OKF("NOTE: This is v3.x which changes defaults and behaviours - see "
-      "README.md");
+  OKF("NOTE: afl++ >= v3 has changed defaults and behaviours - see README.md");
 
   #ifdef __linux__
   if (afl->fsrv.nyx_mode) {
@@ -2497,10 +2501,22 @@ int main(int argc, char **argv_orig, char **envp) {
       }
 
   #ifdef INTROSPECTION
-      fprintf(afl->introspection_file,
-              "CYCLE cycle=%llu cycle_wo_finds=%llu expand_havoc=%u queue=%u\n",
-              afl->queue_cycle, afl->cycles_wo_finds, afl->expand_havoc,
-              afl->queued_items);
+      {
+
+        u64 cur_time = get_cur_time();
+        fprintf(afl->introspection_file,
+                "CYCLE cycle=%llu cycle_wo_finds=%llu time_wo_finds=%llu "
+                "expand_havoc=%u queue=%u\n",
+                afl->queue_cycle, afl->cycles_wo_finds,
+                afl->longest_find_time > cur_time - afl->last_find_time
+                    ? afl->longest_find_time / 1000
+                    : ((afl->start_time == 0 || afl->last_find_time == 0)
+                           ? 0
+                           : (cur_time - afl->last_find_time) / 1000),
+                afl->expand_havoc, afl->queued_items);
+
+      }
+
   #endif
 
       if (afl->cycle_schedules) {
diff --git a/test/test-basic.sh b/test/test-basic.sh
index 53de8c64..5bb2ca28 100755
--- a/test/test-basic.sh
+++ b/test/test-basic.sh
@@ -133,7 +133,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
  SKIP=
  test -e ../${AFL_CLANG} -a -e ../afl-showmap -a -e ../afl-fuzz && {
   ../${AFL_CLANG} -v 2>&1 | grep -qi "clang version" && {
-   ../${AFL_CLANG} -o test-instr.plain -O0 ../test-instr.c > /dev/null 2>&1
+   ../${AFL_CLANG} -O0 -o test-instr.plain ../test-instr.c > /dev/null 2>&1
    AFL_HARDEN=1 ../${AFL_CLANG} -o test-compcov.harden test-compcov.c > /dev/null 2>&1
    test -e test-instr.plain && {
     $ECHO "$GREEN[+] ${AFL_CLANG} compilation succeeded"
diff --git a/utils/aflpp_driver/GNUmakefile b/utils/aflpp_driver/GNUmakefile
index b973f96a..409789cb 100644
--- a/utils/aflpp_driver/GNUmakefile
+++ b/utils/aflpp_driver/GNUmakefile
@@ -20,6 +20,10 @@ endif
 
 CFLAGS := -O3 -funroll-loops -g -fPIC
 
+ifdef MAGMA_PATCH
+	CFLAGS += -DMAGMA_PATCH
+endif
+
 all:	libAFLDriver.a libAFLQemuDriver.a aflpp_qemu_driver_hook.so
 
 aflpp_driver.o:	aflpp_driver.c
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index f08c9864..5fef4730 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -1,12 +1,14 @@
-//===- afl_driver.cpp - a glue between AFL++ and libFuzzer ------*- C++ -* ===//
-//===----------------------------------------------------------------------===//
+//
+// afl_driver.cpp - a glue between AFL++ and libFuzzer
+//
 
 /* This file allows to fuzz libFuzzer-style target functions
  (LLVMFuzzerTestOneInput) with AFL++ using persistent in-memory fuzzing.
 
 Usage:
-################################################################################
-cat << EOF > test_fuzzer.cc
+
+# Example target:
+$ cat << EOF > test_fuzzer.cc
 #include <stddef.h>
 #include <stdint.h>
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
@@ -20,16 +22,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
 }
 
 EOF
-# Build your target with -fsanitize-coverage=trace-pc-guard using fresh clang.
-clang -c aflpp_driver.c
-# Build afl-compiler-rt.o.c from the AFL distribution.
-clang -c $AFL_HOME/instrumentation/afl-compiler-rt.o.c
-# Build this file, link it with afl-compiler-rt.o.o and the target code.
-afl-clang-fast -o test_fuzzer test_fuzzer.cc afl-compiler-rt.o aflpp_driver.o
+
+# Build your target with afl-cc -fsanitize=fuzzer
+$ afl-c++ -fsanitize=fuzzer -o test_fuzzer test_fuzzer.cc
 # Run AFL:
-rm -rf IN OUT; mkdir IN OUT; echo z > IN/z;
-$AFL_HOME/afl-fuzz -i IN -o OUT ./a.out
-################################################################################
+$ rm -rf in out; mkdir in out; echo z > in/foo;
+$ afl-fuzz -i in -o out -- ./test_fuzzer
+
 */
 
 #include <assert.h>
@@ -71,8 +70,8 @@ extern unsigned int   __afl_map_size;
 __attribute__((weak)) int LLVMFuzzerTestOneInput(const uint8_t *Data,
                                                  size_t         Size);
 __attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
-int                       LLVMFuzzerRunDriver(int *argc, char ***argv,
-                                              int (*callback)(const uint8_t *data, size_t size));
+__attribute__((weak)) int LLVMFuzzerRunDriver(
+    int *argc, char ***argv, int (*callback)(const uint8_t *data, size_t size));
 
 // Default nop ASan hooks for manual poisoning when not linking the ASan
 // runtime
@@ -196,7 +195,8 @@ static void maybe_close_fd_mask() {
 
 // Define LLVMFuzzerMutate to avoid link failures for targets that use it
 // with libFuzzer's LLVMFuzzerCustomMutator.
-size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
+__attribute__((weak)) size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size,
+                                              size_t MaxSize) {
 
   // assert(false && "LLVMFuzzerMutate should not be called from afl_driver");
   return 0;
@@ -280,8 +280,9 @@ __attribute__((weak)) int main(int argc, char **argv) {
 
 }
 
-int LLVMFuzzerRunDriver(int *argcp, char ***argvp,
-                        int (*callback)(const uint8_t *data, size_t size)) {
+__attribute__((weak)) int LLVMFuzzerRunDriver(
+    int *argcp, char ***argvp,
+    int (*callback)(const uint8_t *data, size_t size)) {
 
   int    argc = *argcp;
   char **argv = *argvp;