diff options
Diffstat (limited to 'llvm_mode/afl-llvm-pass.so.cc')
-rw-r--r-- | llvm_mode/afl-llvm-pass.so.cc | 294 |
1 files changed, 173 insertions, 121 deletions
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc index b242163e..5d531a87 100644 --- a/llvm_mode/afl-llvm-pass.so.cc +++ b/llvm_mode/afl-llvm-pass.so.cc @@ -48,50 +48,52 @@ using namespace llvm; namespace { - class AFLCoverage : public ModulePass { - - public: - - static char ID; - AFLCoverage() : ModulePass(ID) { - char* instWhiteListFilename = getenv("AFL_LLVM_WHITELIST"); - if (instWhiteListFilename) { - std::string line; - std::ifstream fileStream; - fileStream.open(instWhiteListFilename); - if (!fileStream) - report_fatal_error("Unable to open AFL_LLVM_WHITELIST"); - getline(fileStream, line); - while (fileStream) { - myWhitelist.push_back(line); - getline(fileStream, line); - } - } +class AFLCoverage : public ModulePass { + + public: + static char ID; + AFLCoverage() : ModulePass(ID) { + + char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST"); + if (instWhiteListFilename) { + + std::string line; + std::ifstream fileStream; + fileStream.open(instWhiteListFilename); + if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST"); + getline(fileStream, line); + while (fileStream) { + + myWhitelist.push_back(line); + getline(fileStream, line); + } - bool runOnModule(Module &M) override; + } - // StringRef getPassName() const override { - // return "American Fuzzy Lop Instrumentation"; - // } + } - protected: + bool runOnModule(Module &M) override; - std::list<std::string> myWhitelist; + // StringRef getPassName() const override { - }; + // return "American Fuzzy Lop Instrumentation"; + // } -} + protected: + std::list<std::string> myWhitelist; +}; -char AFLCoverage::ID = 0; +} // namespace +char AFLCoverage::ID = 0; bool AFLCoverage::runOnModule(Module &M) { LLVMContext &C = M.getContext(); - IntegerType *Int8Ty = IntegerType::getInt8Ty(C); + IntegerType *Int8Ty = IntegerType::getInt8Ty(C); IntegerType *Int32Ty = IntegerType::getInt32Ty(C); unsigned int cur_loc = 0; @@ -103,11 +105,13 @@ bool AFLCoverage::runOnModule(Module &M) { SAYF(cCYA "afl-llvm-pass" VERSION cRST " by <lszekeres@google.com>\n"); - } else be_quiet = 1; + } else + + be_quiet = 1; /* Decide instrumentation ratio */ - char* inst_ratio_str = getenv("AFL_INST_RATIO"); + char * inst_ratio_str = getenv("AFL_INST_RATIO"); unsigned int inst_ratio = 100; if (inst_ratio_str) { @@ -119,7 +123,7 @@ bool AFLCoverage::runOnModule(Module &M) { } #if LLVM_VERSION_MAJOR < 9 - char* neverZero_counters_str = getenv("AFL_LLVM_NOT_ZERO"); + char *neverZero_counters_str = getenv("AFL_LLVM_NOT_ZERO"); #endif /* Get globals for the SHM region and the previous location. Note that @@ -134,8 +138,8 @@ bool AFLCoverage::runOnModule(Module &M) { M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc"); #else GlobalVariable *AFLPrevLoc = new GlobalVariable( - M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc", - 0, GlobalVariable::GeneralDynamicTLSModel, 0, false); + M, Int32Ty, false, GlobalValue::ExternalLinkage, 0, "__afl_prev_loc", 0, + GlobalVariable::GeneralDynamicTLSModel, 0, false); #endif /* Instrument all the things! */ @@ -146,58 +150,77 @@ bool AFLCoverage::runOnModule(Module &M) { for (auto &BB : F) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); - IRBuilder<> IRB(&(*IP)); - + IRBuilder<> IRB(&(*IP)); + if (!myWhitelist.empty()) { - bool instrumentBlock = false; - - /* Get the current location using debug information. - * For now, just instrument the block if we are not able - * to determine our location. */ - DebugLoc Loc = IP->getDebugLoc(); - if ( Loc ) { - DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode()); - - unsigned int instLine = cDILoc->getLine(); - StringRef instFilename = cDILoc->getFilename(); - - if (instFilename.str().empty()) { - /* If the original location is empty, try using the inlined location */ - DILocation *oDILoc = cDILoc->getInlinedAt(); - if (oDILoc) { - instFilename = oDILoc->getFilename(); - instLine = oDILoc->getLine(); - } - } - /* Continue only if we know where we actually are */ - if (!instFilename.str().empty()) { - for (std::list<std::string>::iterator it = myWhitelist.begin(); it != myWhitelist.end(); ++it) { - /* We don't check for filename equality here because - * filenames might actually be full paths. Instead we - * check that the actual filename ends in the filename - * specified in the list. */ - if (instFilename.str().length() >= it->length()) { - if (instFilename.str().compare(instFilename.str().length() - it->length(), it->length(), *it) == 0) { - instrumentBlock = true; - break; - } - } - } + bool instrumentBlock = false; + + /* Get the current location using debug information. + * For now, just instrument the block if we are not able + * to determine our location. */ + DebugLoc Loc = IP->getDebugLoc(); + if (Loc) { + + DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode()); + + unsigned int instLine = cDILoc->getLine(); + StringRef instFilename = cDILoc->getFilename(); + + if (instFilename.str().empty()) { + + /* If the original location is empty, try using the inlined location + */ + DILocation *oDILoc = cDILoc->getInlinedAt(); + if (oDILoc) { + + instFilename = oDILoc->getFilename(); + instLine = oDILoc->getLine(); + + } + + } + + /* Continue only if we know where we actually are */ + if (!instFilename.str().empty()) { + + for (std::list<std::string>::iterator it = myWhitelist.begin(); + it != myWhitelist.end(); ++it) { + + /* We don't check for filename equality here because + * filenames might actually be full paths. Instead we + * check that the actual filename ends in the filename + * specified in the list. */ + if (instFilename.str().length() >= it->length()) { + + if (instFilename.str().compare( + instFilename.str().length() - it->length(), + it->length(), *it) == 0) { + + instrumentBlock = true; + break; + + } + } + + } + } - /* Either we couldn't figure out our location or the location is - * not whitelisted, so we skip instrumentation. */ - if (!instrumentBlock) continue; - } + } + + /* Either we couldn't figure out our location or the location is + * not whitelisted, so we skip instrumentation. */ + if (!instrumentBlock) continue; + } if (AFL_R(100) >= inst_ratio) continue; /* Make up cur_loc */ - //cur_loc++; + // cur_loc++; cur_loc = AFL_R(MAP_SIZE); // only instrument if this basic block is the destination of a previous @@ -205,24 +228,27 @@ bool AFLCoverage::runOnModule(Module &M) { // this gets rid of ~5-10% of instrumentations that are unnecessary // result: a little more speed and less map pollution int more_than_one = -1; - //fprintf(stderr, "BB %u: ", cur_loc); + // fprintf(stderr, "BB %u: ", cur_loc); for (BasicBlock *Pred : predecessors(&BB)) { + int count = 0; - if (more_than_one == -1) - more_than_one = 0; - //fprintf(stderr, " %p=>", Pred); + if (more_than_one == -1) more_than_one = 0; + // fprintf(stderr, " %p=>", Pred); for (BasicBlock *Succ : successors(Pred)) { - //if (count > 0) + + // if (count > 0) // fprintf(stderr, "|"); if (Succ != NULL) count++; - //fprintf(stderr, "%p", Succ); + // fprintf(stderr, "%p", Succ); + } - if (count > 1) - more_than_one = 1; + + if (count > 1) more_than_one = 1; + } - //fprintf(stderr, " == %d\n", more_than_one); - if (more_than_one != 1) - continue; + + // fprintf(stderr, " == %d\n", more_than_one); + if (more_than_one != 1) continue; ConstantInt *CurLoc = ConstantInt::get(Int32Ty, cur_loc); @@ -236,7 +262,8 @@ bool AFLCoverage::runOnModule(Module &M) { LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr); MapPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - Value *MapPtrIdx = IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc)); + Value *MapPtrIdx = + IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc)); /* Update bitmap */ @@ -246,7 +273,9 @@ bool AFLCoverage::runOnModule(Module &M) { Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1)); #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 + if (neverZero_counters_str != + NULL) { // with llvm 9 we make this the default as the bug in llvm is + // then fixed #endif /* hexcoder: Realize a counter that skips zero during overflow. * Once this counter reaches its maximum value, it next increments to 1 @@ -257,48 +286,67 @@ bool AFLCoverage::runOnModule(Module &M) { * Counter + 1 -> {Counter, OverflowFlag} * Counter + OverflowFlag -> Counter */ -/* // we keep the old solutions just in case - // Solution #1 - if (neverZero_counters_str[0] == '1') { - CallInst *AddOv = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter, ConstantInt::get(Int8Ty, 1)); - AddOv->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); - Value *SumWithOverflowBit = AddOv; - Incr = IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0), // sum - IRB.CreateZExt( // convert from one bit type to 8 bits type - IRB.CreateExtractValue(SumWithOverflowBit, 1), // overflow - Int8Ty)); - // Solution #2 - } else if (neverZero_counters_str[0] == '2') { - auto cf = IRB.CreateICmpEQ(Counter, ConstantInt::get(Int8Ty, 255)); - Value *HowMuch = IRB.CreateAdd(ConstantInt::get(Int8Ty, 1), cf); - Incr = IRB.CreateAdd(Counter, HowMuch); - // Solution #3 - } else if (neverZero_counters_str[0] == '3') { -*/ - // this is the solution we choose because llvm9 should do the right thing here - auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0)); - auto carry = IRB.CreateZExt(cf, Int8Ty); - Incr = IRB.CreateAdd(Incr, carry); + /* // we keep the old solutions just in case + // Solution #1 + if (neverZero_counters_str[0] == '1') { + + CallInst *AddOv = + IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter, + ConstantInt::get(Int8Ty, 1)); + AddOv->setMetadata(M.getMDKindID("nosanitize"), + MDNode::get(C, None)); Value *SumWithOverflowBit = AddOv; Incr = + IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0), // sum + IRB.CreateZExt( // convert from one bit + type to 8 bits type IRB.CreateExtractValue(SumWithOverflowBit, 1), // + overflow Int8Ty)); + // Solution #2 + + } else if (neverZero_counters_str[0] == '2') { + + auto cf = IRB.CreateICmpEQ(Counter, + ConstantInt::get(Int8Ty, 255)); Value *HowMuch = + IRB.CreateAdd(ConstantInt::get(Int8Ty, 1), cf); Incr = + IRB.CreateAdd(Counter, HowMuch); + // Solution #3 + + } else if (neverZero_counters_str[0] == '3') { + + */ + // this is the solution we choose because llvm9 should do the right + // thing here + auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0)); + auto carry = IRB.CreateZExt(cf, Int8Ty); + Incr = IRB.CreateAdd(Incr, carry); /* // Solution #4 + } else if (neverZero_counters_str[0] == '4') { + auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1)); auto carry = IRB.CreateZExt(cf, Int8Ty); Incr = IRB.CreateAdd(Incr, carry); + } else { - fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s (valid is 1-4)\n", neverZero_counters_str); - exit(-1); + + fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s + (valid is 1-4)\n", neverZero_counters_str); exit(-1); + } + */ #if LLVM_VERSION_MAJOR < 9 + } + #endif - IRB.CreateStore(Incr, MapPtrIdx)->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); + IRB.CreateStore(Incr, MapPtrIdx) + ->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); /* Set prev_loc to cur_loc >> 1 */ - StoreInst *Store = IRB.CreateStore(ConstantInt::get(Int32Ty, cur_loc >> 1), AFLPrevLoc); + StoreInst *Store = + IRB.CreateStore(ConstantInt::get(Int32Ty, cur_loc >> 1), AFLPrevLoc); Store->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None)); inst_blocks++; @@ -309,11 +357,16 @@ bool AFLCoverage::runOnModule(Module &M) { if (!be_quiet) { - if (!inst_blocks) WARNF("No instrumentation targets found."); - else OKF("Instrumented %u locations (%s mode, ratio %u%%).", - inst_blocks, getenv("AFL_HARDEN") ? "hardened" : - ((getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) ? - "ASAN/MSAN" : "non-hardened"), inst_ratio); + if (!inst_blocks) + WARNF("No instrumentation targets found."); + else + OKF("Instrumented %u locations (%s mode, ratio %u%%).", inst_blocks, + getenv("AFL_HARDEN") + ? "hardened" + : ((getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) + ? "ASAN/MSAN" + : "non-hardened"), + inst_ratio); } @@ -321,7 +374,6 @@ bool AFLCoverage::runOnModule(Module &M) { } - static void registerAFLPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -329,9 +381,9 @@ static void registerAFLPass(const PassManagerBuilder &, } - static RegisterStandardPasses RegisterAFLPass( PassManagerBuilder::EP_OptimizerLast, registerAFLPass); static RegisterStandardPasses RegisterAFLPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass); + |