about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--docs/Changelog.md8
-rw-r--r--include/envs.h2
-rw-r--r--llvm_mode/LLVMInsTrim.so.cc95
-rw-r--r--llvm_mode/afl-llvm-rt.o.c2
-rw-r--r--src/afl-as.c3
-rw-r--r--src/afl-fuzz-one.c4
-rw-r--r--src/afl-fuzz-redqueen.c10
7 files changed, 87 insertions, 37 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 5d781545..0d67e807 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -17,6 +17,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
   - the memory safety checks are now disabled for a little more speed during
     fuzzing (only affects creating queue entries), can be toggled in config.h
   - afl-fuzz:
+     - MOpt out of bounds writing crash fixed
      - now prints the real python version support compiled in
      - set stronger performance compile options and little tweaks
      - Android: prefer bigcores when selecting a CPU
@@ -28,7 +29,12 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
      - bugfix for dictionary insert stage count (fix via Google repo PR)
      - added warning if -M is used together with custom mutators with _ONLY option
      - AFL_TMPDIR checks are now later and better explained if they fail
-  - llvm_mode InsTrim: no pointless instrumentation of 1 block functions
+  - llvm_mode 
+     - InsTrim: three bug fixes:
+        1. (minor) no pointless instrumentation of 1 block functions
+        2. (medium) path bug that leads a few blocks not instrumented that
+           should be
+        3. (major) incorrect prev_loc was written, fixed!
   - afl-clang-fast:
      - show in the help output for which llvm version it was compiled for
      - now does not need to be recompiled between trace-pc and pass
diff --git a/include/envs.h b/include/envs.h
index 4650dc54..8e6e3731 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -59,7 +59,7 @@ const char *afl_environment_variables[] = {
     "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_NO_X86",  // not really an env but we dont want to warn on it
     "AFL_PATH",
     "AFL_PERFORMANCE_FILE",
     "AFL_PERSISTENT",
diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc
index 08d3f68f..afe89ec7 100644
--- a/llvm_mode/LLVMInsTrim.so.cc
+++ b/llvm_mode/LLVMInsTrim.so.cc
@@ -382,19 +382,64 @@ struct InsTrim : public ModulePass {
 
         }
 
-        auto *EBB = &F.getEntryBlock();
-        if (succ_begin(EBB) == succ_end(EBB)) {
+        // Bugfix #1: remove single block function instrumentation
 
-          MS.insert(EBB);
-          total_rs += 1;
+        for (BasicBlock &BB : F) {
 
-        }
+          if (MarkSetOpt && MS.find(&BB) == MS.end()) {
 
-        for (BasicBlock &BB : F) {
+            // Bugfix #2: instrument blocks that should be but InsTrim
+            //            doesn't due to an algorithmic bug
+            int more_than_one = -1;
+
+            for (pred_iterator PI = pred_begin(&BB), E = pred_end(&BB); PI != E;
+                 ++PI) {
+
+              BasicBlock *Pred = *PI;
+              int         count = 0;
+
+              if (more_than_one == -1) more_than_one = 0;
+              for (succ_iterator SI = succ_begin(Pred), E = succ_end(Pred);
+                   SI != E; ++SI) {
+
+                BasicBlock *Succ = *SI;
+                if (Succ != NULL) count++;
+
+              }
+
+              if (count > 1) more_than_one = 1;
+
+            }
+
+            if (more_than_one != 1) continue;
+            for (succ_iterator SI = succ_begin(&BB), E = succ_end(&BB); SI != E;
+                 ++SI) {
+
+              BasicBlock *Succ = *SI;
+              if (Succ != NULL && MS.find(Succ) == MS.end()) {
+
+                int cnt = 0;
+                for (succ_iterator SI2 = succ_begin(Succ), E2 = succ_end(Succ);
+                     SI2 != E2; ++SI2) {
+
+                  BasicBlock *Succ2 = *SI2;
+                  if (Succ2 != NULL) cnt++;
+
+                }
 
-          if (MS.find(&BB) == MS.end()) { continue; }
-          IRBuilder<> IRB(&*BB.getFirstInsertionPt());
-          IRB.CreateStore(ConstantInt::get(Int32Ty, genLabel()), OldPrev);
+                if (cnt == 0) {
+
+                  // fprintf(stderr, "INSERT!\n");
+                  MS.insert(Succ);
+                  total_rs += 1;
+
+                }
+
+              }
+
+            }
+
+          }
 
         }
 
@@ -402,33 +447,24 @@ struct InsTrim : public ModulePass {
 
       for (BasicBlock &BB : F) {
 
-        auto PI = pred_begin(&BB);
-        auto PE = pred_end(&BB);
         if (MarkSetOpt && MS.find(&BB) == MS.end()) { continue; }
 
         IRBuilder<> IRB(&*BB.getFirstInsertionPt());
         Value *     L = NULL;
-        if (PI == PE) {
 
-          L = ConstantInt::get(Int32Ty, genLabel());
+        auto *PN = PHINode::Create(Int32Ty, 0, "", &*BB.begin());
+        DenseMap<BasicBlock *, unsigned> PredMap;
+        for (auto PI = pred_begin(&BB), PE = pred_end(&BB); PI != PE; ++PI) {
 
-        } else {
-
-          auto *PN = PHINode::Create(Int32Ty, 0, "", &*BB.begin());
-          DenseMap<BasicBlock *, unsigned> PredMap;
-          for (auto PI = pred_begin(&BB), PE = pred_end(&BB); PI != PE; ++PI) {
-
-            BasicBlock *PBB = *PI;
-            auto        It = PredMap.insert({PBB, genLabel()});
-            unsigned    Label = It.first->second;
-            PN->addIncoming(ConstantInt::get(Int32Ty, Label), PBB);
-
-          }
-
-          L = PN;
+          BasicBlock *PBB = *PI;
+          auto        It = PredMap.insert({PBB, genLabel()});
+          unsigned    Label = It.first->second;
+          PN->addIncoming(ConstantInt::get(Int32Ty, Label), PBB);
 
         }
 
+        L = PN;
+
         /* Load prev_loc */
         LoadInst *PrevLoc = IRB.CreateLoad(OldPrev);
         PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
@@ -475,6 +511,11 @@ struct InsTrim : public ModulePass {
         IRB.CreateStore(Incr, MapPtrIdx)
             ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
 
+        // Bugfix #3: save the actually location ID to OldPrev
+        Value *Shr = IRB.CreateLShr(L, One);
+        IRB.CreateStore(Shr, OldPrev)
+            ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
+
         total_instr++;
 
       }
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
index 53852320..93b03bb2 100644
--- a/llvm_mode/afl-llvm-rt.o.c
+++ b/llvm_mode/afl-llvm-rt.o.c
@@ -129,7 +129,7 @@ static void __afl_map_shm(void) {
     __afl_area_ptr[0] = 1;
 
   }
-  
+
   id_str = getenv(CMPLOG_SHM_ENV_VAR);
 
   if (id_str) {
diff --git a/src/afl-as.c b/src/afl-as.c
index acb026df..98bd3ff5 100644
--- a/src/afl-as.c
+++ b/src/afl-as.c
@@ -530,7 +530,8 @@ int main(int argc, char** argv) {
 
         "Rarely, when dealing with extremely complex projects, it may be "
         "advisable\n"
-        "to set AFL_INST_RATIO to a value less than 100 in order to reduce the\n"
+        "to set AFL_INST_RATIO to a value less than 100 in order to reduce "
+        "the\n"
         "odds of instrumenting every discovered branch.\n\n"
         "Environment variables used:\n"
         "AFL_AS: path to assembler to use for instrumented files\n"
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 0ddeeb8a..f1efe2df 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -3714,7 +3714,7 @@ pacemaker_fuzzing:
 
             case 1:
               if (temp_len < 2) break;
-              temp_len_puppet = UR((temp_len << 3) -1);
+              temp_len_puppet = UR((temp_len << 3) - 1);
               FLIP_BIT(out_buf, temp_len_puppet);
               FLIP_BIT(out_buf, temp_len_puppet + 1);
               MOpt_globals.cycles_v2[STAGE_FLIP2] += 1;
@@ -3722,7 +3722,7 @@ pacemaker_fuzzing:
 
             case 2:
               if (temp_len < 2) break;
-              temp_len_puppet = UR((temp_len << 3) -3);
+              temp_len_puppet = UR((temp_len << 3) - 3);
               FLIP_BIT(out_buf, temp_len_puppet);
               FLIP_BIT(out_buf, temp_len_puppet + 1);
               FLIP_BIT(out_buf, temp_len_puppet + 2);
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 6cb229e3..19fc51f0 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -243,7 +243,7 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx,
 
   if (SHAPE_BYTES(h->shape) == 8) {
 
-    if (its_len >= 8 && *buf_64 == pattern) {// && *o_buf_64 == pattern) {
+    if (its_len >= 8 && *buf_64 == pattern) {  // && *o_buf_64 == pattern) {
 
       *buf_64 = repl;
       if (unlikely(its_fuzz(buf, len, status))) return 1;
@@ -261,7 +261,8 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx,
 
   if (SHAPE_BYTES(h->shape) == 4 || *status == 2) {
 
-    if (its_len >= 4 && *buf_32 == (u32)pattern) {// && *o_buf_32 == (u32)pattern) {
+    if (its_len >= 4 &&
+        *buf_32 == (u32)pattern) {  // && *o_buf_32 == (u32)pattern) {
 
       *buf_32 = (u32)repl;
       if (unlikely(its_fuzz(buf, len, status))) return 1;
@@ -279,7 +280,8 @@ u8 cmp_extend_encoding(struct cmp_header* h, u64 pattern, u64 repl, u32 idx,
 
   if (SHAPE_BYTES(h->shape) == 2 || *status == 2) {
 
-    if (its_len >= 2 && *buf_16 == (u16)pattern) {// && *o_buf_16 == (u16)pattern) {
+    if (its_len >= 2 &&
+        *buf_16 == (u16)pattern) {  // && *o_buf_16 == (u16)pattern) {
 
       *buf_16 = (u16)repl;
       if (unlikely(its_fuzz(buf, len, status))) return 1;
@@ -531,7 +533,7 @@ u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len,
       stage_max += MIN(cmp_map->headers[k].hits, CMP_MAP_RTN_H);
 
   }
-  
+
   for (k = 0; k < CMP_MAP_W; ++k) {
 
     if (!cmp_map->headers[k].hits) continue;