about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md7
-rw-r--r--docs/Changelog.md21
-rw-r--r--src/afl-fuzz-init.c33
-rw-r--r--src/afl-fuzz-stats.c16
-rw-r--r--src/afl-fuzz.c33
5 files changed, 68 insertions, 42 deletions
diff --git a/README.md b/README.md
index 0539752c..119426f6 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,12 @@
   For comparisons use the fuzzbench `aflplusplus` setup, or use `afl-clang-fast`
   with `AFL_LLVM_CMPLOG=1`.
 
-## Major changes in afl++ 3.0
+## Major changes in afl++ 3.0 + 3.1
+
+With afl++ 3.1 we introduced the following changes from previous behaviours:
+  * The '+' feature of the '-t' option now means to  auto-calculate the timeout
+    with the value given being the maximum timeout. The original meaning of
+    "skipping timeouts instead of abort" is now inherent to the -t option.
 
 With afl++ 3.0 we introduced changes that break some previous afl and afl++
 behaviours and defaults:
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 9a61fac3..c4347baf 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -16,26 +16,31 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
     to be placed in the source code.
     Check out instrumentation/README.instrument_list.md
   - afl-fuzz
-    - Making AFL_MAP_SIZE (mostly) obsolete - afl-fuzz now learns on start
-      the target map size
+    - Making AFL_MAP_SIZE (mostly) obsolete - afl-fuzz now learns on
+      start the target map size
     - upgraded cmplog/redqueen: solving for floating point, solving
       transformations (e.g. toupper, tolower, to/from hex, xor,
       arithmetics, etc.). This is costly hence new command line option
-      `-l` that sets the intensity (values 1 to 3). Recommended is 1 or 2.
-    - added `AFL_CMPLOG_ONLY_NEW` to not use cmplog on initial testcases from
-      `-i` or resumes (as these have most likely already been done)
+      `-l` that sets the intensity (values 1 to 3). Recommended is 2.
+    - added `AFL_CMPLOG_ONLY_NEW` to not use cmplog on initial seeds
+      from `-i` or resumes (these have most likely already been done)
     - fix crash for very, very fast targets+systems (thanks to mhlakhani
       for reporting)
     - on restarts (`-i`)/autoresume (AFL_AUTORESUME) the stats are now
       reloaded and used, thanks to Vimal Joseph for this patch! 
-    - if deterministic mode is active (`-D`, or `-M` without `-d`) then we sync
-      after every queue entry as this can take very long time otherwise
+    - changed the meaning of '+' of the '-t' option, it now means to
+      auto-calculate the timeout with the value given being the max
+      timeout. The original meaning of skipping timeouts instead of
+      abort is now inherent to the -t option.
+    - if deterministic mode is active (`-D`, or `-M` without `-d`) then
+      we sync after every queue entry as this can take very long time
+      otherwise
+    - added minimum SYNC_TIME to include/config.h (30 minutes default)
     - better detection if a target needs a large shared map
     - fix for `-Z`
     - fixed a few crashes
     - switched to an even faster RNG
     - added hghwng's patch for faster trace map analysis
-    - added minimum SYNC_TIME to include/config.h (30 minutes default)
     - printing suggestions for mistyped `AFL_` env variables
   - afl-cc
     - allow instrumenting LLVMFuzzerTestOneInput
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index d85a83e0..3dbc4c65 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -882,32 +882,23 @@ void perform_dry_run(afl_state_t *afl) {
 
         if (afl->timeout_given) {
 
-          /* The -t nn+ syntax in the command line sets afl->timeout_given to
-             '2' and instructs afl-fuzz to tolerate but skip queue entries that
-             time out. */
+          /* if we have a timeout but a timeout value was given then always
+             skip. The '+' meaning has been changed! */
+          WARNF("Test case results in a timeout (skipping)");
+          ++cal_failures;
+          q->cal_failed = CAL_CHANCES;
+          q->disabled = 1;
+          q->perf_score = 0;
 
-          if (afl->timeout_given > 1) {
+          if (!q->was_fuzzed) {
 
-            WARNF("Test case results in a timeout (skipping)");
-            q->cal_failed = CAL_CHANCES;
-            ++cal_failures;
-            break;
+            q->was_fuzzed = 1;
+            --afl->pending_not_fuzzed;
+            --afl->active_paths;
 
           }
 
-          SAYF("\n" cLRD "[-] " cRST
-               "The program took more than %u ms to process one of the initial "
-               "test cases.\n"
-               "    Usually, the right thing to do is to relax the -t option - "
-               "or to delete it\n"
-               "    altogether and allow the fuzzer to auto-calibrate. That "
-               "said, if you know\n"
-               "    what you are doing and want to simply skip the unruly test "
-               "cases, append\n"
-               "    '+' at the end of the value passed to -t ('-t %u+').\n",
-               afl->fsrv.exec_tmout, afl->fsrv.exec_tmout);
-
-          FATAL("Test case '%s' results in a timeout", fn);
+          break;
 
         } else {
 
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 42c71b05..bd856088 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -388,13 +388,13 @@ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
      favored_not_fuzzed, unique_crashes, unique_hangs, max_depth,
      execs_per_sec, edges_found */
 
-  fprintf(
-      afl->fsrv.plot_file,
-      "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, %u\n",
-      get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry,
-      afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored,
-      bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth, eps,
-      afl->plot_prev_ed, t_bytes);                                  /* ignore errors */
+  fprintf(afl->fsrv.plot_file,
+          "%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f, %llu, "
+          "%u\n",
+          get_cur_time() / 1000, afl->queue_cycle - 1, afl->current_entry,
+          afl->queued_paths, afl->pending_not_fuzzed, afl->pending_favored,
+          bitmap_cvg, afl->unique_crashes, afl->unique_hangs, afl->max_depth,
+          eps, afl->plot_prev_ed, t_bytes);                /* ignore errors */
 
   fflush(afl->fsrv.plot_file);
 
@@ -1219,7 +1219,7 @@ void show_init_stats(afl_state_t *afl) {
       stringify_int(IB(0), min_us), stringify_int(IB(1), max_us),
       stringify_int(IB(2), avg_us));
 
-  if (!afl->timeout_given) {
+  if (afl->timeout_given != 1) {
 
     /* Figure out the appropriate timeout. The basic idea is: 5x average or
        1x max, rounded up to EXEC_TM_ROUND ms and capped at 1 second.
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 5810e9a9..a02eadb2 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -103,9 +103,10 @@ static void usage(u8 *argv0, int more_help) {
       "                  quad -- see docs/power_schedules.md\n"
       "  -f file       - location read by the fuzzed program (default: stdin "
       "or @@)\n"
-      "  -t msec       - timeout for each run (auto-scaled, 50-... ms, default "
-      "%u ms)\n"
-      "                  add a '+' to skip over seeds running longer.\n"
+      "  -t msec       - timeout for each run (auto-scaled, default %u ms). "
+      "Add a '+'\n"
+      "                  to auto-calculate the timeout, the value being the "
+      "maximum.\n"
       "  -m megs       - memory limit for child process (%u MB, 0 = no limit "
       "[default])\n"
       "  -Q            - use binary-only instrumentation (QEMU mode)\n"
@@ -1453,7 +1454,7 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  if (!afl->timeout_given) { find_timeout(afl); }
+  if (!afl->timeout_given) { find_timeout(afl); }  // only for resumes!
 
   if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL &&
       !afl->in_place_resume) {
@@ -1718,6 +1719,30 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  if (afl->timeout_given == 2) {  // -t ...+ option
+
+    if (valid_seeds == 1) {
+
+      WARNF(
+          "Only one valid seed is present, auto-calculating the timeout is "
+          "disabled!");
+      afl->timeout_given = 1;
+
+    } else {
+
+      u64 max_ms = 0;
+
+      for (entry = 0; entry < afl->queued_paths; ++entry)
+        if (!afl->queue_buf[entry]->disabled)
+          if (afl->queue_buf[entry]->exec_us > max_ms)
+            max_ms = afl->queue_buf[entry]->exec_us;
+
+      afl->fsrv.exec_tmout = max_ms;
+
+    }
+
+  }
+
   show_init_stats(afl);
 
   if (unlikely(afl->old_seed_selection)) seek_to = find_start_position(afl);