about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2023-03-17 12:47:33 +0100
committerGitHub <noreply@github.com>2023-03-17 12:47:33 +0100
commit24503fba5fd2580559223ec3c6ee408dfa15e080 (patch)
tree95826d4a61f3c423d0e70eb7f1da568dc793204b /src
parent2ff0ff7a903c57f9df5ed1e97370c187ec45a31e (diff)
parentd80cedcf02f56351bb08e7520ddcd76b0ff3f84e (diff)
downloadafl++-24503fba5fd2580559223ec3c6ee408dfa15e080.tar.gz
Merge pull request #1668 from AFLplusplus/dev
push to stable
Diffstat (limited to 'src')
-rw-r--r--src/afl-analyze.c4
-rw-r--r--src/afl-common.c75
-rw-r--r--src/afl-fuzz-bitmap.c42
-rw-r--r--src/afl-fuzz-init.c19
-rw-r--r--src/afl-fuzz-queue.c2
-rw-r--r--src/afl-fuzz-state.c22
-rw-r--r--src/afl-fuzz-stats.c31
-rw-r--r--src/afl-fuzz.c5
-rw-r--r--src/afl-showmap.c4
-rw-r--r--src/afl-tmin.c4
10 files changed, 148 insertions, 60 deletions
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index d4a9aa91..548956d8 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -725,7 +725,11 @@ static void setup_signal_handlers(void) {
   struct sigaction sa;
 
   sa.sa_handler = NULL;
+#ifdef SA_RESTART
   sa.sa_flags = SA_RESTART;
+#else
+  sa.sa_flags = 0;
+#endif
   sa.sa_sigaction = NULL;
 
   sigemptyset(&sa.sa_mask);
diff --git a/src/afl-common.c b/src/afl-common.c
index d83130b4..86226c9f 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -58,6 +58,25 @@ u8  last_intr = 0;
   #define AFL_PATH "/usr/local/lib/afl/"
 #endif
 
+void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle,
+                 size_t needlelen) {
+
+  if (unlikely(needlelen > haystacklen)) { return NULL; }
+
+  for (u32 i = 0; i <= haystacklen - needlelen; ++i) {
+
+    if (unlikely(memcmp(haystack + i, needle, needlelen) == 0)) {
+
+      return (void *)(haystack + i);
+
+    }
+
+  }
+
+  return (void *)NULL;
+
+}
+
 void set_sanitizer_defaults() {
 
   /* Set sane defaults for ASAN if nothing else is specified. */
@@ -66,23 +85,44 @@ void set_sanitizer_defaults() {
   u8 *have_msan_options = getenv("MSAN_OPTIONS");
   u8 *have_lsan_options = getenv("LSAN_OPTIONS");
   u8  have_san_options = 0;
+  u8  default_options[1024] =
+      "detect_odr_violation=0:abort_on_error=1:symbolize=0:allocator_may_"
+      "return_null=1:handle_segv=0:handle_sigbus=0:handle_abort=0:handle_"
+      "sigfpe=0:handle_sigill=0:";
+
   if (have_asan_options || have_ubsan_options || have_msan_options ||
-      have_lsan_options)
+      have_lsan_options) {
+
     have_san_options = 1;
-  u8 default_options[1024] =
-      "detect_odr_violation=0:abort_on_error=1:symbolize=0:malloc_context_"
-      "size=0:allocator_may_return_null=1:handle_segv=0:handle_sigbus=0:"
-      "handle_abort=0:handle_sigfpe=0:handle_sigill=0:";
 
-  if (!have_lsan_options) strcat(default_options, "detect_leaks=0:");
+  }
+
+  /* LSAN does not support abort_on_error=1. (is this still true??) */
+
+  if (!have_lsan_options) {
+
+    u8 buf[2048] = "";
+    if (!have_san_options) { strcpy(buf, default_options); }
+    strcat(buf, "exitcode=" STRINGIFY(LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:detect_leaks=1:malloc_context_size=30:");
+    setenv("LSAN_OPTIONS", buf, 1);
+
+  }
+
+  /* for everything not LSAN we disable detect_leaks */
+
+  if (!have_lsan_options) {
+
+    strcat(default_options, "detect_leaks=0:malloc_context_size=0:");
+
+  }
 
   /* Set sane defaults for ASAN if nothing else is specified. */
 
-  if (!have_san_options) setenv("ASAN_OPTIONS", default_options, 1);
+  if (!have_san_options) { setenv("ASAN_OPTIONS", default_options, 1); }
 
   /* Set sane defaults for UBSAN if nothing else is specified. */
 
-  if (!have_san_options) setenv("UBSAN_OPTIONS", default_options, 1);
+  if (!have_san_options) { setenv("UBSAN_OPTIONS", default_options, 1); }
 
   /* MSAN is tricky, because it doesn't support abort_on_error=1 at this
      point. So, we do this in a very hacky way. */
@@ -90,25 +130,12 @@ void set_sanitizer_defaults() {
   if (!have_msan_options) {
 
     u8 buf[2048] = "";
-    if (!have_san_options) strcpy(buf, default_options);
+    if (!have_san_options) { strcpy(buf, default_options); }
     strcat(buf, "exit_code=" STRINGIFY(MSAN_ERROR) ":msan_track_origins=0:");
     setenv("MSAN_OPTIONS", buf, 1);
 
   }
 
-  /* LSAN, too, does not support abort_on_error=1. (is this still true??) */
-
-  if (!have_lsan_options) {
-
-    u8 buf[2048] = "";
-    if (!have_san_options) strcpy(buf, default_options);
-    strcat(buf,
-           "exitcode=" STRINGIFY(
-               LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:");
-    setenv("LSAN_OPTIONS", buf, 1);
-
-  }
-
   /* Envs for QASan */
   setenv("QASAN_MAX_CALL_STACK", "0", 0);
   setenv("QASAN_SYMBOLIZE", "0", 0);
@@ -126,7 +153,7 @@ u32 check_binary_signatures(u8 *fn) {
   if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); }
   close(fd);
 
-  if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {
+  if (afl_memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {
 
     if (!be_quiet) { OKF(cPIN "Persistent mode binary detected."); }
     setenv(PERSIST_ENV_VAR, "1", 1);
@@ -151,7 +178,7 @@ u32 check_binary_signatures(u8 *fn) {
 
   }
 
-  if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {
+  if (afl_memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {
 
     if (!be_quiet) { OKF(cPIN "Deferred forkserver binary detected."); }
     setenv(DEFER_ENV_VAR, "1", 1);
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index b4e9537e..c65dd641 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -475,10 +475,13 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
      only be used for special schedules */
   if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
 
+    classify_counts(&afl->fsrv);
+    classified = 1;
+
     cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
     /* Saturated increment */
-    if (afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF)
+    if (likely(afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF))
       afl->n_fuzz[cksum % N_FUZZ_SIZE]++;
 
   }
@@ -488,7 +491,15 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
     /* Keep only if there are new bits in the map, add to queue for
        future fuzzing, etc. */
 
-    new_bits = has_new_bits_unclassified(afl, afl->virgin_bits);
+    if (likely(classified)) {
+
+      new_bits = has_new_bits(afl, afl->virgin_bits);
+
+    } else {
+
+      new_bits = has_new_bits_unclassified(afl, afl->virgin_bits);
+
+    }
 
     if (likely(!new_bits)) {
 
@@ -497,8 +508,6 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
     }
 
-    classified = new_bits;
-
   save_to_queue:
 
 #ifndef SIMPLE_FILES
@@ -556,21 +565,21 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
     }
 
-    /* AFLFast schedule? update the new queue entry */
-    if (cksum) {
+    if (unlikely(!classified && new_bits)) {
 
-      afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
-      afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
+      /* 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;
 
     }
 
-    /* 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);
+    /* For AFLFast schedules we update the new queue entry */
+    afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
+    afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
 
     /* Try to calibrate inline; this also calls update_bitmap_score() when
        successful. */
-
     res = calibrate_case(afl, afl->queue_top, mem, afl->queue_cycle - 1, 0);
 
     if (unlikely(res == FSRV_RUN_ERROR)) {
@@ -604,7 +613,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
       if (likely(!afl->non_instrumented_mode)) {
 
-        if (!classified) {
+        if (unlikely(!classified)) {
 
           classify_counts(&afl->fsrv);
           classified = 1;
@@ -729,7 +738,12 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
       if (likely(!afl->non_instrumented_mode)) {
 
-        if (!classified) { classify_counts(&afl->fsrv); }
+        if (unlikely(!classified)) {
+
+          classify_counts(&afl->fsrv);
+          classified = 1;
+
+        }
 
         simplify_trace(afl, afl->fsrv.trace_bits);
 
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index c20965b4..01d1e82e 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -24,7 +24,9 @@
  */
 
 #include "afl-fuzz.h"
+#include "common.h"
 #include <limits.h>
+#include <string.h>
 #include "cmplog.h"
 
 #ifdef HAVE_AFFINITY
@@ -2786,7 +2788,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
       !afl->fsrv.nyx_mode &&
 #endif
       !afl->fsrv.cs_mode && !afl->non_instrumented_mode &&
-      !memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
+      !afl_memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
 
     SAYF("\n" cLRD "[-] " cRST
          "Looks like the target binary is not instrumented! The fuzzer depends "
@@ -2817,7 +2819,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
   }
 
   if ((afl->fsrv.cs_mode || afl->fsrv.qemu_mode || afl->fsrv.frida_mode) &&
-      memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
+      afl_memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
 
     SAYF("\n" cLRD "[-] " cRST
          "This program appears to be instrumented with afl-gcc, but is being "
@@ -2830,9 +2832,9 @@ void check_binary(afl_state_t *afl, u8 *fname) {
 
   }
 
-  if (memmem(f_data, f_len, "__asan_init", 11) ||
-      memmem(f_data, f_len, "__msan_init", 11) ||
-      memmem(f_data, f_len, "__lsan_init", 11)) {
+  if (afl_memmem(f_data, f_len, "__asan_init", 11) ||
+      afl_memmem(f_data, f_len, "__msan_init", 11) ||
+      afl_memmem(f_data, f_len, "__lsan_init", 11)) {
 
     afl->fsrv.uses_asan = 1;
 
@@ -2840,7 +2842,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
 
   /* Detect persistent & deferred init signatures in the binary. */
 
-  if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {
+  if (afl_memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {
 
     OKF(cPIN "Persistent mode binary detected.");
     setenv(PERSIST_ENV_VAR, "1", 1);
@@ -2867,7 +2869,7 @@ void check_binary(afl_state_t *afl, u8 *fname) {
   }
 
   if (afl->fsrv.frida_mode ||
-      memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {
+      afl_memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {
 
     OKF(cPIN "Deferred forkserver binary detected.");
     setenv(DEFER_ENV_VAR, "1", 1);
@@ -2923,8 +2925,11 @@ void setup_signal_handlers(void) {
 
   struct sigaction sa;
 
+  memset((void *)&sa, 0, sizeof(sa));
   sa.sa_handler = NULL;
+#ifdef SA_RESTART
   sa.sa_flags = SA_RESTART;
+#endif
   sa.sa_sigaction = NULL;
 
   sigemptyset(&sa.sa_mask);
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 65446799..4eb55bb3 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -67,7 +67,7 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q,
   if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) {
 
     u32 hits = afl->n_fuzz[q->n_fuzz_entry];
-    if (likely(hits)) { weight *= (log10(hits) + 1); }
+    if (likely(hits)) { weight /= (log10(hits) + 1); }
 
   }
 
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 6d8c8758..f9aa5cfe 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -24,6 +24,7 @@
  */
 
 #include <signal.h>
+#include <limits.h>
 #include "afl-fuzz.h"
 #include "envs.h"
 
@@ -100,6 +101,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
   afl->hang_tmout = EXEC_TIMEOUT;
   afl->exit_on_time = 0;
   afl->stats_update_freq = 1;
+  afl->stats_file_update_freq_msecs = STATS_UPDATE_SEC * 1000;
   afl->stats_avg_exec = 0;
   afl->skip_deterministic = 1;
   afl->sync_time = SYNC_TIME;
@@ -565,6 +567,26 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
 
             }
 
+          } else if (!strncmp(env, "AFL_FUZZER_STATS_UPDATE_INTERVAL",
+
+                              afl_environment_variable_len)) {
+
+            u64 stats_update_freq_sec =
+                strtoull(get_afl_env(afl_environment_variables[i]), NULL, 0);
+            if (stats_update_freq_sec >= UINT_MAX ||
+                0 == stats_update_freq_sec) {
+
+              WARNF(
+                  "Incorrect value given to AFL_FUZZER_STATS_UPDATE_INTERVAL, "
+                  "using default of %d seconds\n",
+                  STATS_UPDATE_SEC);
+
+            } else {
+
+              afl->stats_file_update_freq_msecs = stats_update_freq_sec * 1000;
+
+            }
+
           }
 
         } else {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index bfd30845..f53fd610 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -62,7 +62,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
     if (memchr(argv[i], '\'', strlen(argv[i]))) {
 
 #else
-    if (index(argv[i], '\'')) {
+    if (strchr(argv[i], '\'')) {
 
 #endif
 
@@ -611,9 +611,10 @@ void show_stats_normal(afl_state_t *afl) {
 
   /* Roughly every minute, update fuzzer stats and save auto tokens. */
 
-  if (unlikely(!afl->non_instrumented_mode &&
-               (afl->force_ui_update ||
-                cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000))) {
+  if (unlikely(
+          !afl->non_instrumented_mode &&
+          (afl->force_ui_update || cur_ms - afl->stats_last_stats_ms >
+                                       afl->stats_file_update_freq_msecs))) {
 
     afl->stats_last_stats_ms = cur_ms;
     write_stats_file(afl, t_bytes, t_byte_ratio, stab_ratio,
@@ -669,9 +670,14 @@ void show_stats_normal(afl_state_t *afl) {
 
   /* AFL_EXIT_ON_TIME. */
 
-  if (unlikely(afl->last_find_time && !afl->non_instrumented_mode &&
-               afl->afl_env.afl_exit_on_time &&
-               (cur_ms - afl->last_find_time) > afl->exit_on_time)) {
+  /* If no coverage was found yet, check whether run time is greater than
+   * exit_on_time. */
+
+  if (unlikely(!afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time &&
+               ((afl->last_find_time &&
+                 (cur_ms - afl->last_find_time) > afl->exit_on_time) ||
+                (!afl->last_find_time &&
+                 (cur_ms - afl->start_time) > afl->exit_on_time)))) {
 
     afl->stop_soon = 2;
 
@@ -1470,12 +1476,11 @@ void show_stats_pizza(afl_state_t *afl) {
   /* If no coverage was found yet, check whether run time is greater than
    * exit_on_time. */
 
-  if (unlikely(
-          !afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time &&
-          ((afl->last_find_time &&
-            (cur_ms - afl->last_find_time) > afl->exit_on_time) ||
-           (!afl->last_find_time && (afl->prev_run_time + cur_ms -
-                                     afl->start_time) > afl->exit_on_time)))) {
+  if (unlikely(!afl->non_instrumented_mode && afl->afl_env.afl_exit_on_time &&
+               ((afl->last_find_time &&
+                 (cur_ms - afl->last_find_time) > afl->exit_on_time) ||
+                (!afl->last_find_time &&
+                 (cur_ms - afl->start_time) > afl->exit_on_time)))) {
 
     afl->stop_soon = 2;
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 4914ce0b..d7708fdf 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -210,7 +210,8 @@ static void usage(u8 *argv0, int more_help) {
       "  -b cpu_id     - bind the fuzzing process to the specified CPU core "
       "(0-...)\n"
       "  -e ext        - file extension for the fuzz test input file (if "
-      "needed)\n\n",
+      "needed)\n"
+      "\n",
       argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX);
 
   if (more_help > 1) {
@@ -312,6 +313,8 @@ static void usage(u8 *argv0, int more_help) {
       "                      afl-clang-lto/afl-gcc-fast target\n"
       "AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib\n"
       "AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a .so)\n"
+      "AFL_FUZZER_STATS_UPDATE_INTERVAL: interval to update fuzzer_stats file in seconds, "
+      "(default: 60, minimum: 1)\n"
       "\n"
     );
 
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 1e281d08..29abeb13 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -654,7 +654,11 @@ static void setup_signal_handlers(void) {
   struct sigaction sa;
 
   sa.sa_handler = NULL;
+#ifdef SA_RESTART
   sa.sa_flags = SA_RESTART;
+#else
+  sa.sa_flags = 0;
+#endif
   sa.sa_sigaction = NULL;
 
   sigemptyset(&sa.sa_mask);
diff --git a/src/afl-tmin.c b/src/afl-tmin.c
index 12c5e0c9..c0087f5f 100644
--- a/src/afl-tmin.c
+++ b/src/afl-tmin.c
@@ -743,7 +743,11 @@ static void setup_signal_handlers(void) {
   struct sigaction sa;
 
   sa.sa_handler = NULL;
+#ifdef SA_RESTART
   sa.sa_flags = SA_RESTART;
+#else
+  sa.sa_flags = 0;
+#endif
   sa.sa_sigaction = NULL;
 
   sigemptyset(&sa.sa_mask);