about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2020-03-10 07:14:42 +0100
committervan Hauser <vh@thc.org>2020-03-10 07:14:42 +0100
commit1148a2d0d1ce43ab89e14eefb70bc410726838c4 (patch)
tree4c2a69940d07cb2fadd8b8a5cbbfdb7f902c8d36
parent38d9aedb26d6c4530763a29fe7695155a21ffbbc (diff)
downloadafl++-1148a2d0d1ce43ab89e14eefb70bc410726838c4.tar.gz
document new environment variables and code format
-rw-r--r--docs/Changelog.md4
-rw-r--r--docs/custom_mutators.md2
-rw-r--r--docs/env_variables.md23
-rw-r--r--include/afl-fuzz.h2
-rw-r--r--include/common.h6
-rw-r--r--include/envs.h13
-rw-r--r--llvm_mode/LLVMInsTrim.so.cc13
-rw-r--r--llvm_mode/MarkNodes.cc13
-rw-r--r--llvm_mode/README.instrim.md9
9 files changed, 61 insertions, 24 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 2a5e36d8..177054e2 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -25,8 +25,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
   - llvm_mode InsTrim mode:
     - removed workaround for bug where paths were not instrumented and 
       imported fix by author
-    - made skipping 1 block functions an option and is disable by default
--> TODO: document this!
+    - made skipping 1 block functions an option and is disable by default,
+      set AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1 to renable this
   - qemu_mode:
     - qemu_mode now uses solely the internal capstone version to fix builds
       on modern Linux distributions
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index 7f95b4af..14d8f518 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -15,7 +15,7 @@ cases beyond those available in AFL. For example, to enable structure-aware
 fuzzing by using libraries that perform mutations according to a given grammar.
 
 The custom mutator is passed to `afl-fuzz` via the `AFL_CUSTOM_MUTATOR_LIBRARY`
-or `AFL_PYTHON_MODULE` environment variable., and must export a fuzz function.
+or `AFL_PYTHON_MODULE` environment variable, and must export a fuzz function.
 Please see [APIs](#2-apis) and [Usage](#3-usage) for detail.
 
 The custom mutation stage is set to be the first non-deterministic stage (right before the havoc stage).
diff --git a/docs/env_variables.md b/docs/env_variables.md
index d1cf6977..8c7510cd 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -91,6 +91,25 @@ of the settings discussed in section #1, with the exception of:
 
 Then there are a few specific features that are only available in llvm_mode:
 
+### LTO
+
+This is a different kind way of instrumentation: first it compiles all
+code in LTO (link time optimization) and then performs an edge inserting
+instrumentation which is 100% collision free (collisions are a big issue
+in afl and afl-like instrumentations). This is performed by using
+afl-clang-lto/afl-clang-lto++ instead of afl-clang-fast, but is only
+built if LLVM 9 or newer is used.
+
+None of these options are necessary to be used and are rather for manual
+use (which only ever the author of this LTO implementation will use ;-)
+These are used if several seperated instrumentation are performed which
+are then later combined.
+
+   - AFL_LLVM_LTO_STARTID sets the starting location ID for the instrumentation.
+     This defaults to 1
+   - AFL_LLVM_LTO_DONTWRITEID prevents that the highest location ID written
+     into the instrumentation is set in a global variable
+
 ### LAF-INTEL
 
     This great feature will split compares to series of single byte comparisons
@@ -126,6 +145,10 @@ Then there are a few specific features that are only available in llvm_mode:
       afl-fuzz will only be able to see the path the loop took, but not how
       many times it was called (unless it is a complex loop).
 
+    - Setting AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1 will skip instrumenting
+      functions with a single basic block. This is useful for most C and
+      some C++ targets.
+
     See llvm_mode/README.instrim.md
 
 ### NOT_ZERO
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index b83d224b..a28608ce 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -516,7 +516,7 @@ typedef struct afl_state {
   /* CmpLog */
 
   char* cmplog_binary;
-  s32 cmplog_child_pid, cmplog_fsrv_pid;
+  s32   cmplog_child_pid, cmplog_fsrv_pid;
 
   /* Custom mutators */
   struct custom_mutator* mutator;
diff --git a/include/common.h b/include/common.h
index 5d0e7266..504783ba 100644
--- a/include/common.h
+++ b/include/common.h
@@ -31,11 +31,11 @@
 #include "types.h"
 #include "stdbool.h"
 
-void detect_file_args(char** argv, u8* prog_in, u8 *use_stdin);
+void detect_file_args(char** argv, u8* prog_in, u8* use_stdin);
 void check_environment_vars(char** env);
 
-char **argv_cpy_dup(int argc, char **argv);
-void argv_cpy_free(char **argv);
+char** argv_cpy_dup(int argc, char** argv);
+void   argv_cpy_free(char** argv);
 
 char** get_qemu_argv(u8* own_loc, u8** target_path_p, int argc, char** argv);
 char** get_wine_argv(u8* own_loc, u8** target_path_p, int argc, char** argv);
diff --git a/include/envs.h b/include/envs.h
index b131f406..82eaf456 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -14,12 +14,13 @@ const char *afl_environment_variables[] = {
     "AFL_INST_LIBS", "AFL_INST_RATIO", "AFL_KEEP_TRACES", "AFL_KEEP_ASSEMBLY",
     "AFL_LD_HARD_FAIL", "AFL_LD_LIMIT_MB", "AFL_LD_NO_CALLOC_OVER",
     "AFL_LD_PRELOAD", "AFL_LD_VERBOSE", "AFL_LLVM_CMPLOG", "AFL_LLVM_INSTRIM",
-    "AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_LAF_SPLIT_COMPARES",
-    "AFL_LLVM_LAF_SPLIT_COMPARES_BITW", "AFL_LLVM_LAF_SPLIT_FLOATS",
-    "AFL_LLVM_LAF_SPLIT_SWITCHES", "AFL_LLVM_LAF_TRANSFORM_COMPARES",
-    "AFL_LLVM_NOT_ZERO", "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY",
-    "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH",
-    "AFL_NO_BUILTIN", "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI",
+    "AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK",
+    "AFL_LLVM_LAF_SPLIT_COMPARES", "AFL_LLVM_LAF_SPLIT_COMPARES_BITW",
+    "AFL_LLVM_LAF_SPLIT_FLOATS", "AFL_LLVM_LAF_SPLIT_SWITCHES",
+    "AFL_LLVM_LAF_TRANSFORM_COMPARES", "AFL_LLVM_NOT_ZERO",
+    "AFL_LLVM_WHITELIST", "AFL_NO_AFFINITY", "AFL_LLVM_LTO_STARTID",
+    "AFL_LLVM_LTO_DONTWRITEID", "AFL_NO_ARITH", "AFL_NO_BUILTIN",
+    "AFL_NO_CPU_RED", "AFL_NO_FORKSRV", "AFL_NO_UI",
     "AFL_NO_X86",  // not really an env but we dont want to warn on it
     "AFL_PATH", "AFL_PERFORMANCE_FILE",
     //"AFL_PERSISTENT", // not implemented anymore, so warn additionally
diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc
index 0fddad24..229d7d24 100644
--- a/llvm_mode/LLVMInsTrim.so.cc
+++ b/llvm_mode/LLVMInsTrim.so.cc
@@ -54,7 +54,7 @@ struct InsTrim : public ModulePass {
 
  protected:
   std::list<std::string> myWhitelist;
-  uint32_t function_minimum_size = 1;
+  uint32_t               function_minimum_size = 1;
 
  private:
   std::mt19937 generator;
@@ -387,15 +387,18 @@ struct InsTrim : public ModulePass {
 
         }
 
-	if (function_minimum_size < 2) {
+        if (function_minimum_size < 2) {
+
           for (BasicBlock &BB : F) {
-            if (MS.find(&BB) == MS.end()) {
-              continue;
-            }
+
+            if (MS.find(&BB) == MS.end()) { continue; }
             IRBuilder<> IRB(&*BB.getFirstInsertionPt());
             IRB.CreateStore(ConstantInt::get(Int32Ty, genLabel()), OldPrev);
+
           }
+
         }
+
       }
 
       for (BasicBlock &BB : F) {
diff --git a/llvm_mode/MarkNodes.cc b/llvm_mode/MarkNodes.cc
index b8587826..cff6c90a 100644
--- a/llvm_mode/MarkNodes.cc
+++ b/llvm_mode/MarkNodes.cc
@@ -393,10 +393,9 @@ bool MarkSubGraph(uint32_t ss, uint32_t tt) {
     MakeUniq(TopoOrder[i]);
 
   }
-  
-   // Check if there is an empty path.
-  if (NextMarked[tt].count(TopoOrder[0]) > 0)
-    return true;
+
+  // Check if there is an empty path.
+  if (NextMarked[tt].count(TopoOrder[0]) > 0) return true;
   return false;
 
 }
@@ -422,7 +421,7 @@ void MarkVertice() {
 
   timeStamp = 0;
   uint32_t t = 0;
-  bool emptyPathExists = true;
+  bool     emptyPathExists = true;
 
   while (s != t) {
 
@@ -430,10 +429,12 @@ void MarkVertice() {
     t = DominatorTree::idom[t];
 
   }
-  
+
   if (emptyPathExists) {
+
     // Mark all exit blocks to catch the empty path.
     Marked.insert(t_Pred[0].begin(), t_Pred[0].end());
+
   }
 
 }
diff --git a/llvm_mode/README.instrim.md b/llvm_mode/README.instrim.md
index b40dbb18..5c3f32c8 100644
--- a/llvm_mode/README.instrim.md
+++ b/llvm_mode/README.instrim.md
@@ -19,6 +19,15 @@ see how often the loop has been rerun.
 This again is a tradeoff for speed for less path information.
 To enable this mode set `AFL_LLVM_INSTRIM_LOOPHEAD=1`.
 
+There is an additional optimization option that skips single block
+functions. In 95% of the C targets and (guess) 50% of the C++ targets
+it is good to enable this, as otherwise pointless instrumentation occurs.
+The corner case where we want this instrumentation is when vtable/call table
+is used and the index to that vtable/call table is not set in specific
+basic blocks.
+To enable skipping these (most of the time) unnecessary instrumentations set
+`AFL_LLVM_INSTRIM_SKIPSINGLEBLOCK=1`
+
 ## Background
 
 The paper: [InsTrim: Lightweight Instrumentation for Coverage-guided Fuzzing]