about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-08-10 23:42:33 +0200
committervan Hauser <vh@thc.org>2020-08-10 23:42:33 +0200
commit701fb95d24cd754e9c116d81502b6057a29eb2bd (patch)
treeb1fd3fe2eed7f99630835d187ba18febf00ea608
parent7b5a18428e3370856177cb84ec9d3f1c630e0e7c (diff)
downloadafl++-701fb95d24cd754e9c116d81502b6057a29eb2bd.tar.gz
LTO: make dynamic map the default
-rw-r--r--docs/Changelog.md2
-rw-r--r--llvm_mode/README.lto.md20
-rw-r--r--llvm_mode/afl-llvm-lto-instrumentation.so.cc33
-rw-r--r--src/afl-forkserver.c13
4 files changed, 40 insertions, 28 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index f8742b1c..182a15b8 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -28,6 +28,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
        sancov, and also supports function matching!
      - fixes for laf-intel float splitting (thanks to mark-griffin for
        reporting)
+     - LTO: switch default to the dynamic memory map, set AFL_LLVM_MAP_ADDR
+            for a fixed map address (eg. 0x10000)
      - LTO: autodictionary mode is a default
      - LTO: instrim instrumentation disabled, only classic support used
             as it is always better
diff --git a/llvm_mode/README.lto.md b/llvm_mode/README.lto.md
index 4d643324..9046c5a8 100644
--- a/llvm_mode/README.lto.md
+++ b/llvm_mode/README.lto.md
@@ -17,9 +17,6 @@ This version requires a current llvm 11+ compiled from the github master.
 5. If any problems arise be sure to set `AR=llvm-ar RANLIB=llvm-ranlib`.
    Some targets might need `LD=afl-clang-lto` and others `LD=afl-ld-lto`.
 
-6. If a target uses _init functions or early constructors then additionally
-   set `AFL_LLVM_MAP_DYNAMIC=1` as your target will crash otherwise!
-
 ## Introduction and problem description
 
 A big issue with how afl/afl++ works is that the basic block IDs that are
@@ -128,14 +125,14 @@ on start. This improves coverage statistically by 5-10% :)
 
 ## Fixed memory map
 
-To speed up fuzzing, the shared memory map is hard set to a specific address,
-by default 0x10000. In most cases this will work without any problems.
+To speed up fuzzing, it is possible to set a fixed shared memory map.
+Recommened is the value 0x10000.
+In most cases this will work without any problems. However if a target uses
+early constructors, ifuncs or a deferred forkserver this can crash the target.
 On unusual operating systems/processors/kernels or weird libraries this might
 fail so to change the fixed address at compile time set
 AFL_LLVM_MAP_ADDR with a better value (a value of 0 or empty sets the map address
 to be dynamic - the original afl way, which is slower).
-AFL_LLVM_MAP_DYNAMIC can be set so the shared memory address is dynamic (which
-is safer but also slower).
 
 ## Document edge IDs
 
@@ -262,15 +259,6 @@ If this succeeeds then there is an issue with afl-clang-lto. Please report at
 Even some targets where clang-12 fails can be build if the fail is just in
 `./configure`, see `Solving difficult targets` above.
 
-### Target crashes immediately
-
-If the target is using early constructors (priority values smaller than 6)
-or have their own _init/.init functions and these are instrumented then the
-target will likely crash when started. This can be avoided by compiling with
-`AFL_LLVM_MAP_DYNAMIC=1` .
-
-This can e.g. happen with OpenSSL.
-
 ## History
 
 This was originally envisioned by hexcoder- in Summer 2019, however we saw no
diff --git a/llvm_mode/afl-llvm-lto-instrumentation.so.cc b/llvm_mode/afl-llvm-lto-instrumentation.so.cc
index 38c3f202..ddfcb400 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"
 
@@ -135,7 +136,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;
 
@@ -196,7 +200,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;
@@ -212,7 +217,21 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   }
 
-  */
+    */
+
+  if (map_addr)
+    for (GlobalIFunc &IF : M.ifuncs()) {
+
+      // No clue how to follow these up and find the resolver function.
+      // If we would know that resolver function name we could just skip
+      // instrumenting it and everything would be fine :-(
+      // StringRef ifunc_name = IF.getName();
+      // Constant *r = IF.getResolver();
+      FATAL(
+          "Target uses ifunc attribute, dynamic map cannot be used, remove "
+          "AFL_LLVM_MAP_DYNAMIC");
+
+    }
 
   /* Instrument all the things! */
 
@@ -220,8 +239,12 @@ bool AFLLTOPass::runOnModule(Module &M) {
 
   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;
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 752641d7..1ececf27 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -293,8 +293,8 @@ static void report_error_and_exit(int error) {
       FATAL(
           "the fuzzing target reports that hardcoded map address might be the "
           "reason the mmap of the shared memory failed. Solution: recompile "
-          "the target with either afl-clang-lto and the environment variable "
-          "AFL_LLVM_MAP_DYNAMIC set or recompile with afl-clang-fast.");
+          "the target with either afl-clang-lto and do not set "
+          "AFL_LLVM_MAP_ADDR or recompile with afl-clang-fast.");
       break;
     case FS_ERROR_SHM_OPEN:
       FATAL("the fuzzing target reports that the shm_open() call failed.");
@@ -828,8 +828,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
     SAYF("\n" cLRD "[-] " cRST
          "Hmm, looks like the target binary terminated before we could"
          " complete a handshake with the injected code.\n"
-         "If the target was compiled with afl-clang-lto then recompiling with"
-         " AFL_LLVM_MAP_DYNAMIC might solve your problem.\n"
+         "If the target was compiled with afl-clang-lto and AFL_LLVM_MAP_ADDR"
+         " then recompiling without this parameter.\n"
          "Otherwise there is a horrible bug in the fuzzer.\n"
          "Poke <afl-users@googlegroups.com> for troubleshooting tips.\n");
 
@@ -860,9 +860,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
         "    - the target was compiled with afl-clang-lto and a constructor "
         "was\n"
-        "      instrumented, recompiling with AFL_LLVM_MAP_DYNAMIC might solve "
-        "your\n"
-        "      problem\n\n"
+        "      instrumented, recompiling without AFL_LLVM_MAP_ADDR might solve "
+        "your problem\n\n"
 
         "    - Less likely, there is a horrible bug in the fuzzer. If other "
         "options\n"