about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--docs/Changelog.md2
-rw-r--r--include/config.h4
-rw-r--r--include/envs.h2
-rw-r--r--instrumentation/afl-compiler-rt.o.c2
-rw-r--r--instrumentation/cmplog-instructions-pass.cc196
-rw-r--r--qemu_mode/README.md22
-rw-r--r--qemu_mode/libqasan/dlmalloc.c5
-rw-r--r--qemu_mode/libqasan/string.c2
m---------qemu_mode/qemuafl0
-rw-r--r--src/afl-cc.c2
-rw-r--r--src/afl-fuzz-redqueen.c5
-rwxr-xr-xtest/test-unicorn-mode.sh2
-rwxr-xr-xunicorn_mode/build_unicorn_support.sh6
13 files changed, 59 insertions, 191 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e2482f8f..477498d0 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -48,8 +48,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
       support (less performant than our own), GCC for old afl-gcc and
       CLANG for old afl-clang
     - fixed a potential crash in the LAF feature
+    - workaround for llvm bitcast lto bug
     - workaround for llvm 13
-    - workaround for llvm internal lto bug that lets not bitcast from _ExtInt()
   - qemuafl
     - QASan (address sanitizer for Qemu) ported to qemuafl!
       See qemu_mode/libqasan/README.md
diff --git a/include/config.h b/include/config.h
index 181285cd..9f7db04d 100644
--- a/include/config.h
+++ b/include/config.h
@@ -42,7 +42,7 @@
  *
  */
 
-/* Enable arithmetic compare solving for both path */
+/* Enable arithmetic compare solving for both branches */
 #define CMPLOG_SOLVE_ARITHMETIC
 
 /* Enable transform following (XOR/ADD/SUB manipulations, hex en/decoding) */
@@ -51,7 +51,7 @@
 /* if TRANSFORM is enabled, this additionally enables base64 en/decoding */
 // #define CMPLOG_SOLVE_TRANSFORM_BASE64
 
-/* If a redqueen pass finds more than one solve, try to combine them? */
+/* If a redqueen pass finds more than one solution, try to combine them? */
 #define CMPLOG_COMBINE
 
 /* Minimum % of the corpus to perform cmplog on. Default: 20% */
diff --git a/include/envs.h b/include/envs.h
index 36667ebc..143979c6 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -16,7 +16,6 @@ static char *afl_environment_deprecated[] = {
 
 static char *afl_environment_variables[] = {
 
-    "_AFL_LTO_COMPILE",
     "AFL_ALIGNED_ALLOC",
     "AFL_ALLOW_TMP",
     "AFL_ANALYZE_HEX",
@@ -132,6 +131,7 @@ static char *afl_environment_variables[] = {
     "AFL_QEMU_DEBUG_MAPS",
     "AFL_QEMU_DISABLE_CACHE",
     "AFL_QEMU_DRIVER_NO_HOOK",
+    "AFL_QEMU_FORCE_DFL",
     "AFL_QEMU_PERSISTENT_ADDR",
     "AFL_QEMU_PERSISTENT_CNT",
     "AFL_QEMU_PERSISTENT_GPR",
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 5fb715e2..dba4dc65 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -1090,7 +1090,7 @@ __attribute__((constructor(0))) void __afl_auto_first(void) {
   if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return;
   u8 *ptr;
 
-  ptr = (u8 *)malloc(2097152);
+  ptr = (u8 *)malloc(MAP_INITIAL_SIZE);
 
   if (ptr && (ssize_t)ptr != -1) {
 
diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc
index 6b071b48..dbca9afa 100644
--- a/instrumentation/cmplog-instructions-pass.cc
+++ b/instrumentation/cmplog-instructions-pass.cc
@@ -19,12 +19,13 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include <iostream>
 #include <list>
 #include <string>
 #include <fstream>
 #include <sys/time.h>
-#include "llvm/Config/llvm-config.h"
 
+#include "llvm/Config/llvm-config.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/LegacyPassManager.h"
@@ -113,8 +114,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
   IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
   IntegerType *Int128Ty = IntegerType::getInt128Ty(C);
 
-  char *is_lto = getenv("_AFL_LTO_COMPILE");
-
 #if LLVM_VERSION_MAJOR < 9
   Constant *
 #else
@@ -267,20 +266,17 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
       unsigned int  max_size = Val->getType()->getIntegerBitWidth(), cast_size;
       unsigned char do_cast = 0;
 
-      if (!SI->getNumCases() || max_size < 16) { continue; }
-
-      if (max_size % 8) {
+      if (!SI->getNumCases() || max_size < 16) {
 
-        if (is_lto) {
+        // if (!be_quiet) errs() << "skip trivial switch..\n";
+        continue;
 
-          continue;  // LTO cannot bitcast from _ExtInt() :(
-
-        } else {
+      }
 
-          max_size = (((max_size / 8) + 1) * 8);
-          do_cast = 1;
+      if (max_size % 8) {
 
-        }
+        max_size = (((max_size / 8) + 1) * 8);
+        do_cast = 1;
 
       }
 
@@ -297,7 +293,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 
         }
 
-        if (is_lto) { continue; }  // LTO cannot bitcast _ExtInt() :(
         max_size = 128;
         do_cast = 1;
 
@@ -314,7 +309,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
           cast_size = max_size;
           break;
         default:
-          if (is_lto) { continue; }  // LTO cannot bitcast _ExtInt() :(
           cast_size = 128;
           do_cast = 1;
 
@@ -324,36 +318,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 
       if (do_cast) {
 
-        ConstantInt *cint = dyn_cast<ConstantInt>(Val);
-        if (cint) {
-
-          uint64_t val = cint->getZExtValue();
-          // fprintf(stderr, "ConstantInt: %lu\n", val);
-          switch (cast_size) {
-
-            case 8:
-              CompareTo = ConstantInt::get(Int8Ty, val);
-              break;
-            case 16:
-              CompareTo = ConstantInt::get(Int16Ty, val);
-              break;
-            case 32:
-              CompareTo = ConstantInt::get(Int32Ty, val);
-              break;
-            case 64:
-              CompareTo = ConstantInt::get(Int64Ty, val);
-              break;
-            case 128:
-              CompareTo = ConstantInt::get(Int128Ty, val);
-              break;
-
-          }
-
-        } else {
-
-          CompareTo = IRB.CreateBitCast(Val, IntegerType::get(C, cast_size));
-
-        }
+        CompareTo =
+            IRB.CreateIntCast(CompareTo, IntegerType::get(C, cast_size), false);
 
       }
 
@@ -375,27 +341,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 
           if (do_cast) {
 
-            uint64_t val = cint->getZExtValue();
-            // fprintf(stderr, "ConstantInt: %lu\n", val);
-            switch (cast_size) {
-
-              case 8:
-                new_param = ConstantInt::get(Int8Ty, val);
-                break;
-              case 16:
-                new_param = ConstantInt::get(Int16Ty, val);
-                break;
-              case 32:
-                new_param = ConstantInt::get(Int32Ty, val);
-                break;
-              case 64:
-                new_param = ConstantInt::get(Int64Ty, val);
-                break;
-              case 128:
-                new_param = ConstantInt::get(Int128Ty, val);
-                break;
-
-            }
+            new_param =
+                IRB.CreateIntCast(cint, IntegerType::get(C, cast_size), false);
 
           }
 
@@ -558,16 +505,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 
       if (max_size % 8) {
 
-        if (is_lto) {
-
-          continue;  // LTO cannot bitcast from _ExtInt() :(
-
-        } else {
-
-          max_size = (((max_size / 8) + 1) * 8);
-          do_cast = 1;
-
-        }
+        max_size = (((max_size / 8) + 1) * 8);
+        do_cast = 1;
 
       }
 
@@ -581,7 +520,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
 
         }
 
-        if (is_lto) { continue; }  // LTO cannot bitcast from _ExtInt() :(
         max_size = 128;
         do_cast = 1;
 
@@ -598,94 +536,32 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
           cast_size = max_size;
           break;
         default:
-          if (is_lto) { continue; }  // LTO cannot bitcast from _ExtInt() :(
           cast_size = 128;
           do_cast = 1;
 
       }
 
-      if (do_cast) {
-
-        // F*cking LLVM optimized out any kind of bitcasts of ConstantInt values
-        // creating illegal calls. WTF. So we have to work around this.
-
-        ConstantInt *cint = dyn_cast<ConstantInt>(op0);
-        if (cint) {
-
-          uint64_t val = cint->getZExtValue();
-          // fprintf(stderr, "ConstantInt: %lu\n", val);
-          ConstantInt *new_param = NULL;
-          switch (cast_size) {
-
-            case 8:
-              new_param = ConstantInt::get(Int8Ty, val);
-              break;
-            case 16:
-              new_param = ConstantInt::get(Int16Ty, val);
-              break;
-            case 32:
-              new_param = ConstantInt::get(Int32Ty, val);
-              break;
-            case 64:
-              new_param = ConstantInt::get(Int64Ty, val);
-              break;
-            case 128:
-              new_param = ConstantInt::get(Int128Ty, val);
-              break;
-
-          }
-
-          if (!new_param) { continue; }
-          args.push_back(new_param);
-
-        } else {
-
-          Value *V0 = IRB.CreateBitCast(op0, IntegerType::get(C, cast_size));
-          args.push_back(V0);
-
-        }
-
-        cint = dyn_cast<ConstantInt>(op1);
-        if (cint) {
-
-          uint64_t     val = cint->getZExtValue();
-          ConstantInt *new_param = NULL;
-          switch (cast_size) {
-
-            case 8:
-              new_param = ConstantInt::get(Int8Ty, val);
-              break;
-            case 16:
-              new_param = ConstantInt::get(Int16Ty, val);
-              break;
-            case 32:
-              new_param = ConstantInt::get(Int32Ty, val);
-              break;
-            case 64:
-              new_param = ConstantInt::get(Int64Ty, val);
-              break;
-            case 128:
-              new_param = ConstantInt::get(Int128Ty, val);
-              break;
-
-          }
-
-          if (!new_param) { continue; }
-          args.push_back(new_param);
-
-        } else {
-
-          Value *V1 = IRB.CreateBitCast(op1, IntegerType::get(C, cast_size));
-          args.push_back(V1);
-
-        }
-
-      } else {
-
-        args.push_back(op0);
-        args.push_back(op1);
-
-      }
+      // errs() << "[CMPLOG] cmp  " << *cmpInst << "(in function " <<
+      // cmpInst->getFunction()->getName() << ")\n";
+
+      // first bitcast to integer type of the same bitsize as the original
+      // type (this is a nop, if already integer)
+      Value *op0_i = IRB.CreateBitCast(
+          op0, IntegerType::get(C, op0->getType()->getPrimitiveSizeInBits()));
+      // then create a int cast, which does zext, trunc or bitcast. In our case
+      // usually zext to the next larger supported type (this is a nop if
+      // already the right type)
+      Value *V0 =
+          IRB.CreateIntCast(op0_i, IntegerType::get(C, cast_size), false);
+      args.push_back(V0);
+      Value *op1_i = IRB.CreateBitCast(
+          op1, IntegerType::get(C, op1->getType()->getPrimitiveSizeInBits()));
+      Value *V1 =
+          IRB.CreateIntCast(op1_i, IntegerType::get(C, cast_size), false);
+      args.push_back(V1);
+
+      // errs() << "[CMPLOG] casted parameters:\n0: " << *V0 << "\n1: " << *V1
+      // << "\n";
 
       ConstantInt *attribute = ConstantInt::get(Int8Ty, attr);
       args.push_back(attribute);
diff --git a/qemu_mode/README.md b/qemu_mode/README.md
index 9818846d..bc4c1d2c 100644
--- a/qemu_mode/README.md
+++ b/qemu_mode/README.md
@@ -17,7 +17,7 @@ The idea and much of the initial implementation comes from Andrew Griffiths.
 The actual implementation on current QEMU (shipped as qemuafl) is from
 Andrea Fioraldi. Special thanks to abiondo that re-enabled TCG chaining.
 
-## 2) How to use
+## 2) How to use qemu_mode
 
 The feature is implemented with a patched QEMU. The simplest way
 to build it is to run ./build_qemu_support.sh. The script will download,
@@ -176,7 +176,12 @@ Comparative measurements of execution speed or instrumentation coverage will be
 fairly meaningless if the optimization levels or instrumentation scopes don't
 match.
 
-## 12) Gotchas, feedback, bugs
+## 12) Other features
+
+With `AFL_QEMU_FORCE_DFL` you force QEMU to ignore the registered signal
+handlers of the target.
+
+## 13) Gotchas, feedback, bugs
 
 If you need to fix up checksums or do other cleanup on mutated test cases, see
 utils/custom_mutators/ for a viable solution.
@@ -197,19 +202,12 @@ with -march=core2, can help.
 Beyond that, this is an early-stage mechanism, so fields reports are welcome.
 You can send them to <afl-users@googlegroups.com>.
 
-## 13) Alternatives: static rewriting
+## 14) Alternatives: static rewriting
 
 Statically rewriting binaries just once, instead of attempting to translate
 them at run time, can be a faster alternative. That said, static rewriting is
 fraught with peril, because it depends on being able to properly and fully model
 program control flow without actually executing each and every code path.
 
-The best implementation is this one:
-
-  https://github.com/vanhauser-thc/afl-dyninst
-
-The issue however is Dyninst which is not rewriting the binaries so that
-they run stable. A lot of crashes happen, especially in C++ programs that
-use throw/catch. Try it first, and if it works for you be happy as it is
-2-3x as fast as qemu_mode, however usually not as fast as QEMU persistent mode.
-
+Checkout the "Fuzzing binary-only targets" section in our main README.md and
+the docs/binaryonly_fuzzing.md document for more information and hints.
diff --git a/qemu_mode/libqasan/dlmalloc.c b/qemu_mode/libqasan/dlmalloc.c
index aff58ad5..bace0ff6 100644
--- a/qemu_mode/libqasan/dlmalloc.c
+++ b/qemu_mode/libqasan/dlmalloc.c
@@ -3917,7 +3917,6 @@ static void internal_malloc_stats(mstate m) {
                                                                 \
         } else if (RTCHECK(B == smallbin_at(M, I) ||            \
                                                                 \
-                                                                \
                            (ok_address(M, B) && B->fd == P))) { \
                                                                 \
           F->bk = B;                                            \
@@ -4129,7 +4128,6 @@ static void internal_malloc_stats(mstate m) {
                                                                      \
         } else                                                       \
                                                                      \
-                                                                     \
           CORRUPTION_ERROR_ACTION(M);                                \
         if (R != 0) {                                                \
                                                                      \
@@ -4146,7 +4144,6 @@ static void internal_malloc_stats(mstate m) {
                                                                      \
               } else                                                 \
                                                                      \
-                                                                     \
                 CORRUPTION_ERROR_ACTION(M);                          \
                                                                      \
             }                                                        \
@@ -4159,14 +4156,12 @@ static void internal_malloc_stats(mstate m) {
                                                                      \
               } else                                                 \
                                                                      \
-                                                                     \
                 CORRUPTION_ERROR_ACTION(M);                          \
                                                                      \
             }                                                        \
                                                                      \
           } else                                                     \
                                                                      \
-                                                                     \
             CORRUPTION_ERROR_ACTION(M);                              \
                                                                      \
         }                                                            \
diff --git a/qemu_mode/libqasan/string.c b/qemu_mode/libqasan/string.c
index c850463b..4be01279 100644
--- a/qemu_mode/libqasan/string.c
+++ b/qemu_mode/libqasan/string.c
@@ -271,7 +271,7 @@ void *__libqasan_memmem(const void *haystack, size_t haystack_len,
 
     }
 
-  } while (h++ <= end);
+  } while (++h <= end);
 
   return 0;
 
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
-Subproject 9a258d5b7a38c045a6e385fcfcf80a746a60e55
+Subproject 213f3b27dd099ef352181c48cd75c0f20a73e3f
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 959c9a6f..d41f79a2 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -1875,8 +1875,6 @@ int main(int argc, char **argv, char **envp) {
 
   edit_params(argc, argv, envp);
 
-  if (lto_mode) { setenv("_AFL_LTO_COMPILE", "1", 1); }
-
   if (debug) {
 
     DEBUGF("cd '%s';", getthecwd());
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index cf65d3c1..bbe35fe5 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -421,8 +421,9 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
 
   if (taint) {
 
-    if (len / positions == 1 && positions > CMPLOG_POSITIONS_MAX &&
-        afl->active_paths / afl->colorize_success > CMPLOG_CORPUS_PERCENT) {
+    if (afl->colorize_success &&
+        (len / positions == 1 && positions > CMPLOG_POSITIONS_MAX &&
+         afl->active_paths / afl->colorize_success > CMPLOG_CORPUS_PERCENT)) {
 
 #ifdef _DEBUG
       fprintf(stderr, "Colorization unsatisfactory\n");
diff --git a/test/test-unicorn-mode.sh b/test/test-unicorn-mode.sh
index b4c6eb3e..e197e226 100755
--- a/test/test-unicorn-mode.sh
+++ b/test/test-unicorn-mode.sh
@@ -14,7 +14,7 @@ test -d ../unicorn_mode/unicornafl -a -e ../unicorn_mode/unicornafl/samples/shel
       EASY_INSTALL_FOUND=0
       for PYTHON in $PYTHONS ; do
 
-        if $PYTHON -c "help('easy_install');" </dev/null | grep -q module ; then
+        if $PYTHON -c "import setuptools" ; then
 
             EASY_INSTALL_FOUND=1
             PY=$PYTHON
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index f1d028f8..6c376f8d 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -117,19 +117,19 @@ done
 
 # some python version should be available now
 PYTHONS="`command -v python3` `command -v python` `command -v python2`"
-EASY_INSTALL_FOUND=0
+SETUPTOOLS_FOUND=0
 for PYTHON in $PYTHONS ; do
 
   if $PYTHON -c "import setuptools" ; then
 
-    EASY_INSTALL_FOUND=1
+    SETUPTOOLS_FOUND=1
     PYTHONBIN=$PYTHON
     break
 
   fi
 
 done
-if [ "0" = $EASY_INSTALL_FOUND ]; then
+if [ "0" = $SETUPTOOLS_FOUND ]; then
 
   echo "[-] Error: Python setup-tools not found. Run 'sudo apt-get install python-setuptools', or install python3-setuptools, or run '$PYTHONBIN -m ensurepip', or create a virtualenv, or ..."
   PREREQ_NOTFOUND=1