about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-08-11 02:05:39 +0200
committervan Hauser <vh@thc.org>2020-08-11 02:05:39 +0200
commit50e76fce123f01ec83024f3bbd3190f2e1a6d387 (patch)
tree4d701919ada33e3c26a078bc571903abd4e258e0
parent432638404f40594ae163b6e1b92fcfd51b59d59a (diff)
downloadafl++-50e76fce123f01ec83024f3bbd3190f2e1a6d387.tar.gz
adding ctor function skipping in LTO fixed map mode
-rw-r--r--docs/Changelog.md1
-rw-r--r--include/debug.h52
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc76
3 files changed, 90 insertions, 39 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 182a15b8..25c7a761 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -30,6 +30,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
        reporting)
      - LTO: switch default to the dynamic memory map, set AFL_LLVM_MAP_ADDR
             for a fixed map address (eg. 0x10000)
+     - LTO: skipping ctors and ifuncs in fix map address instrumentation
      - LTO: autodictionary mode is a default
      - LTO: instrim instrumentation disabled, only classic support used
             as it is always better
diff --git a/include/debug.h b/include/debug.h
index 6cc26ec2..f9ebce58 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -218,43 +218,43 @@
 
 /* Die with a verbose non-OS fatal error message. */
 
-#define FATAL(x...)                                                          \
-  do {                                                                       \
-                                                                             \
-    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                                \
-         "\n[-] PROGRAM ABORT : " cRST   x);                                   \
+#define FATAL(x...)                                                      \
+  do {                                                                   \
+                                                                         \
+    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                            \
+         "\n[-] PROGRAM ABORT : " cRST   x);                               \
     SAYF(cLRD "\n         Location : " cRST "%s(), %s:%u\n\n", __func__, \
-         __FILE__, __LINE__);                                                \
-    exit(1);                                                                 \
-                                                                             \
+         __FILE__, __LINE__);                                            \
+    exit(1);                                                             \
+                                                                         \
   } while (0)
 
 /* Die by calling abort() to provide a core dump. */
 
-#define ABORT(x...)                                                          \
-  do {                                                                       \
-                                                                             \
-    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                                \
-         "\n[-] PROGRAM ABORT : " cRST   x);                                   \
+#define ABORT(x...)                                                      \
+  do {                                                                   \
+                                                                         \
+    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                            \
+         "\n[-] PROGRAM ABORT : " cRST   x);                               \
     SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n\n", __func__, \
-         __FILE__, __LINE__);                                                \
-    abort();                                                                 \
-                                                                             \
+         __FILE__, __LINE__);                                            \
+    abort();                                                             \
+                                                                         \
   } while (0)
 
 /* Die while also including the output of perror(). */
 
-#define PFATAL(x...)                                                       \
-  do {                                                                     \
-                                                                           \
-    fflush(stdout);                                                        \
-    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                              \
-         "\n[-]  SYSTEM ERROR : " cRST   x);                                 \
+#define PFATAL(x...)                                                   \
+  do {                                                                 \
+                                                                       \
+    fflush(stdout);                                                    \
+    SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD                          \
+         "\n[-]  SYSTEM ERROR : " cRST   x);                             \
     SAYF(cLRD "\n    Stop location : " cRST "%s(), %s:%u\n", __func__, \
-         __FILE__, __LINE__);                                              \
-    SAYF(cLRD "       OS message : " cRST "%s\n", strerror(errno));        \
-    exit(1);                                                               \
-                                                                           \
+         __FILE__, __LINE__);                                          \
+    SAYF(cLRD "       OS message : " cRST "%s\n", strerror(errno));    \
+    exit(1);                                                           \
+                                                                       \
   } while (0)
 
 /* Die with FATAL() or PFATAL() depending on the value of res (used to
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index abc836aa..fd8e48a7 100644
--- a/llvm_mode/afl-llvm-lto-instrumentation.so.cc
+++ b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
@@ -224,22 +224,70 @@ bool AFLLTOPass::runOnModule(Module &M) {
   if (map_addr) {
 
     for (GlobalIFunc &IF : M.ifuncs()) {
-    
+
       StringRef ifunc_name = IF.getName();
       Constant *r = IF.getResolver();
       StringRef r_name = cast<Function>(r->getOperand(0))->getName();
       if (!be_quiet)
-        fprintf(stderr, "Found an ifunc with name %s that  points to resolver function %s, we cannot instrument this, putting it into a block list.\n",
+        fprintf(stderr,
+                "Warning: Found an ifunc with name %s that points to resolver "
+                "function %s, we cannot instrument this, putting it into a "
+                "block list.\n",
                 ifunc_name.str().c_str(), r_name.str().c_str());
-
       module_block_list.push_back(r_name.str());
 
     }
 
-    // next up: ctors run before __afl_init()
-    
-    // TODO
+    GlobalVariable *GV = M.getNamedGlobal("llvm.global_ctors");
+    if (GV && !GV->isDeclaration() && !GV->hasLocalLinkage()) {
+
+      ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
+
+      if (InitList) {
+
+        for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
+
+          if (ConstantStruct *CS =
+                  dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
+
+            if (CS->getNumOperands() >= 2) {
 
+              if (CS->getOperand(1)->isNullValue())
+                break;  // Found a null terminator, stop here.
+
+              ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
+              int          Priority = CI ? CI->getSExtValue() : 0;
+
+              Constant *FP = CS->getOperand(1);
+              if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
+                if (CE->isCast()) FP = CE->getOperand(0);
+              if (Function *F = dyn_cast<Function>(FP)) {
+
+                if (!F->isDeclaration() &&
+                    strncmp(F->getName().str().c_str(), "__afl", 5) != 0 &&
+                    Priority <= 5) {
+
+                  if (!be_quiet)
+                    fprintf(stderr,
+                            "Warning: Found constructor function %s with prio "
+                            "%u, we cannot instrument this, putting it into a "
+                            "block list.\n",
+                            F->getName().str().c_str(), Priority);
+                  module_block_list.push_back(F->getName().str());
+
+                }
+
+              }
+
+            }
+
+          }
+
+        }
+
+      }
+
+    }
 
   }
 
@@ -260,21 +308,23 @@ bool AFLLTOPass::runOnModule(Module &M) {
     if (isIgnoreFunction(&F)) continue;
 
     if (module_block_list.size()) {
-    
+
       for (auto bname : module_block_list) {
 
         std::string fname = F.getName().str();
 
         if (fname.compare(bname) == 0) {
-        
+
           if (!be_quiet)
-            WARNF("Skipping instrumentation of ifunc resolver function %s",
-                  fname.c_str());
-        
+            WARNF(
+                "Skipping instrumentation of dangerous early running function "
+                "%s",
+                fname.c_str());
+
         }
-      
+
       }
-    
+
     }
 
     // the instrument file list check