about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--docs/Changelog.md6
-rw-r--r--docs/afl-fuzz_approach.md4
-rw-r--r--docs/tutorials.md5
-rw-r--r--include/afl-mutations.h16
-rw-r--r--include/config.h2
-rw-r--r--include/envs.h1
-rw-r--r--instrumentation/afl-llvm-common.cc8
-rw-r--r--src/afl-cc.c38
-rw-r--r--src/afl-fuzz-bitmap.c11
-rw-r--r--utils/aflpp_driver/aflpp_driver.c7
11 files changed, 73 insertions, 29 deletions
diff --git a/README.md b/README.md
index 322ebcf2..a09147c5 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
 
 <img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
 
-Release version: [4.08c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.09c](https://github.com/AFLplusplus/AFLplusplus/releases)
 
-GitHub version: 4.09a
+GitHub version: 4.09c
 
 Repository:
 [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index b2e9fbf6..2dfcb482 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,8 +3,9 @@
   This is the list of all noteworthy changes made in every public
   release of the tool. See README.md for the general instruction manual.
 
-### Version ++4.09a (dev)
+### Version ++4.09c (release)
   - afl-fuzz:
+    - fixed the new mutation implementation for two bugs
     - added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
       before terminating.
     - added AFL_IGNORE_SEED_PROBLEMS to skip over seeds that time out instead
@@ -23,8 +24,11 @@
     - option -n will not use color in the output
   - instrumentation:
     - fix for a few string compare transform functions for LAF
+    - we are instrumenting __cxx internal functions again. this might break
+      a few targets, please report if so.
   - frida_mode:
     - fixes support for large map offsets
+  - support for AFL_FUZZER_LOOPCOUNT for afl.rs and LLVMFuzzerTestOneInput
   - afl-cmin/afl-cmin.bash: prevent unneeded file errors
   - added new tool afl-addseeds that adds new seeds to a running campaign
   - added benchmark/benchmark.py if you want to see how good your fuzzing
diff --git a/docs/afl-fuzz_approach.md b/docs/afl-fuzz_approach.md
index 7d18b178..9ea06325 100644
--- a/docs/afl-fuzz_approach.md
+++ b/docs/afl-fuzz_approach.md
@@ -5,6 +5,10 @@ instrumentation-guided genetic algorithm. It uses a modified form of edge
 coverage to effortlessly pick up subtle, local-scale changes to program control
 flow.
 
+Note: If you are interested in a more current up-to-date deep dive how AFL++
+works then we commend this blog post:
+[https://blog.ritsec.club/posts/afl-under-hood/](https://blog.ritsec.club/posts/afl-under-hood/)
+
 Simplifying a bit, the overall algorithm can be summed up as:
 
 1) Load user-supplied initial test cases into the queue.
diff --git a/docs/tutorials.md b/docs/tutorials.md
index a5ee3322..0a09f6dc 100644
--- a/docs/tutorials.md
+++ b/docs/tutorials.md
@@ -21,7 +21,7 @@ training, then we can highly recommend the following:
 
 * [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
 
-Here is a good forkflow description (and tutorial) for qemu_mode:
+Here is a good workflow description (and tutorial) for qemu_mode:
 
 * [https://airbus-seclab.github.io/AFLplusplus-blogpost/](https://airbus-seclab.github.io/AFLplusplus-blogpost/)
 
@@ -41,6 +41,9 @@ structure is), these links have you covered (some are outdated though):
 * Superion for AFL++:
   [https://github.com/adrian-rt/superion-mutator](https://github.com/adrian-rt/superion-mutator)
 
+For a very in-depth explanation on how AFL++ works check out:
+[https://blog.ritsec.club/posts/afl-under-hood/](https://blog.ritsec.club/posts/afl-under-hood/)
+
 ## Video Tutorials
 
 * [Install AFL++ Ubuntu](https://www.youtube.com/watch?v=5dCvhkbi3RA)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index d709b90d..6338c93c 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -2456,14 +2456,14 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
 
         }
 
-        char buf[20];
-        snprintf(buf, sizeof(buf), "%" PRId64, val);
+        char numbuf[32];
+        snprintf(numbuf, sizeof(buf), "%" PRId64, val);
         u32 old_len = off2 - off;
-        u32 new_len = strlen(buf);
+        u32 new_len = strlen(numbuf);
 
         if (old_len == new_len) {
 
-          memcpy(buf + off, buf, new_len);
+          memcpy(buf + off, numbuf, new_len);
 
         } else {
 
@@ -2473,7 +2473,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
 
           /* Inserted part */
 
-          memcpy(tmp_buf + off, buf, new_len);
+          memcpy(tmp_buf + off, numbuf, new_len);
 
           /* Tail */
           memcpy(tmp_buf + off + new_len, buf + off2, len - off2);
@@ -2509,9 +2509,9 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
         }
 
         u64  val = rand_next(afl);
-        char buf[20];
-        snprintf(buf, sizeof(buf), "%llu", val);
-        memcpy(buf + pos, buf, len);
+        char numbuf[32];
+        snprintf(numbuf, sizeof(numbuf), "%llu", val);
+        memcpy(buf + pos, numbuf, len);
 
         break;
 
diff --git a/include/config.h b/include/config.h
index 988e536e..b346d7b4 100644
--- a/include/config.h
+++ b/include/config.h
@@ -26,7 +26,7 @@
 /* Version string: */
 
 // c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++4.09a"
+#define VERSION "++4.09c"
 
 /******************************************************
  *                                                    *
diff --git a/include/envs.h b/include/envs.h
index 93e49e34..560092d9 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -172,6 +172,7 @@ static char *afl_environment_variables[] = {
     "AFL_LLVM_LTO_DONTWRITEID",
     "AFL_LLVM_LTO_SKIPINIT"
     "AFL_LLVM_LTO_STARTID",
+    "AFL_FUZZER_LOOPCOUNT",
     "AFL_NO_ARITH",
     "AFL_NO_AUTODICT",
     "AFL_NO_BUILTIN",
diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc
index 7f17b02d..96952bd6 100644
--- a/instrumentation/afl-llvm-common.cc
+++ b/instrumentation/afl-llvm-common.cc
@@ -97,11 +97,15 @@ bool isIgnoreFunction(const llvm::Function *F) {
 
   static constexpr const char *ignoreSubstringList[] = {
 
-      "__asan", "__msan",       "__ubsan",    "__lsan",  "__san", "__sanitize",
-      "__cxx",  "DebugCounter", "DwarfDebug", "DebugLoc"
+      "__asan",     "__msan",       "__ubsan",    "__lsan",  "__san",
+      "__sanitize", "DebugCounter", "DwarfDebug", "DebugLoc"
 
   };
 
+  // This check is very sensitive, we must be sure to not include patterns
+  // that are part of user-written C++ functions like the ones including
+  // std::string as parameter (see #1927) as the mangled type is inserted in the
+  // mangled name of the user-written function
   for (auto const &ignoreListFunc : ignoreSubstringList) {
 
     // hexcoder: F->getName().contains() not avaiilable in llvm 3.8.0
diff --git a/src/afl-cc.c b/src/afl-cc.c
index ceea61f2..22cce2cd 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -395,12 +395,16 @@ static void process_params(u32 argc, char **argv) {
 
   }
 
+  // reset
+  have_instr_list = 0;
+  have_c = 0;
+
   if (lto_mode && argc > 1) {
 
     u32 idx;
     for (idx = 1; idx < argc; idx++) {
 
-      if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
+      if (!strncasecmp(argv[idx], "-fpic", 5)) { have_pic = 1; }
 
     }
 
@@ -689,6 +693,18 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
   cc_params = ck_alloc(MAX_PARAMS_NUM * sizeof(u8 *));
 
+  for (u32 c = 1; c < argc; ++c) {
+
+    if (!strcmp(argv[c], "-c")) have_c = 1;
+    if (!strncmp(argv[c], "-fsanitize-coverage-", 20) &&
+        strstr(argv[c], "list=")) {
+
+      have_instr_list = 1;
+
+    }
+
+  }
+
   if (lto_mode) {
 
     if (lto_flag[0] != '-')
@@ -1125,24 +1141,18 @@ static void edit_params(u32 argc, char **argv, char **envp) {
 
     // cc_params[cc_par_cnt++] = "-Qunused-arguments";
 
-    if (lto_mode && argc > 1) {
-
-      u32 idx;
-      for (idx = 1; idx < argc; idx++) {
-
-        if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
-
-      }
-
-    }
-
   }
 
   /* Inspect the command line parameters. */
 
   process_params(argc, argv);
 
-  if (!have_pic) { cc_params[cc_par_cnt++] = "-fPIC"; }
+  if (!have_pic) {
+
+    cc_params[cc_par_cnt++] = "-fPIC";
+    have_pic = 1;
+
+  }
 
   if (compiler_mode != GCC_PLUGIN && compiler_mode != GCC &&
       !getenv("AFL_LLVM_NO_RPATH")) {
@@ -2303,7 +2313,7 @@ int main(int argc, char **argv, char **envp) {
             "0x10000\n"
             "  AFL_LLVM_DOCUMENT_IDS: write all edge IDs and the corresponding "
             "functions\n"
-            "    into this file\n"
+            "    into this file (LTO mode)\n"
             "  AFL_LLVM_LTO_DONTWRITEID: don't write the highest ID used to a "
             "global var\n"
             "  AFL_LLVM_LTO_STARTID: from which ID to start counting from for "
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 568c5274..5f67347c 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -459,6 +459,17 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
 
   if (unlikely(fault == FSRV_RUN_TMOUT && afl->afl_env.afl_ignore_timeouts)) {
 
+    if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) {
+
+      classify_counts(&afl->fsrv);
+      u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
+
+      // Saturated increment
+      if (likely(afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF))
+        afl->n_fuzz[cksum % N_FUZZ_SIZE]++;
+
+    }
+
     return 0;
 
   }
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index dab7fd95..9ffb2383 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -292,6 +292,7 @@ __attribute__((weak)) int main(int argc, char **argv) {
         "afl-fuzz will run N iterations before re-spawning the process "
         "(default: "
         "INT_MAX)\n"
+        "You can also use AFL_FUZZER_LOOPCOUNT to set N\n"
         "For stdin input processing, pass '-' as single command line option.\n"
         "For file input processing, pass '@@' as single command line option.\n"
         "To use with afl-cmin or afl-cmin.bash pass '-' as single command line "
@@ -379,6 +380,12 @@ __attribute__((weak)) int LLVMFuzzerRunDriver(
 
   }
 
+  if (getenv("AFL_FUZZER_LOOPCOUNT")) {
+
+    N = atoi(getenv("AFL_FUZZER_LOOPCOUNT"));
+
+  }
+
   assert(N > 0);
 
   __afl_manual_init();