about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--docs/Changelog.md1
-rw-r--r--include/afl-fuzz.h5
-rw-r--r--instrumentation/afl-llvm-dict2file.so.cc14
-rw-r--r--instrumentation/cmplog-instructions-pass.cc6
-rw-r--r--instrumentation/cmplog-routines-pass.cc11
-rw-r--r--instrumentation/compare-transform-pass.so.cc24
-rw-r--r--instrumentation/split-compares-pass.so.cc47
-rw-r--r--instrumentation/split-switches-pass.so.cc21
-rw-r--r--src/afl-fuzz-bitmap.c13
-rw-r--r--src/afl-fuzz-init.c4
-rw-r--r--src/afl-fuzz-queue.c30
-rw-r--r--src/afl-fuzz.c2
12 files changed, 104 insertions, 74 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 789b1f74..0f923423 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -14,6 +14,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
   - all compilers combined to afl-cc which emulates the previous ones
   - afl-llvm/gcc-rt.o merged into afl-compiler-rt.o
   - afl-fuzz
+    - Marcel Boehme submitted a patch that improves all AFFast schedules :)
     - reading testcases from -i now descends into subdirectories
     - allow up to 4 -x command line options
     - loaded extras now have a duplicate protection
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index f65fc40f..fb661ce5 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -151,7 +151,8 @@ struct queue_entry {
       is_ascii;                         /* Is the input just ascii text?    */
 
   u32 bitmap_size,                      /* Number of bits set in bitmap     */
-      fuzz_level;                       /* Number of fuzzing iterations     */
+      fuzz_level,                       /* Number of fuzzing iterations     */
+      n_fuzz_entry;                     /* offset in n_fuzz                 */
 
   u64 exec_us,                          /* Execution time (us)              */
       handicap,                         /* Number of queue cycles behind    */
@@ -491,7 +492,7 @@ typedef struct afl_state {
 
   u8 *var_bytes;                        /* Bytes that appear to be variable */
 
-  #define n_fuzz_size (1 << 21)
+#define N_FUZZ_SIZE (1 << 21)
   u32 *n_fuzz;
 
   volatile u8 stop_soon,                /* Ctrl-C pressed?                  */
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index e04ebda8..bd8eb27a 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -381,8 +381,9 @@ bool AFLdict2filePass::runOnModule(Module &M) {
 
           if (debug)
             fprintf(stderr, "F:%s %p(%s)->\"%s\"(%s) %p(%s)->\"%s\"(%s)\n",
-                    FuncName.c_str(), (void*)Str1P, Str1P->getName().str().c_str(),
-                    Str1.c_str(), HasStr1 == true ? "true" : "false", (void*)Str2P,
+                    FuncName.c_str(), (void *)Str1P,
+                    Str1P->getName().str().c_str(), Str1.c_str(),
+                    HasStr1 == true ? "true" : "false", (void *)Str2P,
                     Str2P->getName().str().c_str(), Str2.c_str(),
                     HasStr2 == true ? "true" : "false");
 
@@ -436,7 +437,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
               valueMap[Str1P] = new std::string(Str2);
 
               if (debug)
-                fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), (void*)Str1P);
+                fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(),
+                        (void *)Str1P);
               continue;
 
             }
@@ -455,7 +457,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
               Str2 = *strng;
               HasStr2 = true;
               if (debug)
-                fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(), (void*)Str2P);
+                fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(),
+                        (void *)Str2P);
 
             }
 
@@ -497,7 +500,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
               Str1 = *strng;
               HasStr1 = true;
               if (debug)
-                fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(), (void*)Str1P);
+                fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(),
+                        (void *)Str1P);
 
             }
 
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index d5de3dbb..9921de0c 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -210,7 +210,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
   }
 
   if (!icomps.size()) return false;
-  if (!be_quiet) errs() << "Hooking " << icomps.size() << " cmp instructions\n";
+  // if (!be_quiet) errs() << "Hooking " << icomps.size() << " cmp
+  // instructions\n";
 
   for (auto &selectcmpInst : icomps) {
 
@@ -259,8 +260,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 bool CmpLogInstructions::runOnModule(Module &M) {
 
   if (getenv("AFL_QUIET") == NULL)
-    llvm::errs()
-        << "Running cmplog-instructions-pass by andreafioraldi@gmail.com\n";
+    printf("Running cmplog-instructions-pass by andreafioraldi@gmail.com\n");
   else
     be_quiet = 1;
   hookInstrs(M);
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index c44f38c4..e92883ae 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -149,9 +149,11 @@ bool CmpLogRoutines::hookRtns(Module &M) {
   }
 
   if (!calls.size()) return false;
-  if (!be_quiet)
-    errs() << "Hooking " << calls.size()
-           << " calls with pointers as arguments\n";
+  /*
+    if (!be_quiet)
+      errs() << "Hooking " << calls.size()
+             << " calls with pointers as arguments\n";
+  */
 
   for (auto &callInst : calls) {
 
@@ -179,8 +181,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
 bool CmpLogRoutines::runOnModule(Module &M) {
 
   if (getenv("AFL_QUIET") == NULL)
-    llvm::errs()
-        << "Running cmplog-routines-pass by andreafioraldi@gmail.com\n";
+    printf("Running cmplog-routines-pass by andreafioraldi@gmail.com\n");
   else
     be_quiet = 1;
   hookRtns(M);
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index 9d2f4a92..3a4abd6e 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -339,8 +339,9 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
 
   if (!calls.size()) return false;
   if (!be_quiet)
-    errs() << "Replacing " << calls.size()
-           << " calls to strcmp/memcmp/strncmp/strcasecmp/strncasecmp\n";
+    printf(
+        "Replacing %lu calls to strcmp/memcmp/strncmp/strcasecmp/strncasecmp\n",
+        calls.size());
 
   for (auto &callInst : calls) {
 
@@ -426,11 +427,14 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
     else
       unrollLen = constStrLen;
 
-    if (!be_quiet)
-      errs() << callInst->getCalledFunction()->getName() << ": unroll len "
-             << unrollLen
-             << ((isSizedcmp && !isConstSized) ? ", variable n" : "") << ": "
-             << ConstStr << "\n";
+    /*
+        if (!be_quiet)
+          errs() << callInst->getCalledFunction()->getName() << ": unroll len "
+                 << unrollLen
+                 << ((isSizedcmp && !isConstSized) ? ", variable n" : "") << ":
+       "
+                 << ConstStr << "\n";
+    */
 
     /* split before the call instruction */
     BasicBlock *bb = callInst->getParent();
@@ -556,10 +560,12 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
 bool CompareTransform::runOnModule(Module &M) {
 
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
-    llvm::errs() << "Running compare-transform-pass by laf.intel@gmail.com, "
-                    "extended by heiko@hexco.de\n";
+    printf(
+        "Running compare-transform-pass by laf.intel@gmail.com, extended by "
+        "heiko@hexco.de\n");
   else
     be_quiet = 1;
+
   transformCmps(M, true, true, true, true, true);
   verifyModule(M);
 
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 2fb90e5e..6d0c52a4 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -1262,8 +1262,9 @@ bool SplitComparesTransform::runOnModule(Module &M) {
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
       getenv("AFL_DEBUG") != NULL) {
 
-    errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
-              "heiko@hexco.de\n";
+    printf(
+        "Split-compare-pass by laf.intel@gmail.com, extended by "
+        "heiko@hexco.de\n");
 
   } else {
 
@@ -1275,13 +1276,15 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
     count = splitFPCompares(M);
 
-    if (!be_quiet) {
+    /*
+        if (!be_quiet) {
 
-      errs() << "Split-floatingpoint-compare-pass: " << count
-             << " FP comparisons split\n";
+          errs() << "Split-floatingpoint-compare-pass: " << count
+                 << " FP comparisons split\n";
 
-    }
+        }
 
+    */
     simplifyFPCompares(M);
 
   }
@@ -1294,10 +1297,12 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 
     case 64:
       count = splitIntCompares(M, bitw);
-      if (!be_quiet)
-        errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
-               << " split\n";
-
+      /*
+            if (!be_quiet)
+              errs() << "Split-integer-compare-pass " << bitw << "bit: " <<
+         count
+                     << " split\n";
+      */
       bitw >>= 1;
 #if LLVM_VERSION_MAJOR > 3 || \
     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7)
@@ -1305,10 +1310,12 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 #endif
     case 32:
       count = splitIntCompares(M, bitw);
-      if (!be_quiet)
-        errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
-               << " split\n";
-
+      /*
+            if (!be_quiet)
+              errs() << "Split-integer-compare-pass " << bitw << "bit: " <<
+         count
+                     << " split\n";
+      */
       bitw >>= 1;
 #if LLVM_VERSION_MAJOR > 3 || \
     (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7)
@@ -1316,15 +1323,17 @@ bool SplitComparesTransform::runOnModule(Module &M) {
 #endif
     case 16:
       count = splitIntCompares(M, bitw);
-      if (!be_quiet)
-        errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
-               << " split\n";
-
+      /*
+            if (!be_quiet)
+              errs() << "Split-integer-compare-pass " << bitw << "bit: " <<
+         count
+                     << " split\n";
+      */
       bitw >>= 1;
       break;
 
     default:
-      if (!be_quiet) errs() << "NOT Running split-compare-pass \n";
+      // if (!be_quiet) errs() << "NOT Running split-compare-pass \n";
       return false;
       break;
 
diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc
index a79d4114..97ab04a4 100644
--- a/instrumentation/split-switches-pass.so.cc
+++ b/instrumentation/split-switches-pass.so.cc
@@ -327,10 +327,11 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
   }
 
   if (!switches.size()) return false;
-  if (!be_quiet)
-    errs() << "Rewriting " << switches.size() << " switch statements "
-           << "\n";
-
+  /*
+    if (!be_quiet)
+      errs() << "Rewriting " << switches.size() << " switch statements "
+             << "\n";
+  */
   for (auto &SI : switches) {
 
     BasicBlock *CurBlock = SI->getParent();
@@ -341,15 +342,17 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
     BasicBlock *Default = SI->getDefaultDest();
     unsigned    bitw = Val->getType()->getIntegerBitWidth();
 
-    if (!be_quiet)
-      errs() << "switch: " << SI->getNumCases() << " cases " << bitw
-             << " bit\n";
+    /*
+        if (!be_quiet)
+          errs() << "switch: " << SI->getNumCases() << " cases " << bitw
+                 << " bit\n";
+    */
 
     /* If there is only the default destination or the condition checks 8 bit or
      * less, don't bother with the code below. */
     if (!SI->getNumCases() || bitw <= 8) {
 
-      if (!be_quiet) errs() << "skip trivial switch..\n";
+      // if (!be_quiet) errs() << "skip trivial switch..\n";
       continue;
 
     }
@@ -415,7 +418,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
 bool SplitSwitchesTransform::runOnModule(Module &M) {
 
   if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
-    llvm::errs() << "Running split-switches-pass by laf.intel@gmail.com\n";
+    printf("Running split-switches-pass by laf.intel@gmail.com\n");
   else
     be_quiet = 1;
   splitSwitches(M);
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 64de86a2..a22223b9 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -556,8 +556,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
     cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
     /* Saturated increment */
-    if (afl->n_fuzz[cksum % n_fuzz_size] < 0xFFFFFFFF)
-      afl->n_fuzz[cksum % n_fuzz_size]++;
+    if (afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF)
+      afl->n_fuzz[cksum % N_FUZZ_SIZE]++;
 
   }
 
@@ -597,10 +597,15 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
     if (cksum)
       afl->queue_top->exec_cksum = cksum;
     else
-      afl->queue_top->exec_cksum =
+      cksum = afl->queue_top->exec_cksum =
           hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
 
-    afl->n_fuzz[cksum % n_fuzz_size] = 1;
+    if (afl->schedule >= FAST && afl->schedule <= RARE) {
+
+      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. */
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index b825837f..65478a78 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -732,8 +732,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
     if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
 
       u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
-
-      afl->n_fuzz[cksum % n_fuzz_size] = 1;
+      afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
+      afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
 
     }
 
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index dfabba7b..0d7d0314 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -308,9 +308,9 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
   u64 fuzz_p2;
 
   if (unlikely(afl->schedule >= FAST && afl->schedule < RARE))
-    fuzz_p2 = 0; // Skip the fuzz_p2 comparison 
+    fuzz_p2 = 0;  // Skip the fuzz_p2 comparison
   else if (unlikely(afl->schedule == RARE))
-    fuzz_p2 = next_pow2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]);
+    fuzz_p2 = next_pow2(afl->n_fuzz[q->n_fuzz_entry]);
   else
     fuzz_p2 = q->fuzz_level;
 
@@ -336,7 +336,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
         u64 top_rated_fav_factor;
         u64 top_rated_fuzz_p2;
         if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
-          top_rated_fuzz_p2 = next_pow2(afl->n_fuzz[afl->top_rated[i]->exec_cksum % n_fuzz_size]);
+          top_rated_fuzz_p2 =
+              next_pow2(afl->n_fuzz[afl->top_rated[i]->n_fuzz_entry]);
         else
           top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level;
 
@@ -607,11 +608,10 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
 
   }
 
-  u32 n_paths;
-  double factor = 1.0;
+  u32         n_paths;
+  double      factor = 1.0;
   long double fuzz_mu;
 
-
   switch (afl->schedule) {
 
     case EXPLORE:
@@ -634,7 +634,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
       struct queue_entry *queue_it = afl->queue;
       while (queue_it) {
 
-        fuzz_mu += log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]);
+        fuzz_mu += log2(afl->n_fuzz[q->n_fuzz_entry]);
         n_paths++;
 
         queue_it = queue_it->next;
@@ -645,7 +645,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
 
       fuzz_mu = fuzz_mu / n_paths;
 
-      if (log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]) > fuzz_mu) {
+      if (log2(afl->n_fuzz[q->n_fuzz_entry]) > fuzz_mu) {
 
         /* Never skip favourites */
         if (!q->favored) factor = 0;
@@ -660,7 +660,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
       // Don't modify unfuzzed seeds
       if (q->fuzz_level == 0) break;
 
-      switch ((u32)log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size])) {
+      switch ((u32)log2(afl->n_fuzz[q->n_fuzz_entry])) {
 
         case 0 ... 1:
           factor = 4;
@@ -691,17 +691,17 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
 
       }
 
-      if (q->favored)
-        factor *= 1.15;
+      if (q->favored) factor *= 1.15;
 
       break;
 
     case LIN:
-      factor = q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1);
+      factor = q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
       break;
 
     case QUAD:
-      factor = q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1);
+      factor =
+          q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
       break;
 
     case MMOPT:
@@ -726,8 +726,8 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
       perf_score += (q->tc_ref * 10);
       // the more often fuzz result paths are equal to this queue entry,
       // reduce its value
-      perf_score *=
-          (1 - (double)((double)afl->n_fuzz[q->exec_cksum % n_fuzz_size] / (double)afl->fsrv.total_execs));
+      perf_score *= (1 - (double)((double)afl->n_fuzz[q->n_fuzz_entry] /
+                                  (double)afl->fsrv.total_execs));
 
       break;
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 889f753d..273d1c14 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -939,7 +939,7 @@ int main(int argc, char **argv_orig, char **envp) {
   /* Dynamically allocate memory for AFLFast schedules */
   if (afl->schedule >= FAST && afl->schedule <= RARE) {
 
-    afl->n_fuzz = ck_alloc(n_fuzz_size * sizeof(u32));
+    afl->n_fuzz = ck_alloc(N_FUZZ_SIZE * sizeof(u32));
 
   }