about summary refs log tree commit diff
path: root/llvm_mode/afl-llvm-lto-instrumentation.so.cc
diff options
context:
space:
mode:
Diffstat (limited to 'llvm_mode/afl-llvm-lto-instrumentation.so.cc')
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc107
1 files changed, 85 insertions, 22 deletions
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index 38c3f202..10482705 100644
--- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
@@ -49,6 +49,7 @@
 #include "llvm/Analysis/MemorySSAUpdater.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/Pass.h"
+#include "llvm/IR/Constants.h"
 
 #include "afl-llvm-common.h"
 
@@ -102,6 +103,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
   std::vector<std::string>         dictionary;
   std::vector<CallInst *>          calls;
   DenseMap<Value *, std::string *> valueMap;
+  std::vector<BasicBlock *>        BlockList;
   char *                           ptr;
   FILE *                           documentFile = NULL;
 
@@ -135,7 +137,10 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   if (getenv("AFL_LLVM_LTO_AUTODICTIONARY")) autodictionary = 1;
 
-  if (getenv("AFL_LLVM_MAP_DYNAMIC")) map_addr = 0;
+  // we make this the default as the fixed map has problems with
+  // defered forkserver, early constructors, ifuncs and maybe more
+  /*if (getenv("AFL_LLVM_MAP_DYNAMIC"))*/
+  map_addr = 0;
 
   if (getenv("AFL_LLVM_SKIPSINGLEBLOCK")) function_minimum_size = 2;
 
@@ -146,7 +151,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
       map_addr = 0;
 
-    } else if (map_addr == 0) {
+    } else if (getenv("AFL_LLVM_MAP_DYNAMIC")) {
 
       FATAL(
           "AFL_LLVM_MAP_ADDR and AFL_LLVM_MAP_DYNAMIC cannot be used together");
@@ -196,7 +201,8 @@ bool AFLLTOPass::runOnModule(Module &M) {
   ConstantInt *Zero = ConstantInt::get(Int8Ty, 0);
   ConstantInt *One = ConstantInt::get(Int8Ty, 1);
 
-  /* This dumps all inialized global strings - might be useful in the future
+  // This dumps all inialized global strings - might be useful in the future
+  /*
   for (auto G=M.getGlobalList().begin(); G!=M.getGlobalList().end(); G++) {
 
     GlobalVariable &GV=*G;
@@ -214,14 +220,20 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   */
 
+  scanForDangerousFunctions(&M);
+
   /* Instrument all the things! */
 
   int inst_blocks = 0;
 
   for (auto &F : M) {
 
-    // fprintf(stderr, "DEBUG: Module %s Function %s\n",
-    // M.getName().str().c_str(), F.getName().str().c_str());
+    /*For debugging
+    AttributeSet X = F.getAttributes().getFnAttributes();
+    fprintf(stderr, "DEBUG: Module %s Function %s attributes %u\n",
+      M.getName().str().c_str(), F.getName().str().c_str(),
+      X.getNumAttributes());
+    */
 
     if (F.size() < function_minimum_size) continue;
     if (isIgnoreFunction(&F)) continue;
@@ -279,14 +291,14 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
           if ((callInst = dyn_cast<CallInst>(&IN))) {
 
-            bool    isStrcmp = true;
-            bool    isMemcmp = true;
-            bool    isStrncmp = true;
-            bool    isStrcasecmp = true;
-            bool    isStrncasecmp = true;
-            bool    isIntMemcpy = true;
-            bool    addedNull = false;
-            uint8_t optLen = 0;
+            bool   isStrcmp = true;
+            bool   isMemcmp = true;
+            bool   isStrncmp = true;
+            bool   isStrcasecmp = true;
+            bool   isStrncasecmp = true;
+            bool   isIntMemcpy = true;
+            bool   addedNull = false;
+            size_t optLen = 0;
 
             Function *Callee = callInst->getCalledFunction();
             if (!Callee) continue;
@@ -299,6 +311,24 @@ bool AFLLTOPass::runOnModule(Module &M) {
             isStrncasecmp &= !FuncName.compare("strncasecmp");
             isIntMemcpy &= !FuncName.compare("llvm.memcpy.p0i8.p0i8.i64");
 
+            /* we do something different here, putting this BB and the
+               successors in a block map */
+            if (!FuncName.compare("__afl_persistent_loop")) {
+
+              BlockList.push_back(&BB);
+              /*
+                            for (succ_iterator SI = succ_begin(&BB), SE =
+                 succ_end(&BB); SI != SE; ++SI) {
+
+                              BasicBlock *succ = *SI;
+                              BlockList.push_back(succ);
+
+                            }
+
+              */
+
+            }
+
             if (!isStrcmp && !isMemcmp && !isStrncmp && !isStrcasecmp &&
                 !isStrncasecmp && !isIntMemcpy)
               continue;
@@ -516,18 +546,27 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
             // add null byte if this is a string compare function and a null
             // was not already added
-            if (addedNull == false && !isMemcmp) {
+            if (!isMemcmp) {
 
-              thestring.append("\0", 1);  // add null byte
-              optLen++;
+              if (addedNull == false) {
+
+                thestring.append("\0", 1);  // add null byte
+                optLen++;
+
+              }
+
+              // ensure we do not have garbage
+              size_t offset = thestring.find('\0', 0);
+              if (offset + 1 < optLen) optLen = offset + 1;
+              thestring = thestring.substr(0, optLen);
 
             }
 
             if (!be_quiet) {
 
               std::string outstring;
-              fprintf(stderr, "%s: length %u/%u \"", FuncName.c_str(), optLen,
-                      (unsigned int)thestring.length());
+              fprintf(stderr, "%s: length %zu/%zu \"", FuncName.c_str(), optLen,
+                      thestring.length());
               for (uint8_t i = 0; i < thestring.length(); i++) {
 
                 uint8_t c = thestring[i];
@@ -563,17 +602,41 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
     for (auto &BB : F) {
 
-      uint32_t succ = 0;
+      if (F.size() == 1) {
+
+        InsBlocks.push_back(&BB);
+        continue;
 
-      if (F.size() == 1) InsBlocks.push_back(&BB);
+      }
 
+      uint32_t succ = 0;
       for (succ_iterator SI = succ_begin(&BB), SE = succ_end(&BB); SI != SE;
            ++SI)
         if ((*SI)->size() > 0) succ++;
-
       if (succ < 2)  // no need to instrument
         continue;
 
+      if (BlockList.size()) {
+
+        int skip = 0;
+        for (uint32_t k = 0; k < BlockList.size(); k++) {
+
+          if (origBB == BlockList[k]) {
+
+            if (debug)
+              fprintf(stderr,
+                      "DEBUG: Function %s skipping BB with/after __afl_loop\n",
+                      F.getName().str().c_str());
+            skip = 1;
+
+          }
+
+        }
+
+        if (skip) continue;
+
+      }
+
       InsBlocks.push_back(&BB);
 
     }
@@ -585,7 +648,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
       do {
 
         --i;
-        BasicBlock *              newBB;
+        BasicBlock *              newBB = NULL;
         BasicBlock *              origBB = &(*InsBlocks[i]);
         std::vector<BasicBlock *> Successors;
         Instruction *             TI = origBB->getTerminator();