about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile8
-rw-r--r--TODO.md12
-rw-r--r--docs/Changelog.md1
-rw-r--r--docs/FAQ.md9
-rw-r--r--examples/persistent_demo/persistent_demo_new.c4
-rw-r--r--llvm_mode/afl-clang-fast.c10
-rw-r--r--llvm_mode/afl-llvm-rt.o.c29
-rw-r--r--src/afl-fuzz-redqueen.c7
-rw-r--r--src/afl-fuzz.c3
-rw-r--r--test/test-cmplog.c23
-rwxr-xr-xtest/test.sh22
11 files changed, 106 insertions, 22 deletions
diff --git a/Dockerfile b/Dockerfile
index 4d9f6e84..64b04ba6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -50,13 +50,15 @@ ENV LLVM_CONFIG=llvm-config-11
 ENV AFL_SKIP_CPUFREQ=1
 
 RUN git clone https://github.com/vanhauser-thc/afl-cov /afl-cov
-RUN cd /afl-cov && make install
+RUN cd /afl-cov && make install && cd ..
 
 COPY . /AFLplusplus
 WORKDIR /AFLplusplus
 
 RUN export REAL_CXX=g++-10 && export CC=gcc-10 && \
-    export CXX=g++-10 && make clean && make distrib && make install && make clean
+    export CXX=g++-10 && make clean && \
+    make distrib && make install && make clean
 
 RUN echo 'alias joe="jupp --wordwrap"' >> ~/.bashrc
-
+RUN echo 'export PS1="[afl++]$PS1"' >> ~/.bashrc
+ENV IS_DOCKER="1"
diff --git a/TODO.md b/TODO.md
index 3e55f2f1..999cb9d3 100644
--- a/TODO.md
+++ b/TODO.md
@@ -30,3 +30,15 @@ qemu_mode:
    persistent mode
  - add/implement AFL_QEMU_INST_LIBLIST and AFL_QEMU_NOINST_PROGRAM
  - add/implement AFL_QEMU_INST_REGIONS as a list of _START/_END addresses
+
+## Ideas
+
+ - LTO/sancov: write current edge to prev_loc and use that information when
+   using cmplog or __sanitizer_cov_trace_cmp*. maybe we can deduct by follow
+   up edge numbers that both following cmp paths have been found and then
+   disable working on this edge id
+
+ - new tancov: use some lightweight taint analysis to see which parts of a
+   new queue entry is accessed and only fuzz these bytes - or better, only
+   fuzz those bytes that are newly in coverage compared to the queue entry
+   the new one is based on
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 8ab3fdf4..ae7377f2 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -19,6 +19,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
      - eliminated CPU affinity race condition for -S/-M runs
      - expanded havoc mode added, on no cycle finds add extra splicing and
        MOpt into the mix
+     - fixed a bug in redqueen for strings
   - llvm_mode:
      - now supports llvm 12!
      - fixes for laf-intel float splitting (thanks to mark-griffin for
diff --git a/docs/FAQ.md b/docs/FAQ.md
index ee221d02..c15cd484 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -103,10 +103,11 @@ afl-clang-fast PCGUARD and afl-clang-lto LTO instrumentation!
      b) For PCGUARD instrumented binaries it is much more difficult. Here you
         can either modify the __sanitizer_cov_trace_pc_guard function in
         llvm_mode/afl-llvm-rt.o.c to write a backtrace to a file if the ID in
-        __afl_area_ptr[*guard] is one of the unstable edge IDs. Then recompile
-        and reinstall llvm_mode and rebuild your target. Run the recompiled
-	target with afl-fuzz for a while and then check the file that you
-        wrote with the backtrace information.
+        __afl_area_ptr[*guard] is one of the unstable edge IDs.
+        (Example code is already there).
+        Then recompile and reinstall llvm_mode and rebuild your target.
+        Run the recompiled target with afl-fuzz for a while and then check the
+        file that you wrote with the backtrace information.
         Alternatively you can use `gdb` to hook __sanitizer_cov_trace_pc_guard_init
         on start, check to which memory address the edge ID value is written
         and set a write breakpoint to that address (`watch 0x.....`).
diff --git a/examples/persistent_demo/persistent_demo_new.c b/examples/persistent_demo/persistent_demo_new.c
index 5f347667..7f878c0c 100644
--- a/examples/persistent_demo/persistent_demo_new.c
+++ b/examples/persistent_demo/persistent_demo_new.c
@@ -31,8 +31,8 @@
 /* this lets the source compile without afl-clang-fast/lto */
 #ifndef __AFL_FUZZ_TESTCASE_LEN
 
-  ssize_t       fuzz_len;
-  unsigned char fuzz_buf[1024000];
+ssize_t       fuzz_len;
+unsigned char fuzz_buf[1024000];
 
   #define __AFL_FUZZ_TESTCASE_LEN fuzz_len
   #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index 738433ac..484943d2 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -255,12 +255,6 @@ static void edit_params(u32 argc, char **argv, char **envp) {
   if (getenv("LAF_TRANSFORM_COMPARES") ||
       getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) {
 
-    if (!be_quiet && getenv("AFL_LLVM_LTO_AUTODICTIONARY") && lto_mode)
-      WARNF(
-          "using AFL_LLVM_LAF_TRANSFORM_COMPARES together with "
-          "AFL_LLVM_LTO_AUTODICTIONARY makes no sense. Use only "
-          "AFL_LLVM_LTO_AUTODICTIONARY.");
-
     cc_params[cc_par_cnt++] = "-Xclang";
     cc_params[cc_par_cnt++] = "-load";
     cc_params[cc_par_cnt++] = "-Xclang";
@@ -472,9 +466,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
   }
 
   if (getenv("AFL_NO_BUILTIN") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES") ||
-      getenv("LAF_TRANSFORM_COMPARES") ||
-      (lto_mode && (getenv("AFL_LLVM_LTO_AUTODICTIONARY") ||
-                    getenv("AFL_LLVM_AUTODICTIONARY")))) {
+      getenv("LAF_TRANSFORM_COMPARES") || lto_mode) {
 
     cc_params[cc_par_cnt++] = "-fno-builtin-strcmp";
     cc_params[cc_par_cnt++] = "-fno-builtin-strncmp";
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
index c0ed1bcf..88abcbe0 100644
--- a/llvm_mode/afl-llvm-rt.o.c
+++ b/llvm_mode/afl-llvm-rt.o.c
@@ -859,6 +859,35 @@ __attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {
 
 void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
 
+  // For stability analysis, if you want to know to which function unstable
+  // edge IDs belong to - uncomment, recompile+install llvm_mode, recompile
+  // the target. libunwind and libbacktrace are better solutions.
+  // Set AFL_DEBUG_CHILD_OUTPUT=1 and run afl-fuzz with 2>file to capture
+  // the backtrace output
+  /*
+  uint32_t unstable[] = { ... unstable edge IDs };
+  uint32_t idx;
+  char bt[1024];
+  for (idx = 0; i < sizeof(unstable)/sizeof(uint32_t); i++) {
+
+    if (unstable[idx] == __afl_area_ptr[*guard]) {
+
+      int bt_size = backtrace(bt, 256);
+      if (bt_size > 0) {
+
+        char **bt_syms = backtrace_symbols(bt, bt_size);
+        if (bt_syms)
+          fprintf(stderr, "DEBUG: edge=%u caller=%s\n", unstable[idx],
+  bt_syms[0]);
+
+      }
+
+    }
+
+  }
+
+  */
+
   __afl_area_ptr[*guard]++;
 
 }
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index d86190a6..cb4c78df 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -673,14 +673,15 @@ static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header *h,
 
   for (i = 0; i < its_len; ++i) {
 
-    if (pattern[idx + i] != buf[idx + i] ||
-        o_pattern[idx + i] != orig_buf[idx + i] || *status == 1) {
+    if (pattern[i] != buf[idx + i] || o_pattern[i] != orig_buf[idx + i] ||
+        *status == 1) {
 
       break;
 
     }
 
-    buf[idx + i] = repl[idx + i];
+    buf[idx + i] = repl[i];
+
     if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
 
   }
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 326ccc1c..da30797c 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1304,7 +1304,8 @@ int main(int argc, char **argv_orig, char **envp) {
               afl->expand_havoc = 1;
               break;
             case 1:
-              if (afl->limit_time_sig == 0) {
+              if (afl->limit_time_sig == 0 && !afl->custom_only &&
+                  !afl->python_only) {
 
                 afl->limit_time_sig = -1;
                 afl->limit_time_puppet = 0;
diff --git a/test/test-cmplog.c b/test/test-cmplog.c
new file mode 100644
index 00000000..b077e3ab
--- /dev/null
+++ b/test/test-cmplog.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+int main(int argc, char *argv[]) {
+
+  char    buf[1024];
+  ssize_t i;
+  if ((i = read(0, buf, sizeof(buf) - 1)) < 24) return 0;
+  buf[i] = 0;
+  if (buf[0] != 'A') return 0;
+  if (buf[1] != 'B') return 0;
+  if (buf[2] != 'C') return 0;
+  if (buf[3] != 'D') return 0;
+  if (memcmp(buf + 4, "1234", 4) || memcmp(buf + 8, "EFGH", 4)) return 0;
+  if (strncmp(buf + 12, "IJKL", 4) == 0 && strcmp(buf + 16, "DEADBEEF") == 0)
+    abort();
+  return 0;
+
+}
+
diff --git a/test/test.sh b/test/test.sh
index dea9134f..46843d4a 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -423,6 +423,28 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
     CODE=1
   }
   rm -f test-compcov test.out instrumentlist.txt
+  AFL_LLVM_CMPLOG=1 ../afl-clang-fast -o test-cmplog test-cmplog.c > /dev/null 2>&1
+  test -e test-cmplog && {
+    $ECHO "$GREY[*] running afl-fuzz for llvm_mode cmplog, this will take approx 10 seconds"
+    {
+      mkdir -p in
+      echo 0000000000000000000000000 > in/in
+      ../afl-fuzz -m none -V10 -i in -o out -c./test-cmplog -- ./test-cmplog >>errors 2>&1
+    } >>errors 2>&1
+    test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && {
+      $ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog"
+    } || {
+      echo CUT------------------------------------------------------------------CUT
+      cat errors
+      echo CUT------------------------------------------------------------------CUT
+      $ECHO "$RED[!] afl-fuzz is not working correctly with llvm_mode cmplog"
+      CODE=1
+    }
+  } || {
+    $ECHO "$YELLOW[-] we cannot test llvm_mode cmplog because it is not present"
+    INCOMPLETE=1
+  }
+  rm -rf errors test-cmplog in
   ../afl-clang-fast -o test-persistent ../examples/persistent_demo/persistent_demo.c > /dev/null 2>&1
   test -e test-persistent && {
     echo foo | ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -q -r ./test-persistent && {