diff options
author | vanhauser-thc <vh@thc.org> | 2021-03-25 15:35:06 +0100 |
---|---|---|
committer | vanhauser-thc <vh@thc.org> | 2021-03-25 15:35:06 +0100 |
commit | 0029c1a83ef03825c2d19c73151189f159458496 (patch) | |
tree | 6a21d22eaa597b57636b01feec76b8bc23c5d3c4 | |
parent | 447d232caf9fcd9e6e40c24d17000ff9b98ab693 (diff) | |
download | afl++-0029c1a83ef03825c2d19c73151189f159458496.tar.gz |
remove InsTrim
-rw-r--r-- | GNUmakefile.llvm | 5 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | docs/Changelog.md | 2 | ||||
-rw-r--r-- | docs/PATCHES.md | 43 | ||||
-rw-r--r-- | docs/env_variables.md | 27 | ||||
-rw-r--r-- | docs/perf_tips.md | 3 | ||||
-rw-r--r-- | instrumentation/LLVMInsTrim.so.cc | 599 | ||||
-rw-r--r-- | instrumentation/MarkNodes.cc | 481 | ||||
-rw-r--r-- | instrumentation/MarkNodes.h | 12 | ||||
-rw-r--r-- | instrumentation/README.instrim.md | 30 | ||||
-rw-r--r-- | instrumentation/README.llvm.md | 17 | ||||
-rw-r--r-- | instrumentation/README.snapshot.md | 2 | ||||
-rw-r--r-- | src/afl-cc.c | 50 | ||||
-rw-r--r-- | src/afl-ld-lto.c | 20 | ||||
-rwxr-xr-x | test/test-llvm.sh | 21 |
15 files changed, 29 insertions, 1284 deletions
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index 111a847d..4b5ac520 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -304,7 +304,7 @@ ifeq "$(TEST_MMAP)" "1" endif PROGS_ALWAYS = ./afl-cc ./afl-compiler-rt.o ./afl-compiler-rt-32.o ./afl-compiler-rt-64.o -PROGS = $(PROGS_ALWAYS) ./afl-llvm-pass.so ./SanitizerCoveragePCGUARD.so ./split-compares-pass.so ./split-switches-pass.so ./cmplog-routines-pass.so ./cmplog-instructions-pass.so ./afl-llvm-dict2file.so ./compare-transform-pass.so ./libLLVMInsTrim.so ./afl-ld-lto ./afl-llvm-lto-instrumentlist.so ./afl-llvm-lto-instrumentation.so ./SanitizerCoverageLTO.so +PROGS = $(PROGS_ALWAYS) ./afl-llvm-pass.so ./SanitizerCoveragePCGUARD.so ./split-compares-pass.so ./split-switches-pass.so ./cmplog-routines-pass.so ./cmplog-instructions-pass.so ./afl-llvm-dict2file.so ./compare-transform-pass.so ./afl-ld-lto ./afl-llvm-lto-instrumentlist.so ./afl-llvm-lto-instrumentation.so ./SanitizerCoverageLTO.so # If prerequisites are not given, warn, do not build anything, and exit with code 0 ifeq "$(LLVMVER)" "" @@ -382,9 +382,6 @@ endif instrumentation/afl-llvm-common.o: instrumentation/afl-llvm-common.cc instrumentation/afl-llvm-common.h $(CXX) $(CFLAGS) $(CPPFLAGS) `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC -std=$(LLVM_STDCXX) -c $< -o $@ -./libLLVMInsTrim.so: instrumentation/LLVMInsTrim.so.cc instrumentation/MarkNodes.cc instrumentation/afl-llvm-common.o | test_deps - -$(CXX) $(CLANG_CPPFL) -DLLVMInsTrim_EXPORTS -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< instrumentation/MarkNodes.cc -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o - ./afl-llvm-pass.so: instrumentation/afl-llvm-pass.so.cc instrumentation/afl-llvm-common.o | test_deps ifeq "$(LLVM_MIN_4_0_1)" "0" $(info [!] N-gram branch coverage instrumentation is not available for llvm version $(LLVMVER)) diff --git a/README.md b/README.md index 2de35d11..3ba05777 100644 --- a/README.md +++ b/README.md @@ -370,7 +370,6 @@ There are many more options and modes available however these are most of the time less effective. See: * [instrumentation/README.ctx.md](instrumentation/README.ctx.md) * [instrumentation/README.ngram.md](instrumentation/README.ngram.md) - * [instrumentation/README.instrim.md](instrumentation/README.instrim.md) afl++ performs "never zero" counting in its bitmap. You can read more about this here: diff --git a/docs/Changelog.md b/docs/Changelog.md index 87ac858e..730791da 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -16,6 +16,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>. to allow replay of non-reproducable crashes, see AFL_PERSISTENT_RECORD in config.h and docs/envs.h - default cmplog level (-l) is now 2, better efficiency. + - afl-cc: + - Removed InsTrim instrumentation as it is not as good as PCGUARD ### Version ++3.12c (release) - afl-fuzz: diff --git a/docs/PATCHES.md b/docs/PATCHES.md deleted file mode 100644 index b2cff43a..00000000 --- a/docs/PATCHES.md +++ /dev/null @@ -1,43 +0,0 @@ -# Applied Patches - -The following patches from https://github.com/vanhauser-thc/afl-patches -have been installed or not installed: - - -## INSTALLED -``` -afl-llvm-fix.diff by kcwu(at)csie(dot)org -afl-sort-all_uniq-fix.diff by legarrec(dot)vincent(at)gmail(dot)com -laf-intel.diff by heiko(dot)eissfeldt(at)hexco(dot)de -afl-llvm-optimize.diff by mh(at)mh-sec(dot)de -afl-fuzz-tmpdir.diff by mh(at)mh-sec(dot)de -afl-fuzz-79x24.diff by heiko(dot)eissfeldt(at)hexco(dot)de -afl-fuzz-fileextensionopt.diff tbd -afl-as-AFL_INST_RATIO.diff by legarrec(dot)vincent(at)gmail(dot)com -afl-qemu-ppc64.diff by william(dot)barsse(at)airbus(dot)com -afl-qemu-optimize-entrypoint.diff by mh(at)mh-sec(dot)de -afl-qemu-speed.diff by abiondo on github -afl-qemu-optimize-map.diff by mh(at)mh-sec(dot)de -``` - -+ llvm_mode ngram prev_loc coverage (github.com/adrianherrera/afl-ngram-pass) -+ Custom mutator (native library) (by kyakdan) -+ unicorn_mode (modernized and updated by domenukk) -+ instrim (https://github.com/csienslab/instrim) was integrated -+ MOpt (github.com/puppet-meteor/MOpt-AFL) was imported -+ AFLfast additions (github.com/mboehme/aflfast) were incorporated. -+ Qemu 3.1 upgrade with enhancement patches (github.com/andreafioraldi/afl) -+ Python mutator modules support (github.com/choller/afl) -+ Instrument file list in LLVM mode (github.com/choller/afl) -+ forkserver patch for afl-tmin (github.com/nccgroup/TriforceAFL) - - -## NOT INSTALLED - -``` -afl-fuzz-context_sensitive.diff - changes too much of the behaviour -afl-tmpfs.diff - same as afl-fuzz-tmpdir.diff but more complex -afl-cmin-reduce-dataset.diff - unsure of the impact -afl-llvm-fix2.diff - not needed with the other patches -``` - diff --git a/docs/env_variables.md b/docs/env_variables.md index 6d3d1714..572fad01 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -130,16 +130,15 @@ Then there are a few specific features that are only available in instrumentatio PCGUARD - our own pcgard based instrumentation (default) NATIVE - clang's original pcguard based instrumentation CLASSIC - classic AFL (map[cur_loc ^ prev_loc >> 1]++) (default) - CFG - InsTrim instrumentation (see below) LTO - LTO instrumentation (see below) CTX - context sensitive instrumentation (see below) NGRAM-x - deeper previous location coverage (from NGRAM-2 up to NGRAM-16) GCC - outdated gcc instrumentation CLANG - outdated clang instrumentation - In CLASSIC (default) and CFG/INSTRIM you can also specify CTX and/or - NGRAM, seperate the options with a comma "," then, e.g.: - `AFL_LLVM_INSTRUMENT=CFG,CTX,NGRAM-4` - Not that this is a good idea to use both CTX and NGRAM :) + In CLASSIC you can also specify CTX and/or NGRAM, seperate the options + with a comma "," then, e.g.: + `AFL_LLVM_INSTRUMENT=CLASSIC,CTX,NGRAM-4` + Note that this is actually not a good idea to use both CTX and NGRAM :) ### LTO @@ -173,24 +172,6 @@ Then there are a few specific features that are only available in instrumentatio See [instrumentation/README.lto.md](../instrumentation/README.lto.md) for more information. -### INSTRIM - - This feature increases the speed by ~15% without any disadvantages to the - classic instrumentation. - - Note that there is also an LTO version (if you have llvm 11 or higher) - - that is the best instrumentation we have. Use `afl-clang-lto` to activate. - The InsTrim LTO version additionally has all the options and features of - LTO (see above). - - - Setting `AFL_LLVM_INSTRIM` or `AFL_LLVM_INSTRUMENT=CFG` activates this mode - - - Setting `AFL_LLVM_INSTRIM_LOOPHEAD=1` expands on INSTRIM to optimize loops. - 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). - - See [instrumentation/README.instrim.md](../instrumentation/README.instrim.md) - ### NGRAM - Setting `AFL_LLVM_NGRAM_SIZE` or `AFL_LLVM_INSTRUMENT=NGRAM-{value}` diff --git a/docs/perf_tips.md b/docs/perf_tips.md index fbcb4d8d..c5968206 100644 --- a/docs/perf_tips.md +++ b/docs/perf_tips.md @@ -69,9 +69,6 @@ If you are only interested in specific parts of the code being fuzzed, you can instrument_files the files that are actually relevant. This improves the speed and accuracy of afl. See instrumentation/README.instrument_list.md -Also use the InsTrim mode on larger binaries, this improves performance and -coverage a lot. - ## 4. Profile and optimize the binary Check for any parameters or settings that obviously improve performance. For diff --git a/instrumentation/LLVMInsTrim.so.cc b/instrumentation/LLVMInsTrim.so.cc deleted file mode 100644 index 62de6ec5..00000000 --- a/instrumentation/LLVMInsTrim.so.cc +++ /dev/null @@ -1,599 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <unistd.h> - -#include "llvm/Config/llvm-config.h" -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5 -typedef long double max_align_t; -#endif - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" -#if LLVM_VERSION_MAJOR > 3 || \ - (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) - #include "llvm/IR/CFG.h" - #include "llvm/IR/Dominators.h" - #include "llvm/IR/DebugInfo.h" -#else - #include "llvm/Support/CFG.h" - #include "llvm/Analysis/Dominators.h" - #include "llvm/DebugInfo.h" -#endif -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/IR/Module.h" -#include "llvm/Pass.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/IR/BasicBlock.h" -#include <unordered_set> -#include <random> -#include <list> -#include <string> -#include <fstream> - -#include "MarkNodes.h" -#include "afl-llvm-common.h" -#include "llvm-alternative-coverage.h" - -#include "config.h" -#include "debug.h" - -using namespace llvm; - -static cl::opt<bool> MarkSetOpt("markset", cl::desc("MarkSet"), - cl::init(false)); -static cl::opt<bool> LoopHeadOpt("loophead", cl::desc("LoopHead"), - cl::init(false)); - -namespace { - -struct InsTrim : public ModulePass { - - protected: - uint32_t function_minimum_size = 1; - char * skip_nozero = NULL; - - private: - std::mt19937 generator; - int total_instr = 0; - - unsigned int genLabel() { - - return generator() & (MAP_SIZE - 1); - - } - - public: - static char ID; - - InsTrim() : ModulePass(ID), generator(0) { - - initInstrumentList(); - - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - - AU.addRequired<DominatorTreeWrapperPass>(); - - } - -#if LLVM_VERSION_MAJOR < 4 - const char * -#else - StringRef -#endif - getPassName() const override { - - return "InstTrim Instrumentation"; - - } - -#if LLVM_VERSION_MAJOR > 4 || \ - (LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1) - #define AFL_HAVE_VECTOR_INTRINSICS 1 -#endif - - bool runOnModule(Module &M) override { - - setvbuf(stdout, NULL, _IONBF, 0); - - if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) { - - SAYF(cCYA "LLVMInsTrim" VERSION cRST " by csienslab\n"); - - } else - - be_quiet = 1; - - if (getenv("AFL_DEBUG") != NULL) debug = 1; - - LLVMContext &C = M.getContext(); - - IntegerType *Int8Ty = IntegerType::getInt8Ty(C); - IntegerType *Int32Ty = IntegerType::getInt32Ty(C); - -#if LLVM_VERSION_MAJOR < 9 - char *neverZero_counters_str; - if ((neverZero_counters_str = getenv("AFL_LLVM_NOT_ZERO")) != NULL) - if (!be_quiet) OKF("LLVM neverZero activated (by hexcoder)\n"); -#endif - skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO"); - - if (getenv("AFL_LLVM_INSTRIM_LOOPHEAD") != NULL || - getenv("LOOPHEAD") != NULL) { - - LoopHeadOpt = true; - - } - - unsigned int PrevLocSize = 0; - char * ngram_size_str = getenv("AFL_LLVM_NGRAM_SIZE"); - if (!ngram_size_str) ngram_size_str = getenv("AFL_NGRAM_SIZE"); - char *caller_str = getenv("AFL_LLVM_CALLER"); - -#ifdef AFL_HAVE_VECTOR_INTRINSICS - unsigned int ngram_size = 0; - /* Decide previous location vector size (must be a power of two) */ - VectorType *PrevLocTy = NULL; - - if (ngram_size_str) - if (sscanf(ngram_size_str, "%u", &ngram_size) != 1 || ngram_size < 2 || - ngram_size > NGRAM_SIZE_MAX) - FATAL( - "Bad value of AFL_NGRAM_SIZE (must be between 2 and NGRAM_SIZE_MAX " - "(%u))", - NGRAM_SIZE_MAX); - - if (ngram_size) - PrevLocSize = ngram_size - 1; - else -#else - if (ngram_size_str) - #ifdef LLVM_VERSION_STRING - FATAL( - "Sorry, NGRAM branch coverage is not supported with llvm version %s!", - LLVM_VERSION_STRING); - #else - #ifndef LLVM_VERSION_PATCH - FATAL( - "Sorry, NGRAM branch coverage is not supported with llvm version " - "%d.%d.%d!", - LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, 0); - #else - FATAL( - "Sorry, NGRAM branch coverage is not supported with llvm version " - "%d.%d.%d!", - LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERISON_PATCH); - #endif - #endif -#endif - PrevLocSize = 1; - -#ifdef AFL_HAVE_VECTOR_INTRINSICS - // IntegerType *Int64Ty = IntegerType::getInt64Ty(C); - int PrevLocVecSize = PowerOf2Ceil(PrevLocSize); - IntegerType *IntLocTy = - IntegerType::getIntNTy(C, sizeof(PREV_LOC_T) * CHAR_BIT); - if (ngram_size) - PrevLocTy = VectorType::get(IntLocTy, PrevLocVecSize - #if LLVM_VERSION_MAJOR >= 12 - , - false - #endif - ); -#endif - - /* Get globals for the SHM region and the previous location. Note that - __afl_prev_loc is thread-local. */ - - GlobalVariable *AFLMapPtr = - new GlobalVariable(M, PointerType::get(Int8Ty, 0), false, - GlobalValue::ExternalLinkage, 0, "__afl_area_ptr"); - GlobalVariable *AFLPrevLoc; - GlobalVariable *AFLContext = NULL; - LoadInst * PrevCaller = NULL; // for CALLER sensitive coverage - - if (caller_str) -#if defined(__ANDROID__) || defined(__HAIKU__) - AFLContext = new GlobalVariable( - M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx"); -#else - AFLContext = new GlobalVariable( - M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_ctx", - 0, GlobalVariable::GeneralDynamicTLSModel, 0, false); -#endif - -#ifdef AFL_HAVE_VECTOR_INTRINSICS - if (ngram_size) - #if defined(__ANDROID__) || defined(__HAIKU__) - AFLPrevLoc = new GlobalVariable( - M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage, - /* Initializer */ nullptr, "__afl_prev_loc"); - #else - AFLPrevLoc = new GlobalVariable( - M, PrevLocTy, /* isConstant */ false, GlobalValue::ExternalLinkage, - /* Initializer */ nullptr, "__afl_prev_loc", - /* InsertBefore */ nullptr, GlobalVariable::GeneralDynamicTLSModel, - /* AddressSpace */ 0, /* IsExternallyInitialized */ false); - #endif - else -#endif -#if defined(__ANDROID__) || defined(__HAIKU__) - AFLPrevLoc = new GlobalVariable( - M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc"); -#else - AFLPrevLoc = new GlobalVariable( - M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc", 0, - GlobalVariable::GeneralDynamicTLSModel, 0, false); -#endif - -#ifdef AFL_HAVE_VECTOR_INTRINSICS - /* Create the vector shuffle mask for updating the previous block history. - Note that the first element of the vector will store cur_loc, so just set - it to undef to allow the optimizer to do its thing. */ - - SmallVector<Constant *, 32> PrevLocShuffle = {UndefValue::get(Int32Ty)}; - - for (unsigned I = 0; I < PrevLocSize - 1; ++I) - PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, I)); - - for (int I = PrevLocSize; I < PrevLocVecSize; ++I) - PrevLocShuffle.push_back(ConstantInt::get(Int32Ty, PrevLocSize)); - - Constant *PrevLocShuffleMask = ConstantVector::get(PrevLocShuffle); -#endif - - // this is our default - MarkSetOpt = true; - - ConstantInt *Zero = ConstantInt::get(Int8Ty, 0); - ConstantInt *One = ConstantInt::get(Int8Ty, 1); - - u64 total_rs = 0; - u64 total_hs = 0; - - scanForDangerousFunctions(&M); - - for (Function &F : M) { - - if (debug) { - - uint32_t bb_cnt = 0; - - for (auto &BB : F) - if (BB.size() > 0) ++bb_cnt; - DEBUGF("Function %s size %zu %u\n", F.getName().str().c_str(), F.size(), - bb_cnt); - - } - - if (!isInInstrumentList(&F)) continue; - - // if the function below our minimum size skip it (1 or 2) - if (F.size() < function_minimum_size) { continue; } - - std::unordered_set<BasicBlock *> MS; - if (!MarkSetOpt) { - - for (auto &BB : F) { - - MS.insert(&BB); - - } - - total_rs += F.size(); - - } else { - - auto Result = markNodes(&F); - auto RS = Result.first; - auto HS = Result.second; - - MS.insert(RS.begin(), RS.end()); - if (!LoopHeadOpt) { - - MS.insert(HS.begin(), HS.end()); - total_rs += MS.size(); - - } else { - - DenseSet<std::pair<BasicBlock *, BasicBlock *>> EdgeSet; - DominatorTreeWrapperPass * DTWP = - &getAnalysis<DominatorTreeWrapperPass>(F); - auto DT = &DTWP->getDomTree(); - - total_rs += RS.size(); - total_hs += HS.size(); - - for (BasicBlock *BB : HS) { - - bool Inserted = false; - for (auto BI = pred_begin(BB), BE = pred_end(BB); BI != BE; ++BI) { - - auto Edge = BasicBlockEdge(*BI, BB); - if (Edge.isSingleEdge() && DT->dominates(Edge, BB)) { - - EdgeSet.insert({*BI, BB}); - Inserted = true; - break; - - } - - } - - if (!Inserted) { - - MS.insert(BB); - total_rs += 1; - total_hs -= 1; - - } - - } - - for (auto I = EdgeSet.begin(), E = EdgeSet.end(); I != E; ++I) { - - auto PredBB = I->first; - auto SuccBB = I->second; - auto NewBB = - SplitBlockPredecessors(SuccBB, {PredBB}, ".split", DT, nullptr, -#if LLVM_VERSION_MAJOR >= 8 - nullptr, -#endif - false); - MS.insert(NewBB); - - } - - } - - for (BasicBlock &BB : F) { - - if (MS.find(&BB) == MS.end()) { continue; } - IRBuilder<> IRB(&*BB.getFirstInsertionPt()); - -#ifdef AFL_HAVE_VECTOR_INTRINSICS - if (ngram_size) { - - LoadInst *PrevLoc = IRB.CreateLoad(AFLPrevLoc); - PrevLoc->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); - - Value *ShuffledPrevLoc = IRB.CreateShuffleVector( - PrevLoc, UndefValue::get(PrevLocTy), PrevLocShuffleMask); - Value *UpdatedPrevLoc = IRB.CreateInsertElement( - ShuffledPrevLoc, ConstantInt::get(Int32Ty, genLabel()), - (uint64_t)0); - - IRB.CreateStore(UpdatedPrevLoc, AFLPrevLoc) - ->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); - - } else - -#endif - { - - IRB.CreateStore(ConstantInt::get(Int32Ty, genLabel()), AFLPrevLoc); - - } - - } - - } - - int has_calls = 0; - for (BasicBlock &BB : F) { - - auto PI = pred_begin(&BB); - auto PE = pred_end(&BB); - IRBuilder<> IRB(&*BB.getFirstInsertionPt()); - Value * L = NULL; - unsigned int cur_loc; - - // Context sensitive coverage - if (caller_str && &BB == &F.getEntryBlock()) { - - PrevCaller = IRB.CreateLoad(AFLContext); - PrevCaller->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); - - // does the function have calls? and is any of the calls larger than - // one basic block? - has_calls = 0; - for (auto &BB2 : F) { - - if (has_calls) break; - for (auto &IN : BB2) { - - CallInst *callInst = nullptr; - if ((callInst = dyn_cast<CallInst>(&IN))) { - - Function *Callee = callInst->getCalledFunction(); - if (!Callee || Callee->size() < function_minimum_size) - continue; - else { - - has_calls = 1; - break; - - } - - } - - } - - } - - // if yes we store a context ID for this function in the global var - if (has_calls) { - - ConstantInt *NewCtx = ConstantInt::get(Int32Ty, genLabel()); - StoreInst * StoreCtx = IRB.CreateStore(NewCtx, AFLContext); - StoreCtx->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); - - } - - } // END of caller_str - - if (MarkSetOpt && MS.find(&BB) == MS.end()) { continue; } - - if (PI == PE) { - - cur_loc = genLabel(); - L = ConstantInt::get(Int32Ty, cur_loc); - - } else { - - auto *PN = PHINode::Create(Int32Ty, 0, "", &*BB.begin()); - DenseMap<BasicBlock *, unsigned> PredMap; - for (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; - // cur_loc = Label; - PN->addIncoming(ConstantInt::get(Int32Ty, Label), PBB); - - } - - L = PN; - - } - - /* Load prev_loc */ - LoadInst *PrevLoc = IRB.CreateLoad(AFLPrevLoc); - PrevLoc->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - Value *PrevLocTrans; - -#ifdef AFL_HAVE_VECTOR_INTRINSICS - /* "For efficiency, we propose to hash the tuple as a key into the - hit_count map as (prev_block_trans << 1) ^ curr_block_trans, where - prev_block_trans = (block_trans_1 ^ ... ^ block_trans_(n-1)" */ - - if (ngram_size) - PrevLocTrans = - IRB.CreateZExt(IRB.CreateXorReduce(PrevLoc), IRB.getInt32Ty()); - else -#endif - PrevLocTrans = IRB.CreateZExt(PrevLoc, IRB.getInt32Ty()); - - if (caller_str) - PrevLocTrans = - IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, PrevCaller), Int32Ty); - - /* Load SHM pointer */ - LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); - MapPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - Value *MapPtrIdx; -#ifdef AFL_HAVE_VECTOR_INTRINSICS - if (ngram_size) - MapPtrIdx = IRB.CreateGEP( - MapPtr, IRB.CreateZExt(IRB.CreateXor(PrevLocTrans, L), Int32Ty)); - else -#endif - MapPtrIdx = IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocTrans, L)); - - /* Update bitmap */ - LoadInst *Counter = IRB.CreateLoad(MapPtrIdx); - Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - - Value *Incr = IRB.CreateAdd(Counter, One); - -#if LLVM_VERSION_MAJOR < 9 - if (neverZero_counters_str != - NULL) // with llvm 9 we make this the default as the bug in llvm is - // then fixed -#else - if (!skip_nozero) -#endif - { - - /* hexcoder: Realize a counter that skips zero during overflow. - * Once this counter reaches its maximum value, it next increments to - * 1 - * - * Instead of - * Counter + 1 -> Counter - * we inject now this - * Counter + 1 -> {Counter, OverflowFlag} - * Counter + OverflowFlag -> Counter - */ - auto cf = IRB.CreateICmpEQ(Incr, Zero); - auto carry = IRB.CreateZExt(cf, Int8Ty); - Incr = IRB.CreateAdd(Incr, carry); - - } - - IRB.CreateStore(Incr, MapPtrIdx) - ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - - if (caller_str && has_calls) { - - // in CALLER mode we have to restore the original context for the - // caller - she might be calling other functions which need the - // correct CALLER - Instruction *Inst = BB.getTerminator(); - if (isa<ReturnInst>(Inst) || isa<ResumeInst>(Inst)) { - - IRBuilder<> Post_IRB(Inst); - StoreInst * RestoreCtx = - Post_IRB.CreateStore(PrevCaller, AFLContext); - RestoreCtx->setMetadata(M.getMDKindID("nosanitize"), - MDNode::get(C, None)); - - } - - } - - total_instr++; - - } - - } - - if (!be_quiet) { - - char modeline[100]; - snprintf(modeline, sizeof(modeline), "%s%s%s%s%s", - getenv("AFL_HARDEN") ? "hardened" : "non-hardened", - getenv("AFL_USE_ASAN") ? ", ASAN" : "", - getenv("AFL_USE_MSAN") ? ", MSAN" : "", - getenv("AFL_USE_CFISAN") ? ", CFISAN" : "", - getenv("AFL_USE_UBSAN") ? ", UBSAN" : ""); - - OKF("Instrumented %d locations (%llu, %llu) (%s mode)\n", total_instr, - total_rs, total_hs, modeline); - - } - - return false; - - } - -}; // end of struct InsTrim - -} // end of anonymous namespace - -char InsTrim::ID = 0; - -static void registerAFLPass(const PassManagerBuilder &, - legacy::PassManagerBase &PM) { - - PM.add(new InsTrim()); - -} - -static RegisterStandardPasses RegisterAFLPass( - PassManagerBuilder::EP_OptimizerLast, registerAFLPass); - -static RegisterStandardPasses RegisterAFLPass0( - PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass); - diff --git a/instrumentation/MarkNodes.cc b/instrumentation/MarkNodes.cc deleted file mode 100644 index b77466d9..00000000 --- a/instrumentation/MarkNodes.cc +++ /dev/null @@ -1,481 +0,0 @@ -#include <algorithm> -#include <map> -#include <queue> -#include <set> -#include <vector> - -#include "llvm/Config/llvm-config.h" -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 5 -typedef long double max_align_t; -#endif - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/IR/BasicBlock.h" -#if LLVM_VERSION_MAJOR > 3 || \ - (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) - #include "llvm/IR/CFG.h" -#else - #include "llvm/Support/CFG.h" -#endif -#include "llvm/IR/Constants.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/Module.h" -#include "llvm/Pass.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -DenseMap<BasicBlock *, uint32_t> LMap; -std::vector<BasicBlock *> Blocks; -std::set<uint32_t> Marked, Markabove; -std::vector<std::vector<uint32_t> > Succs, Preds; - -void reset() { - - LMap.clear(); - Blocks.clear(); - Marked.clear(); - Markabove.clear(); - -} - -uint32_t start_point; - -void labelEachBlock(Function *F) { - - // Fake single endpoint; - LMap[NULL] = Blocks.size(); - Blocks.push_back(NULL); - - // Assign the unique LabelID to each block; - for (auto I = F->begin(), E = F->end(); I != E; ++I) { - - BasicBlock *BB = &*I; - LMap[BB] = Blocks.size(); - Blocks.push_back(BB); - - } - - start_point = LMap[&F->getEntryBlock()]; - -} - -void buildCFG(Function *F) { - - Succs.resize(Blocks.size()); - Preds.resize(Blocks.size()); - for (size_t i = 0; i < Succs.size(); i++) { - - Succs[i].clear(); - Preds[i].clear(); - - } - - for (auto S = F->begin(), E = F->end(); S != E; ++S) { - - BasicBlock *BB = &*S; - uint32_t MyID = LMap[BB]; - - for (auto I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { - - Succs[MyID].push_back(LMap[*I]); - - } - - } - -} - -std::vector<std::vector<uint32_t> > tSuccs; -std::vector<bool> tag, indfs; - -void DFStree(size_t now_id) { - - if (tag[now_id]) return; - tag[now_id] = true; - indfs[now_id] = true; - for (auto succ : tSuccs[now_id]) { - - if (tag[succ] and indfs[succ]) { - - Marked.insert(succ); - Markabove.insert(succ); - continue; - - } - - Succs[now_id].push_back(succ); - Preds[succ].push_back(now_id); - DFStree(succ); - - } - - indfs[now_id] = false; - -} - -void turnCFGintoDAG() { - - tSuccs = Succs; - tag.resize(Blocks.size()); - indfs.resize(Blocks.size()); - for (size_t i = 0; i < Blocks.size(); ++i) { - - Succs[i].clear(); - tag[i] = false; - indfs[i] = false; - - } - - DFStree(start_point); - for (size_t i = 0; i < Blocks.size(); ++i) - if (Succs[i].empty()) { - - Succs[i].push_back(0); - Preds[0].push_back(i); - - } - -} - -uint32_t timeStamp; -namespace DominatorTree { - -std::vector<std::vector<uint32_t> > cov; -std::vector<uint32_t> dfn, nfd, par, sdom, idom, mom, mn; - -bool Compare(uint32_t u, uint32_t v) { - - return dfn[u] < dfn[v]; - -} - -uint32_t eval(uint32_t u) { - - if (mom[u] == u) return u; - uint32_t res = eval(mom[u]); - if (Compare(sdom[mn[mom[u]]], sdom[mn[u]])) { mn[u] = mn[mom[u]]; } - return mom[u] = res; - -} - -void DFS(uint32_t now) { - - timeStamp += 1; - dfn[now] = timeStamp; - nfd[timeStamp - 1] = now; - for (auto succ : Succs[now]) { - - if (dfn[succ] == 0) { - - par[succ] = now; - DFS(succ); - - } - - } - -} - -void DominatorTree() { - - if (Blocks.empty()) return; - uint32_t s = start_point; - - // Initialization - mn.resize(Blocks.size()); - cov.resize(Blocks.size()); - dfn.resize(Blocks.size()); - nfd.resize(Blocks.size()); - par.resize(Blocks.size()); - mom.resize(Blocks.size()); - sdom.resize(Blocks.size()); - idom.resize(Blocks.size()); - - for (uint32_t i = 0; i < Blocks.size(); i++) { - - dfn[i] = 0; - nfd[i] = Blocks.size(); - cov[i].clear(); - idom[i] = mom[i] = mn[i] = sdom[i] = i; - - } - - timeStamp = 0; - DFS(s); - - for (uint32_t i = Blocks.size() - 1; i >= 1u; i--) { - - uint32_t now = nfd[i]; - if (now == Blocks.size()) { continue; } - for (uint32_t pre : Preds[now]) { - - if (dfn[pre]) { - - eval(pre); - if (Compare(sdom[mn[pre]], sdom[now])) { sdom[now] = sdom[mn[pre]]; } - - } - - } - - cov[sdom[now]].push_back(now); - mom[now] = par[now]; - for (uint32_t x : cov[par[now]]) { - - eval(x); - if (Compare(sdom[mn[x]], par[now])) { - - idom[x] = mn[x]; - - } else { - - idom[x] = par[now]; - - } - - } - - } - - for (uint32_t i = 1; i < Blocks.size(); i += 1) { - - uint32_t now = nfd[i]; - if (now == Blocks.size()) { continue; } - if (idom[now] != sdom[now]) idom[now] = idom[idom[now]]; - - } - -} - -} // namespace DominatorTree - -std::vector<uint32_t> Visited, InStack; -std::vector<uint32_t> TopoOrder, InDeg; -std::vector<std::vector<uint32_t> > t_Succ, t_Pred; - -void Go(uint32_t now, uint32_t tt) { - - if (now == tt) return; - Visited[now] = InStack[now] = timeStamp; - - for (uint32_t nxt : Succs[now]) { - - if (Visited[nxt] == timeStamp and InStack[nxt] == timeStamp) { - - Marked.insert(nxt); - - } - - t_Succ[now].push_back(nxt); - t_Pred[nxt].push_back(now); - InDeg[nxt] += 1; - if (Visited[nxt] == timeStamp) { continue; } - Go(nxt, tt); - - } - - InStack[now] = 0; - -} - -void TopologicalSort(uint32_t ss, uint32_t tt) { - - timeStamp += 1; - - Go(ss, tt); - - TopoOrder.clear(); - std::queue<uint32_t> wait; - wait.push(ss); - while (not wait.empty()) { - - uint32_t now = wait.front(); - wait.pop(); - TopoOrder.push_back(now); - for (uint32_t nxt : t_Succ[now]) { - - InDeg[nxt] -= 1; - if (InDeg[nxt] == 0u) { wait.push(nxt); } - - } - - } - -} - -std::vector<std::set<uint32_t> > NextMarked; -bool Indistinguish(uint32_t node1, uint32_t node2) { - - if (NextMarked[node1].size() > NextMarked[node2].size()) { - - uint32_t _swap = node1; - node1 = node2; - node2 = _swap; - - } - - for (uint32_t x : NextMarked[node1]) { - - if (NextMarked[node2].find(x) != NextMarked[node2].end()) { return true; } - - } - - return false; - -} - -void MakeUniq(uint32_t now) { - - if (Marked.find(now) == Marked.end()) { - - for (uint32_t pred1 : t_Pred[now]) { - - bool StopFlag = false; - for (uint32_t pred2 : t_Pred[now]) { - - if (pred1 == pred2) continue; - if (Indistinguish(pred1, pred2)) { - - Marked.insert(now); - StopFlag = true; - break; - - } - - } - - if (StopFlag) { break; } - - } - - } - - if (Marked.find(now) != Marked.end()) { - - NextMarked[now].insert(now); - - } else { - - for (uint32_t pred : t_Pred[now]) { - - for (uint32_t x : NextMarked[pred]) { - - NextMarked[now].insert(x); - - } - - } - - } - -} - -bool MarkSubGraph(uint32_t ss, uint32_t tt) { - - TopologicalSort(ss, tt); - if (TopoOrder.empty()) return false; - - for (uint32_t i : TopoOrder) { - - NextMarked[i].clear(); - - } - - NextMarked[TopoOrder[0]].insert(TopoOrder[0]); - for (uint32_t i = 1; i < TopoOrder.size(); i += 1) { - - MakeUniq(TopoOrder[i]); - - } - - // Check if there is an empty path. - if (NextMarked[tt].count(TopoOrder[0]) > 0) return true; - return false; - -} - -void MarkVertice() { - - uint32_t s = start_point; - - InDeg.resize(Blocks.size()); - Visited.resize(Blocks.size()); - InStack.resize(Blocks.size()); - t_Succ.resize(Blocks.size()); - t_Pred.resize(Blocks.size()); - NextMarked.resize(Blocks.size()); - - for (uint32_t i = 0; i < Blocks.size(); i += 1) { - - Visited[i] = InStack[i] = InDeg[i] = 0; - t_Succ[i].clear(); - t_Pred[i].clear(); - - } - - timeStamp = 0; - uint32_t t = 0; - bool emptyPathExists = true; - - while (s != t) { - - emptyPathExists &= MarkSubGraph(DominatorTree::idom[t], t); - 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()); - - } - -} - -// return {marked nodes} -std::pair<std::vector<BasicBlock *>, std::vector<BasicBlock *> > markNodes( - Function *F) { - - assert(F->size() > 0 && "Function can not be empty"); - - reset(); - labelEachBlock(F); - buildCFG(F); - turnCFGintoDAG(); - DominatorTree::DominatorTree(); - MarkVertice(); - - std::vector<BasicBlock *> Result, ResultAbove; - for (uint32_t x : Markabove) { - - auto it = Marked.find(x); - if (it != Marked.end()) Marked.erase(it); - if (x) ResultAbove.push_back(Blocks[x]); - - } - - for (uint32_t x : Marked) { - - if (x == 0) { - - continue; - - } else { - - Result.push_back(Blocks[x]); - - } - - } - - return {Result, ResultAbove}; - -} - diff --git a/instrumentation/MarkNodes.h b/instrumentation/MarkNodes.h deleted file mode 100644 index 8ddc978d..00000000 --- a/instrumentation/MarkNodes.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __MARK_NODES__ -#define __MARK_NODES__ - -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/Function.h" -#include <vector> - -std::pair<std::vector<llvm::BasicBlock *>, std::vector<llvm::BasicBlock *>> -markNodes(llvm::Function *F); - -#endif - diff --git a/instrumentation/README.instrim.md b/instrumentation/README.instrim.md deleted file mode 100644 index 99f6477a..00000000 --- a/instrumentation/README.instrim.md +++ /dev/null @@ -1,30 +0,0 @@ -# InsTrim - -InsTrim: Lightweight Instrumentation for Coverage-guided Fuzzing - -## Introduction - -InsTrim is the work of Chin-Chia Hsu, Che-Yu Wu, Hsu-Chun Hsiao and Shih-Kun Huang. - -It uses a CFG (call flow graph) and markers to instrument just what -is necessary in the binary (ie less than llvm_mode). As a result the binary is -about 10-15% faster compared to normal llvm_mode however with some coverage loss. -It requires at least llvm version 3.8.0 to build. -If you have LLVM 7+ we recommend PCGUARD instead. - -## Usage - -Set the environment variable `AFL_LLVM_INSTRUMENT=CFG` or `AFL_LLVM_INSTRIM=1` -during compilation of the target. - -There is also special mode which instruments loops in a way so that -afl-fuzz can see which loop path has been selected but not being able to -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`. - -## Background - -The paper from Chin-Chia Hsu, Che-Yu Wu, Hsu-Chun Hsiao and Shih-Kun Huang: -[InsTrim: Lightweight Instrumentation for Coverage-guided Fuzzing] -(https://www.ndss-symposium.org/wp-content/uploads/2018/07/bar2018_14_Hsu_paper.pdf) diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md index 2705ce0d..adce6c1d 100644 --- a/instrumentation/README.llvm.md +++ b/instrumentation/README.llvm.md @@ -101,8 +101,7 @@ instrumentation by either setting `AFL_CC_COMPILER=LLVM` or pass the parameter The tool honors roughly the same environmental variables as afl-gcc (see [docs/env_variables.md](../docs/env_variables.md)). This includes AFL_USE_ASAN, AFL_HARDEN, and AFL_DONT_OPTIMIZE. However AFL_INST_RATIO is not honored -as it does not serve a good purpose with the more effective PCGUARD, LTO and - instrim CFG analysis. +as it does not serve a good purpose with the more effective PCGUARD analysis. ## 3) Options @@ -116,26 +115,20 @@ For splitting memcmp, strncmp, etc. please see [README.laf-intel.md](README.laf- Then there are different ways of instrumenting the target: -1. There is an optimized instrumentation strategy that uses CFGs and -markers to just instrument what is needed. This increases speed by 10-15% -without any disadvantages -If you want to use this, set AFL_LLVM_INSTRUMENT=CFG or AFL_LLVM_INSTRIM=1 -See [README.instrim.md](README.instrim.md) - -2. An even better instrumentation strategy uses LTO and link time +1. An better instrumentation strategy uses LTO and link time instrumentation. Note that not all targets can compile in this mode, however if it works it is the best option you can use. Simply use afl-clang-lto/afl-clang-lto++ to use this option. See [README.lto.md](README.lto.md) -3. Alternativly you can choose a completely different coverage method: +2. Alternativly you can choose a completely different coverage method: -3a. N-GRAM coverage - which combines the previous visited edges with the +2a. N-GRAM coverage - which combines the previous visited edges with the current one. This explodes the map but on the other hand has proven to be effective for fuzzing. See [README.ngram.md](README.ngram.md) -3b. Context sensitive coverage - which combines the visited edges with an +2b. Context sensitive coverage - which combines the visited edges with an individual caller ID (the function that called the current one) [README.ctx.md](README.ctx.md) diff --git a/instrumentation/README.snapshot.md b/instrumentation/README.snapshot.md index c40a956a..c794c2fd 100644 --- a/instrumentation/README.snapshot.md +++ b/instrumentation/README.snapshot.md @@ -1,5 +1,7 @@ # AFL++ snapshot feature +**NOTE:** the snapshot lkm is currently not supported and needs a maintainer :-) + Snapshotting is a feature that makes a snapshot from a process and then restores its state, which is faster then forking it again. diff --git a/src/afl-cc.c b/src/afl-cc.c index 80fc0742..d134f013 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -66,7 +66,6 @@ enum { INSTRUMENT_CLASSIC = 1, INSTRUMENT_AFL = 1, INSTRUMENT_PCGUARD = 2, - INSTRUMENT_INSTRIM = 3, INSTRUMENT_CFG = 3, INSTRUMENT_LTO = 4, INSTRUMENT_LLVMNATIVE = 5, @@ -639,10 +638,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; - if (instrument_mode == INSTRUMENT_CFG) - cc_params[cc_par_cnt++] = - alloc_printf("%s/libLLVMInsTrim.so", obj_path); - else cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); @@ -1252,8 +1247,7 @@ int main(int argc, char **argv, char **envp) { strcasecmp(ptr, "CFG") == 0) { - compiler_mode = LLVM; - instrument_mode = INSTRUMENT_CFG; + FATAL("InsTrim instrumentation was removed. Use a modern LLVM and PCGUARD (default in afl-cc).\n"); } else if (strcasecmp(ptr, "AFL") == 0 || @@ -1319,10 +1313,7 @@ int main(int argc, char **argv, char **envp) { if (getenv("AFL_LLVM_INSTRIM") || getenv("INSTRIM") || getenv("INSTRIM_LIB")) { - if (instrument_mode == 0) - instrument_mode = INSTRUMENT_CFG; - else if (instrument_mode != INSTRUMENT_CFG) - FATAL("you cannot set AFL_LLVM_INSTRUMENT and AFL_LLVM_INSTRIM together"); + FATAL("InsTrim instrumentation was removed. Use a modern LLVM and PCGUARD (default in afl-cc).\n"); } @@ -1409,17 +1400,7 @@ int main(int argc, char **argv, char **envp) { if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 || strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) { - if (instrument_mode == INSTRUMENT_LTO) { - - instrument_mode = INSTRUMENT_CFG; - lto_mode = 1; - - } else if (!instrument_mode || instrument_mode == INSTRUMENT_CFG) - - instrument_mode = INSTRUMENT_CFG; - else - FATAL("main instrumentation mode already set with %s", - instrument_mode_string[instrument_mode]); + FATAL("InsTrim instrumentation was removed. Use a modern LLVM and PCGUARD (default in afl-cc).\n"); } @@ -1428,7 +1409,7 @@ int main(int argc, char **argv, char **envp) { lto_mode = 1; if (!instrument_mode || instrument_mode == INSTRUMENT_LTO) instrument_mode = INSTRUMENT_LTO; - else if (instrument_mode != INSTRUMENT_CFG) + else FATAL("main instrumentation mode already set with %s", instrument_mode_string[instrument_mode]); @@ -1642,11 +1623,6 @@ int main(int argc, char **argv, char **envp) { " - CALLER\n" " - CTX\n" " - NGRAM-{2-16}\n" - " INSTRIM no yes module yes yes " - " yes\n" - " - NORMAL\n" - " - CALLER\n" - " - NGRAM-{2-16}\n" " [GCC_PLUGIN] gcc plugin: %s%s\n" " CLASSIC DEFAULT no yes no no no " "yes\n" @@ -1697,9 +1673,7 @@ int main(int argc, char **argv, char **envp) { " CTX: CLASSIC + full callee context " "(instrumentation/README.ctx.md)\n" " NGRAM-x: CLASSIC + previous path " - "((instrumentation/README.ngram.md)\n" - " INSTRIM: Dominator tree (for LLVM <= 6.0) " - "(instrumentation/README.instrim.md)\n\n"); + "((instrumentation/README.ngram.md)\n\n"); #undef NATIVE_MSG @@ -1791,19 +1765,15 @@ int main(int argc, char **argv, char **envp) { " AFL_LLVM_CMPLOG: log operands of comparisons (RedQueen " "mutator)\n" " AFL_LLVM_INSTRUMENT: set instrumentation mode:\n" - " CLASSIC, INSTRIM, PCGUARD, LTO, GCC, CLANG, CALLER, CTX, " - "NGRAM-2 ..-16\n" + " CLASSIC, PCGUARD, LTO, GCC, CLANG, CALLER, CTX, NGRAM-2 ..-16\n" " You can also use the old environment variables instead:\n" " AFL_LLVM_USE_TRACE_PC: use LLVM trace-pc-guard instrumentation\n" - " AFL_LLVM_INSTRIM: use light weight instrumentation InsTrim\n" - " AFL_LLVM_INSTRIM_LOOPHEAD: optimize loop tracing for speed " - "(option to INSTRIM)\n" " AFL_LLVM_CALLER: use single context sensitive coverage (for " "CLASSIC)\n" " AFL_LLVM_CTX: use full context sensitive coverage (for " "CLASSIC)\n" " AFL_LLVM_NGRAM_SIZE: use ngram prev_loc count coverage (for " - "CLASSIC & INSTRIM)\n"); + "CLASSIC)\n"); #ifdef AFL_CLANG_FLTO if (have_lto) @@ -1951,11 +1921,7 @@ int main(int argc, char **argv, char **envp) { "(requires LLVM 11 or higher)"); #endif - if (instrument_opt_mode && instrument_mode == INSTRUMENT_CFG && - instrument_opt_mode & INSTRUMENT_OPT_CTX) - FATAL("CFG instrumentation mode supports NGRAM and CALLER, but not CTX."); - else if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC) - // we will drop CFG/INSTRIM in the future so do not advertise + if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC) FATAL( "CALLER, CTX and NGRAM instrumentation options can only be used with " "the LLVM CLASSIC instrumentation mode."); diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 0a978653..8928ddc9 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -73,8 +73,7 @@ static u32 ld_param_cnt = 1; /* Number of params to 'ld' */ so we exploit this property to keep the code "simple". */ static void edit_params(int argc, char **argv) { - u32 i, instrim = 0, gold_pos = 0, gold_present = 0, rt_present = 0, - rt_lto_present = 0, inst_present = 0; + u32 i, gold_pos = 0, gold_present = 0, rt_present = 0, rt_lto_present = 0, inst_present = 0; char *ptr; ld_params = ck_alloc(4096 * sizeof(u8 *)); @@ -186,17 +185,16 @@ static void edit_params(int argc, char **argv) { } - if (getenv("AFL_LLVM_INSTRIM")) - instrim = 1; - else if ((ptr = getenv("AFL_LLVM_INSTRUMENT")) && - (strcasestr(ptr, "CFG") == 0 || strcasestr(ptr, "INSTRIM") == 0)) - instrim = 1; + if (getenv("AFL_LLVM_INSTRIM") || + ((ptr = getenv("AFL_LLVM_INSTRUMENT")) && + (strcasestr(ptr, "CFG") == 0 || strcasestr(ptr, "INSTRIM") == 0))) + FATAL("InsTrim was removed because it is not effective. Use a modern LLVM and PCGUARD (which is the default in afl-cc).\n"); if (debug) DEBUGF( - "passthrough=%s instrim=%u, gold_pos=%u, gold_present=%s " + "passthrough=%s, gold_pos=%u, gold_present=%s " "inst_present=%s rt_present=%s rt_lto_present=%s\n", - passthrough ? "true" : "false", instrim, gold_pos, + passthrough ? "true" : "false", gold_pos, gold_present ? "true" : "false", inst_present ? "true" : "false", rt_present ? "true" : "false", rt_lto_present ? "true" : "false"); @@ -230,10 +228,6 @@ static void edit_params(int argc, char **argv) { if (!inst_present) { - if (instrim) - ld_params[ld_param_cnt++] = - alloc_printf("-mllvm=-load=%s/afl-llvm-lto-instrim.so", afl_path); - else ld_params[ld_param_cnt++] = alloc_printf( "-mllvm=-load=%s/afl-llvm-lto-instrumentation.so", afl_path); diff --git a/test/test-llvm.sh b/test/test-llvm.sh index 3ef36b37..eae76643 100755 --- a/test/test-llvm.sh +++ b/test/test-llvm.sh @@ -166,27 +166,6 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { } rm -f test-instr.plain - # now for the special llvm_mode things - test -e ../libLLVMInsTrim.so && { - AFL_LLVM_INSTRUMENT=CFG AFL_LLVM_INSTRIM_LOOPHEAD=1 ../afl-clang-fast -o test-instr.instrim ../test-instr.c > /dev/null 2>test.out - test -e test-instr.instrim && { - TUPLES=`echo 0|AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-instr.instrim 2>&1 | grep Captur | awk '{print$3}'` - test "$TUPLES" -gt 1 -a "$TUPLES" -lt 5 && { - $ECHO "$GREEN[+] llvm_mode InsTrim reported $TUPLES instrumented locations which is fine" - } || { - $ECHO "$RED[!] llvm_mode InsTrim instrumentation produces weird numbers: $TUPLES" - CODE=1 - } - rm -f test-instr.instrim test.out - } || { - cat test.out - $ECHO "$RED[!] llvm_mode InsTrim compilation failed" - CODE=1 - } - } || { - $ECHO "$YELLOW[-] llvm_mode InsTrim not compiled, cannot test" - INCOMPLETE=1 - } AFL_LLVM_INSTRUMENT=AFL AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_SWITCHES=1 AFL_LLVM_LAF_TRANSFORM_COMPARES=1 AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -o test-compcov.compcov test-compcov.c > test.out 2>&1 test -e test-compcov.compcov && test_compcov_binary_functionality ./test-compcov.compcov && { grep --binary-files=text -Eq " [ 123][0-9][0-9] location| [3-9][0-9] location" test.out && { |