From 92db44363543b510b7737d51ea2b9a4e790bfb07 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 20 Feb 2022 19:51:43 +0100 Subject: Revert "remove new llvm pass manager :(" This reverts commit 55ed2a443c5c61baba37415d4087164454d8a2a8. --- src/afl-cc.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index ed57ca1e..8fe0d35d 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -462,11 +462,17 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { +#if LLVM_MAJOR >= 11 /* use new pass manager */ + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/split-switches-pass.so", obj_path); +#endif } @@ -482,11 +488,17 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { +#if LLVM_MAJOR >= 11 /* use new pass manager */ + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = alloc_printf( + "-fpass-plugin=%s/compare-transform-pass.so", obj_path); +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/compare-transform-pass.so", obj_path); +#endif } @@ -502,11 +514,18 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { +#if LLVM_MAJOR >= 11 + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path); +// cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/split-compares-pass.so", obj_path); +#endif } @@ -536,11 +555,17 @@ static void edit_params(u32 argc, char **argv, char **envp) { alloc_printf("%s/cmplog-switches-pass.so", obj_path); // reuse split switches from laf +#if LLVM_MAJOR >= 11 + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/split-switches-pass.so", obj_path); +#endif } @@ -548,10 +573,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#if LLVM_MAJOR >= 13 - // fuck you llvm 13 - cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; -#endif if (lto_mode && !have_c) { @@ -601,6 +622,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { + cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; @@ -633,10 +655,16 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { +#if LLVM_MAJOR >= 11 + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path); +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); +#endif } @@ -653,11 +681,17 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { +#if LLVM_MAJOR >= 11 + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path); +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/cmplog-instructions-pass.so", obj_path); +#endif cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; -- cgit 1.4.1 From 914eb79cbc14b26b51172a7b14c2a5a3a0ed2875 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 21 Feb 2022 10:32:43 +0100 Subject: todo list --- TODO_LLVM | 10 ++++++++++ src/afl-cc.c | 3 --- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 TODO_LLVM (limited to 'src') diff --git a/TODO_LLVM b/TODO_LLVM new file mode 100644 index 00000000..3dea8cca --- /dev/null +++ b/TODO_LLVM @@ -0,0 +1,10 @@ +with LLVM 14: only new pass manager +up to LLVM 13: only old pass manager + +These do not work yet with the new pass manager: +cmplog-instructions-pass.so +compare-transform-pass.so +afl-llvm-dict2file.so +afl-llvm-lto-instrumentlist.so +SanitizerCoverageLTO.so +SanitizerCoveragePCGUARD.so diff --git a/src/afl-cc.c b/src/afl-cc.c index 8fe0d35d..09aa5e35 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -515,10 +515,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { #if LLVM_MAJOR >= 11 - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path); -// cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; #else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; @@ -622,7 +620,6 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { - cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; -- cgit 1.4.1 From 05119990b6075aaf8f16a385a763651f68b8b1ef Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 22 Feb 2022 10:54:51 +0100 Subject: LLVM 14 fixes --- instrumentation/SanitizerCoverageLTO.so.cc | 5 +++-- instrumentation/SanitizerCoveragePCGUARD.so.cc | 1 + instrumentation/afl-llvm-dict2file.so.cc | 4 ++-- instrumentation/afl-llvm-lto-instrumentlist.so.cc | 1 + instrumentation/afl-llvm-pass.so.cc | 1 + instrumentation/compare-transform-pass.so.cc | 4 ++-- src/afl-cc.c | 4 ++-- 7 files changed, 12 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 6a4a071f..1bdc5376 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -17,6 +17,7 @@ #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ValueTracking.h" @@ -757,7 +758,7 @@ bool ModuleSanitizerCoverage::instrumentModule( if (!HasStr2) { auto *Ptr = dyn_cast(Str2P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast(Ptr->getOperand(0))) { @@ -838,7 +839,7 @@ bool ModuleSanitizerCoverage::instrumentModule( auto Ptr = dyn_cast(Str1P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast(Ptr->getOperand(0))) { diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index e4ffeb50..48bb5a2c 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -13,6 +13,7 @@ #include "llvm/Transforms/Instrumentation/SanitizerCoverage.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/IR/CFG.h" diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 39124660..94dc6984 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -435,7 +435,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { if (!HasStr2) { auto *Ptr = dyn_cast(Str2P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast(Ptr->getOperand(0))) { @@ -519,7 +519,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { auto Ptr = dyn_cast(Str1P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast(Ptr->getOperand(0))) { diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc index 35ba9c5a..2ddbc725 100644 --- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc @@ -43,6 +43,7 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" +#include "llvm/Pass.h" #include "llvm/Support/Debug.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/IR/CFG.h" diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index 5246ba08..6419cd1d 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -45,6 +45,7 @@ typedef long double max_align_t; #endif #include "llvm/IR/IRBuilder.h" +#include "llvm/Pass.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Module.h" diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index c3a4ee34..1e250d7a 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -246,7 +246,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (!(HasStr1 || HasStr2)) { auto *Ptr = dyn_cast(Str2P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast(Ptr->getOperand(0))) { @@ -271,7 +271,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, if (!HasStr2) { Ptr = dyn_cast(Str1P); - if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { + if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) { if (auto *Var = dyn_cast(Ptr->getOperand(0))) { diff --git a/src/afl-cc.c b/src/afl-cc.c index ed57ca1e..bacd9de9 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -549,8 +549,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { } #if LLVM_MAJOR >= 13 - // fuck you llvm 13 - cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; + // Use the old pass manager in LLVM 14 which the afl++ passes still use. + cc_params[cc_par_cnt++] = "-flegacy-pass-manager"; #endif if (lto_mode && !have_c) { -- cgit 1.4.1 From f70760896c7a5d5f2b286d9ea71c8b6d90e98625 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Mar 2022 19:21:31 +0100 Subject: Revert "Merge branch 'newpm2' into dev" This reverts commit fee1acf7e6096533f1aa8cd74035bed21c90fdf6, reversing changes made to 675d17d737ee5dee88766d9c181567771592c94c. --- instrumentation/afl-llvm-dict2file.so.cc | 11 +-- instrumentation/afl-llvm-pass.so.cc | 91 +----------------- instrumentation/cmplog-instructions-pass.cc | 37 +------- instrumentation/compare-transform-pass.so.cc | 105 ++------------------- instrumentation/split-compares-pass.so.cc | 132 +++------------------------ instrumentation/split-switches-pass.so.cc | 107 ++-------------------- src/afl-cc.c | 39 +------- 7 files changed, 41 insertions(+), 481 deletions(-) (limited to 'src') diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index a554c40e..94dc6984 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -589,6 +589,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { if (optLen < 2) { continue; } if (literalLength + 1 == optLen) { // add null byte + thestring.append("\0", 1); } @@ -611,17 +612,11 @@ bool AFLdict2filePass::runOnModule(Module &M) { } */ - - if (!isStdString) { + if (!isStdString && thestring.find('\0', 0) != std::string::npos) { // ensure we do not have garbage size_t offset = thestring.find('\0', 0); - if (offset && offset < optLen && offset + 1 < optLen) { - - optLen = offset + 1; - - } - + if (offset + 1 < optLen) optLen = offset + 1; thestring = thestring.substr(0, optLen); } diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index be8099bb..6419cd1d 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -46,21 +46,12 @@ typedef long double max_align_t; #include "llvm/IR/IRBuilder.h" #include "llvm/Pass.h" -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - #include "llvm/Passes/PassPlugin.h" - #include "llvm/Passes/PassBuilder.h" - #include "llvm/IR/PassManager.h" -#else - #include "llvm/IR/LegacyPassManager.h" - #include "llvm/Transforms/IPO/PassManagerBuilder.h" -#endif +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" -#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ - #include "llvm/Passes/OptimizationLevel.h" -#endif +#include "llvm/Transforms/IPO/PassManagerBuilder.h" #if LLVM_VERSION_MAJOR >= 4 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) @@ -78,30 +69,17 @@ using namespace llvm; namespace { -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ -class AFLCoverage : public PassInfoMixin { - - public: - AFLCoverage() { - -#else class AFLCoverage : public ModulePass { public: static char ID; AFLCoverage() : ModulePass(ID) { -#endif - initInstrumentList(); } -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); -#else bool runOnModule(Module &M) override; -#endif protected: uint32_t ngram_size = 0; @@ -115,55 +93,7 @@ class AFLCoverage : public ModulePass { } // namespace -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ -extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK -llvmGetPassPluginInfo() { - - return {LLVM_PLUGIN_API_VERSION, "AFLCoverage", "v0.1", - /* lambda to insert our pass into the pass pipeline. */ - [](PassBuilder &PB) { - - #if 1 - #if LLVM_VERSION_MAJOR <= 13 - using OptimizationLevel = typename PassBuilder::OptimizationLevel; - #endif - PB.registerOptimizerLastEPCallback( - [](ModulePassManager &MPM, OptimizationLevel OL) { - - MPM.addPass(AFLCoverage()); - - }); - - /* TODO LTO registration */ - #else - using PipelineElement = typename PassBuilder::PipelineElement; - PB.registerPipelineParsingCallback([](StringRef Name, - ModulePassManager &MPM, - ArrayRef) { - - if (Name == "AFLCoverage") { - - MPM.addPass(AFLCoverage()); - return true; - - } else { - - return false; - - } - - }); - - #endif - - }}; - -} - -#else - char AFLCoverage::ID = 0; -#endif /* needed up to 3.9.0 */ #if LLVM_VERSION_MAJOR == 3 && \ @@ -189,15 +119,8 @@ uint64_t PowerOf2Ceil(unsigned in) { (LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1) #define AFL_HAVE_VECTOR_INTRINSICS 1 #endif - -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ -PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) { - -#else bool AFLCoverage::runOnModule(Module &M) { -#endif - LLVMContext &C = M.getContext(); IntegerType *Int8Ty = IntegerType::getInt8Ty(C); @@ -211,10 +134,6 @@ bool AFLCoverage::runOnModule(Module &M) { u32 rand_seed; unsigned int cur_loc = 0; -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - auto PA = PreservedAnalyses::all(); -#endif - /* Setup random() so we get Actually Random(TM) outputs from AFL_R() */ gettimeofday(&tv, &tz); rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); @@ -1079,15 +998,10 @@ bool AFLCoverage::runOnModule(Module &M) { } -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - return PA; -#else return true; -#endif } -#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ static void registerAFLPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -1100,5 +1014,4 @@ static RegisterStandardPasses RegisterAFLPass( static RegisterStandardPasses RegisterAFLPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass); -#endif diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index b6d51ef3..310f5585 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -28,16 +28,11 @@ #include "llvm/Config/llvm-config.h" #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#if LLVM_MAJOR >= 11 -// #include "llvm/Passes/PassPlugin.h" -// #include "llvm/Passes/PassBuilder.h" - #include "llvm/IR/PassManager.h" -#else - #include "llvm/IR/LegacyPassManager.h" -#endif +#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" @@ -60,15 +55,6 @@ using namespace llvm; namespace { -#if LLVM_MAJOR >= 11 /* use new pass manager */ -class CmpLogInstructions : public PassInfoMixin { - public: - CmpLogInstructions() { - - initInstrumentList(); - - } -#else class CmpLogInstructions : public ModulePass { public: @@ -78,11 +64,7 @@ class CmpLogInstructions : public ModulePass { initInstrumentList(); } -#endif -#if LLVM_MAJOR >= 11 /* use new pass manager */ - PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); -#else bool runOnModule(Module &M) override; #if LLVM_VERSION_MAJOR >= 4 @@ -95,7 +77,6 @@ class CmpLogInstructions : public ModulePass { return "cmplog instructions"; } -#endif private: bool hookInstrs(Module &M); @@ -104,9 +85,7 @@ class CmpLogInstructions : public ModulePass { } // namespace -#if LLVM_MAJOR <= 10 /* use old pass manager */ char CmpLogInstructions::ID = 0; -#endif template Iterator Unique(Iterator first, Iterator last) { @@ -634,12 +613,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } -#if LLVM_MAJOR >= 11 /* use new pass manager */ -PreservedAnalyses CmpLogInstructions::run(Module & M, - ModuleAnalysisManager &MAM) { -#else bool CmpLogInstructions::runOnModule(Module &M) { -#endif if (getenv("AFL_QUIET") == NULL) printf("Running cmplog-instructions-pass by andreafioraldi@gmail.com\n"); @@ -648,15 +622,10 @@ bool CmpLogInstructions::runOnModule(Module &M) { hookInstrs(M); verifyModule(M); -#if LLVM_MAJOR >= 11 /* use new pass manager */ - return PreservedAnalyses::all(); -#else return true; -#endif } -#if LLVM_MAJOR < 11 /* use old pass manager */ static void registerCmpLogInstructionsPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -676,4 +645,4 @@ static RegisterStandardPasses RegisterCmpLogInstructionsPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCmpLogInstructionsPass); #endif -#endif + diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index cd3f0e6f..969a2ef4 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -26,23 +26,14 @@ #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#if LLVM_MAJOR >= 11 /* use new pass manager */ - #include "llvm/Passes/PassPlugin.h" - #include "llvm/Passes/PassBuilder.h" - #include "llvm/IR/PassManager.h" -#else - #include "llvm/IR/LegacyPassManager.h" - #include "llvm/Transforms/IPO/PassManagerBuilder.h" -#endif +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" -#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ - #include "llvm/Passes/OptimizationLevel.h" -#endif #if LLVM_VERSION_MAJOR >= 4 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) @@ -61,21 +52,12 @@ using namespace llvm; namespace { -#if LLVM_MAJOR >= 11 /* use new pass manager */ -class CompareTransform : public PassInfoMixin { - - public: - CompareTransform() { - -#else class CompareTransform : public ModulePass { public: static char ID; CompareTransform() : ModulePass(ID) { -#endif - initInstrumentList(); } @@ -83,17 +65,18 @@ class CompareTransform : public ModulePass { #if LLVM_MAJOR < 11 #if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { - #else const char *getPassName() const override { #endif + return "transforms compare functions"; + } #endif -#if LLVM_MAJOR >= 11 /* use new pass manager */ - PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); -#else +//#if LLVM_MAJOR >= 11 /* use new pass manager */ +// PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +//#else bool runOnModule(Module &M) override; -#endif +//#endif private: bool transformCmps(Module &M, const bool processStrcmp, @@ -105,54 +88,7 @@ class CompareTransform : public ModulePass { } // namespace -#if LLVM_MAJOR >= 11 /* use new pass manager */ -extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK -llvmGetPassPluginInfo() { - - return {LLVM_PLUGIN_API_VERSION, "comparetransform", "v0.1", - /* lambda to insert our pass into the pass pipeline. */ - [](PassBuilder &PB) { - - #if 1 - #if LLVM_VERSION_MAJOR <= 13 - using OptimizationLevel = typename PassBuilder::OptimizationLevel; - #endif - PB.registerOptimizerLastEPCallback( - [](ModulePassManager &MPM, OptimizationLevel OL) { - - MPM.addPass(CompareTransform()); - - }); - - /* TODO LTO registration */ - #else - using PipelineElement = typename PassBuilder::PipelineElement; - PB.registerPipelineParsingCallback([](StringRef Name, - ModulePassManager &MPM, - ArrayRef) { - - if (Name == "comparetransform") { - - MPM.addPass(CompareTransform()); - return true; - - } else { - - return false; - - } - - }); - - #endif - - }}; - -} - -#else char CompareTransform::ID = 0; -#endif bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, const bool processMemcmp, @@ -452,7 +388,6 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, bool isCaseInsensitive = false; bool needs_null = false; Function * Callee = callInst->getCalledFunction(); - if (Callee) { if (!Callee->getName().compare("memcmp") || @@ -710,14 +645,8 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, } -#if LLVM_MAJOR >= 11 /* use new pass manager */ -PreservedAnalyses CompareTransform::run(Module &M, ModuleAnalysisManager &MAM) { - -#else bool CompareTransform::runOnModule(Module &M) { -#endif - if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) printf( "Running compare-transform-pass by laf.intel@gmail.com, extended by " @@ -725,28 +654,13 @@ bool CompareTransform::runOnModule(Module &M) { else be_quiet = 1; -#if LLVM_MAJOR >= 11 /* use new pass manager */ - auto PA = PreservedAnalyses::all(); -#endif - transformCmps(M, true, true, true, true, true); verifyModule(M); -#if LLVM_MAJOR >= 11 /* use new pass manager */ - /* if (modified) { - - PA.abandon(); - - }*/ - - return PA; -#else return true; -#endif } -#if LLVM_MAJOR < 11 /* use old pass manager */ static void registerCompTransPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -761,9 +675,8 @@ static RegisterStandardPasses RegisterCompTransPass( static RegisterStandardPasses RegisterCompTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerCompTransPass); - #if LLVM_VERSION_MAJOR >= 11 +#if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterCompTransPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCompTransPass); - #endif #endif diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index d7bb7aba..0f00fa96 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -1,7 +1,6 @@ /* * Copyright 2016 laf-intel * extended for floating point by Heiko Eißfeldt - * adapted to new pass manager by Heiko Eißfeldt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,20 +28,10 @@ #include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" - -#if LLVM_MAJOR >= 11 - #include "llvm/Passes/PassPlugin.h" - #include "llvm/Passes/PassBuilder.h" - #include "llvm/IR/PassManager.h" -#else - #include "llvm/IR/LegacyPassManager.h" - #include "llvm/Transforms/IPO/PassManagerBuilder.h" -#endif +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/IR/Module.h" -#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ - #include "llvm/Passes/OptimizationLevel.h" -#endif #include "llvm/IR/IRBuilder.h" #if LLVM_VERSION_MAJOR >= 4 || \ @@ -64,31 +53,27 @@ using namespace llvm; namespace { -#if LLVM_MAJOR >= 11 -class SplitComparesTransform : public PassInfoMixin { - - public: - // static char ID; - SplitComparesTransform() : enableFPSplit(0) { - -#else class SplitComparesTransform : public ModulePass { public: static char ID; SplitComparesTransform() : ModulePass(ID), enableFPSplit(0) { -#endif - initInstrumentList(); } -#if LLVM_MAJOR >= 11 - PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); -#else bool runOnModule(Module &M) override; +#if LLVM_VERSION_MAJOR >= 4 + StringRef getPassName() const override { + +#else + const char *getPassName() const override { + #endif + return "AFL_SplitComparesTransform"; + + } private: int enableFPSplit; @@ -177,54 +162,7 @@ class SplitComparesTransform : public ModulePass { } // namespace -#if LLVM_MAJOR >= 11 -extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK -llvmGetPassPluginInfo() { - - return {LLVM_PLUGIN_API_VERSION, "splitcompares", "v0.1", - /* lambda to insert our pass into the pass pipeline. */ - [](PassBuilder &PB) { - - #if 1 - #if LLVM_VERSION_MAJOR <= 13 - using OptimizationLevel = typename PassBuilder::OptimizationLevel; - #endif - PB.registerOptimizerLastEPCallback( - [](ModulePassManager &MPM, OptimizationLevel OL) { - - MPM.addPass(SplitComparesTransform()); - - }); - - /* TODO LTO registration */ - #else - using PipelineElement = typename PassBuilder::PipelineElement; - PB.registerPipelineParsingCallback([](StringRef Name, - ModulePassManager &MPM, - ArrayRef) { - - if (Name == "splitcompares") { - - MPM.addPass(SplitComparesTransform()); - return true; - - } else { - - return false; - - } - - }); - - #endif - - }}; - -} - -#else char SplitComparesTransform::ID = 0; -#endif /// This function splits FCMP instructions with xGE or xLE predicates into two /// FCMP instructions with predicate xGT or xLT and EQ @@ -1483,15 +1421,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } -#if LLVM_MAJOR >= 11 -PreservedAnalyses SplitComparesTransform::run(Module & M, - ModuleAnalysisManager &MAM) { - -#else bool SplitComparesTransform::runOnModule(Module &M) { -#endif - char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW"); if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW"); if (bitw_env) { target_bitwidth = atoi(bitw_env); } @@ -1501,7 +1432,7 @@ bool SplitComparesTransform::runOnModule(Module &M) { if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) { - errs() << "Split-compare-newpass by laf.intel@gmail.com, extended by " + errs() << "Split-compare-pass by laf.intel@gmail.com, extended by " "heiko@hexco.de (splitting icmp to " << target_bitwidth << " bit)\n"; @@ -1513,10 +1444,6 @@ bool SplitComparesTransform::runOnModule(Module &M) { } -#if LLVM_MAJOR >= 11 - auto PA = PreservedAnalyses::all(); -#endif - if (enableFPSplit) { simplifyFPCompares(M); @@ -1546,16 +1473,7 @@ bool SplitComparesTransform::runOnModule(Module &M) { auto op0 = CI->getOperand(0); auto op1 = CI->getOperand(1); - if (!op0 || !op1) { - -#if LLVM_MAJOR >= 11 - return PA; -#else - return false; -#endif - - } - + if (!op0 || !op1) { return false; } auto iTy1 = dyn_cast(op0->getType()); if (iTy1 && isa(op1->getType())) { @@ -1604,29 +1522,10 @@ bool SplitComparesTransform::runOnModule(Module &M) { } - if ((isatty(2) && getenv("AFL_QUIET") == NULL) || - getenv("AFL_DEBUG") != NULL) { - - errs() << count << " comparisons found\n"; - - } - -#if LLVM_MAJOR >= 11 - /* if (modified) { - - PA.abandon(); - - }*/ - - return PA; -#else return true; -#endif } -#if LLVM_MAJOR < 11 /* use old pass manager */ - static void registerSplitComparesPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -1640,15 +1539,14 @@ static RegisterStandardPasses RegisterSplitComparesPass( static RegisterStandardPasses RegisterSplitComparesTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitComparesPass); - #if LLVM_VERSION_MAJOR >= 11 +#if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterSplitComparesTransPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerSplitComparesPass); - #endif +#endif static RegisterPass X("splitcompares", "AFL++ split compares", true /* Only looks at CFG */, true /* Analysis Pass */); -#endif diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc index 96e01a8b..9f9e7eca 100644 --- a/instrumentation/split-switches-pass.so.cc +++ b/instrumentation/split-switches-pass.so.cc @@ -27,23 +27,14 @@ #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - #include "llvm/Passes/PassPlugin.h" - #include "llvm/Passes/PassBuilder.h" - #include "llvm/IR/PassManager.h" -#else - #include "llvm/IR/LegacyPassManager.h" - #include "llvm/Transforms/IPO/PassManagerBuilder.h" -#endif +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" -#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ - #include "llvm/Passes/OptimizationLevel.h" -#endif #include "llvm/IR/IRBuilder.h" #if LLVM_VERSION_MAJOR >= 4 || \ @@ -63,42 +54,29 @@ using namespace llvm; namespace { -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ -class SplitSwitchesTransform : public PassInfoMixin { - - public: - SplitSwitchesTransform() { - -#else class SplitSwitchesTransform : public ModulePass { public: static char ID; SplitSwitchesTransform() : ModulePass(ID) { -#endif initInstrumentList(); } -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); -#else - bool runOnModule(Module &M) override; + bool runOnModule(Module &M) override; - #if LLVM_VERSION_MAJOR >= 4 +#if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { - #else +#else const char *getPassName() const override { - #endif +#endif return "splits switch constructs"; } -#endif - struct CaseExpr { ConstantInt *Val; @@ -125,54 +103,7 @@ class SplitSwitchesTransform : public ModulePass { } // namespace -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ -extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK -llvmGetPassPluginInfo() { - - return {LLVM_PLUGIN_API_VERSION, "splitswitches", "v0.1", - /* lambda to insert our pass into the pass pipeline. */ - [](PassBuilder &PB) { - - #if 1 - #if LLVM_VERSION_MAJOR <= 13 - using OptimizationLevel = typename PassBuilder::OptimizationLevel; - #endif - PB.registerOptimizerLastEPCallback( - [](ModulePassManager &MPM, OptimizationLevel OL) { - - MPM.addPass(SplitSwitchesTransform()); - - }); - - /* TODO LTO registration */ - #else - using PipelineElement = typename PassBuilder::PipelineElement; - PB.registerPipelineParsingCallback([](StringRef Name, - ModulePassManager &MPM, - ArrayRef) { - - if (Name == "splitswitches") { - - MPM.addPass(SplitSwitchesTransform()); - return true; - - } else { - - return false; - - } - - }); - - #endif - - }}; - -} - -#else char SplitSwitchesTransform::ID = 0; -#endif /* switchConvert - Transform simple list of Cases into list of CaseRange's */ BasicBlock *SplitSwitchesTransform::switchConvert( @@ -482,42 +413,19 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { } -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ -PreservedAnalyses SplitSwitchesTransform::run(Module & M, - ModuleAnalysisManager &MAM) { - -#else bool SplitSwitchesTransform::runOnModule(Module &M) { -#endif - if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) printf("Running split-switches-pass by laf.intel@gmail.com\n"); else be_quiet = 1; - -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - auto PA = PreservedAnalyses::all(); -#endif - splitSwitches(M); verifyModule(M); -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - /* if (modified) { - - PA.abandon(); - - }*/ - - return PA; -#else return true; -#endif } -#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ static void registerSplitSwitchesTransPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -532,10 +440,9 @@ static RegisterStandardPasses RegisterSplitSwitchesTransPass( static RegisterStandardPasses RegisterSplitSwitchesTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitSwitchesTransPass); - #if LLVM_VERSION_MAJOR >= 11 +#if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterSplitSwitchesTransPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerSplitSwitchesTransPass); - #endif #endif diff --git a/src/afl-cc.c b/src/afl-cc.c index 3e67085e..bacd9de9 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -462,17 +462,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { -#if LLVM_MAJOR >= 11 /* use new pass manager */ - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); -#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/split-switches-pass.so", obj_path); -#endif } @@ -488,17 +482,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { -#if LLVM_MAJOR >= 11 /* use new pass manager */ - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = alloc_printf( - "-fpass-plugin=%s/compare-transform-pass.so", obj_path); -#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/compare-transform-pass.so", obj_path); -#endif } @@ -514,16 +502,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { -#if LLVM_MAJOR >= 11 - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path); -#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/split-compares-pass.so", obj_path); -#endif } @@ -553,17 +536,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { alloc_printf("%s/cmplog-switches-pass.so", obj_path); // reuse split switches from laf -#if LLVM_MAJOR >= 11 - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); -#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/split-switches-pass.so", obj_path); -#endif } @@ -571,8 +548,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#if LLVM_MAJOR == 13 // TODO: set to 14 when done FIXME - // Use the old pass manager in LLVM 13 which the afl++ passes still use. +#if LLVM_MAJOR >= 13 + // Use the old pass manager in LLVM 14 which the afl++ passes still use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager"; #endif @@ -656,16 +633,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { -#if LLVM_MAJOR >= 11 - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path); -#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); -#endif } @@ -682,17 +653,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { -#if LLVM_MAJOR >= 11 - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path); -#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/cmplog-instructions-pass.so", obj_path); -#endif cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; -- cgit 1.4.1 From d84a8da1e9b68f03597f17a9c6c53503551fcb51 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Mar 2022 19:30:17 +0100 Subject: allow for -c0 also for src targets --- docs/Changelog.md | 3 +++ docs/fuzzing_binary-only_targets.md | 9 +++++---- src/afl-fuzz.c | 9 ++++++++- 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index f4ae0e43..549d5e4a 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -12,6 +12,9 @@ sending a mail to . - fix */build_...sh scripts to work outside of git - new custom_mutator: libafl with token fuzzing :) - afl-fuzz: + - when you just want to compile once and set CMPLOG, then just + set -c 0 to tell afl-fuzz that the fuzzing binary is also for + CMPLOG. - new commandline options -g/G to set min/max length of generated fuzz inputs - reintroduced AFL_PERSISTENT and AFL_DEFER_FORKSRV to allow diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md index 1a2b27c7..c97af1b9 100644 --- a/docs/fuzzing_binary-only_targets.md +++ b/docs/fuzzing_binary-only_targets.md @@ -48,11 +48,12 @@ The following setup to use QEMU mode is recommended: Then run as many instances as you have cores left with either -Q mode or - even better - use a binary rewriter like Dyninst, RetroWrite, ZAFL, etc. +The binary rewriters all have their own advantages and caveats. +ZAFL is the best but cannot be used in a business/commercial context. -If [afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst) works for your -binary, then you can use afl-fuzz normally and it will have twice the speed -compared to QEMU mode (but slower than QEMU persistent mode). Note that several -other binary rewriters exist, all with their advantages and caveats. +If a binary rewriter works for your target then you can use afl-fuzz normally +and it will have twice the speed compared to QEMU mode (but slower than QEMU +persistent mode). The speed decrease of QEMU mode is at about 50%. However, various options exist to increase the speed: diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c73ab38b..6b177274 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -167,7 +167,8 @@ static void usage(u8 *argv0, int more_help) { " See docs/README.MOpt.md\n" " -c program - enable CmpLog by specifying a binary compiled for " "it.\n" - " if using QEMU, just use -c 0.\n" + " if using QEMU/FRIDA or if you the fuzzing target is compiled" + " for CmpLog then just use -c 0.\n" " -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n" " 1=small files, 2=larger files (default), 3=all " "files,\n" @@ -1458,6 +1459,12 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->use_banner) { afl->use_banner = argv[optind]; } + if (afl->shm.cmplog_mode && (!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) { + + afl->cmplog_binary = argv[optind]; + + } + if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) { WARNF(cLRD -- cgit 1.4.1 From 7e67545b9de14ae6e425d184581bec93ccf84c6a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Mar 2022 20:01:12 +0100 Subject: code format --- instrumentation/compare-transform-pass.so.cc | 21 +++++++++++++-------- src/afl-fuzz.c | 6 ++++-- 2 files changed, 17 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index 969a2ef4..c668ba95 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -63,20 +63,25 @@ class CompareTransform : public ModulePass { } #if LLVM_MAJOR < 11 -#if LLVM_VERSION_MAJOR >= 4 + #if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { -#else + + #else const char *getPassName() const override { -#endif + + #endif return "transforms compare functions"; + } + #endif -//#if LLVM_MAJOR >= 11 /* use new pass manager */ -// PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); -//#else + //#if LLVM_MAJOR >= 11 /* use new pass manager + / /*/ + // PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); + //#else bool runOnModule(Module &M) override; -//#endif + //#endif private: bool transformCmps(Module &M, const bool processStrcmp, @@ -106,7 +111,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, #if LLVM_VERSION_MAJOR >= 9 FunctionCallee tolowerFn; #else - Function * tolowerFn; + Function *tolowerFn; #endif { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 6b177274..a3f57c1e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -167,7 +167,8 @@ static void usage(u8 *argv0, int more_help) { " See docs/README.MOpt.md\n" " -c program - enable CmpLog by specifying a binary compiled for " "it.\n" - " if using QEMU/FRIDA or if you the fuzzing target is compiled" + " if using QEMU/FRIDA or if you the fuzzing target is " + "compiled" " for CmpLog then just use -c 0.\n" " -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n" " 1=small files, 2=larger files (default), 3=all " @@ -1459,7 +1460,8 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->use_banner) { afl->use_banner = argv[optind]; } - if (afl->shm.cmplog_mode && (!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) { + if (afl->shm.cmplog_mode && + (!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) { afl->cmplog_binary = argv[optind]; -- cgit 1.4.1 From d325fa5db8287e0b4984b12b07b16cf0f643c468 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 1 Mar 2022 20:13:57 +0100 Subject: code format --- instrumentation/cmplog-instructions-pass.cc | 31 +++++++++++++++++----------- instrumentation/compare-transform-pass.so.cc | 23 +++++++++++---------- src/afl-cc.c | 10 ++++----- 3 files changed, 36 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index b6d51ef3..b3fe3880 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -60,14 +60,16 @@ using namespace llvm; namespace { -#if LLVM_MAJOR >= 11 /* use new pass manager */ +#if LLVM_MAJOR >= 11 /* use new pass manager */ class CmpLogInstructions : public PassInfoMixin { + public: CmpLogInstructions() { initInstrumentList(); } + #else class CmpLogInstructions : public ModulePass { @@ -78,23 +80,25 @@ class CmpLogInstructions : public ModulePass { initInstrumentList(); } + #endif -#if LLVM_MAJOR >= 11 /* use new pass manager */ +#if LLVM_MAJOR >= 11 /* use new pass manager */ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); #else - bool runOnModule(Module &M) override; + bool runOnModule(Module &M) override; -#if LLVM_VERSION_MAJOR >= 4 + #if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { -#else + #else const char *getPassName() const override { -#endif + #endif return "cmplog instructions"; } + #endif private: @@ -104,7 +108,7 @@ class CmpLogInstructions : public ModulePass { } // namespace -#if LLVM_MAJOR <= 10 /* use old pass manager */ +#if LLVM_MAJOR <= 10 /* use old pass manager */ char CmpLogInstructions::ID = 0; #endif @@ -634,11 +638,13 @@ bool CmpLogInstructions::hookInstrs(Module &M) { } -#if LLVM_MAJOR >= 11 /* use new pass manager */ +#if LLVM_MAJOR >= 11 /* use new pass manager */ PreservedAnalyses CmpLogInstructions::run(Module & M, - ModuleAnalysisManager &MAM) { + ModuleAnalysisManager &MAM) { + #else bool CmpLogInstructions::runOnModule(Module &M) { + #endif if (getenv("AFL_QUIET") == NULL) @@ -648,7 +654,7 @@ bool CmpLogInstructions::runOnModule(Module &M) { hookInstrs(M); verifyModule(M); -#if LLVM_MAJOR >= 11 /* use new pass manager */ +#if LLVM_MAJOR >= 11 /* use new pass manager */ return PreservedAnalyses::all(); #else return true; @@ -671,9 +677,10 @@ static RegisterStandardPasses RegisterCmpLogInstructionsPass( static RegisterStandardPasses RegisterCmpLogInstructionsPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogInstructionsPass); -#if LLVM_VERSION_MAJOR >= 11 + #if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterCmpLogInstructionsPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCmpLogInstructionsPass); + #endif #endif -#endif + diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index cd3f0e6f..4e471ea3 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -81,27 +81,28 @@ class CompareTransform : public ModulePass { } #if LLVM_MAJOR < 11 -#if LLVM_VERSION_MAJOR >= 4 + #if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { -#else + #else const char *getPassName() const override { -#endif + + #endif #endif #if LLVM_MAJOR >= 11 /* use new pass manager */ - PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); + PreservedAnalyses run(Module & M, ModuleAnalysisManager & MAM); #else bool runOnModule(Module &M) override; #endif - private: - bool transformCmps(Module &M, const bool processStrcmp, - const bool processMemcmp, const bool processStrncmp, - const bool processStrcasecmp, - const bool processStrncasecmp); + private: + bool transformCmps(Module & M, const bool processStrcmp, + const bool processMemcmp, const bool processStrncmp, + const bool processStrcasecmp, + const bool processStrncasecmp); -}; + }; } // namespace @@ -170,7 +171,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, #if LLVM_VERSION_MAJOR >= 9 FunctionCallee tolowerFn; #else - Function * tolowerFn; + Function *tolowerFn; #endif { diff --git a/src/afl-cc.c b/src/afl-cc.c index 3e67085e..fae572f6 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -462,7 +462,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { -#if LLVM_MAJOR >= 11 /* use new pass manager */ +#if LLVM_MAJOR >= 11 /* use new pass manager */ cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); @@ -488,7 +488,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { -#if LLVM_MAJOR >= 11 /* use new pass manager */ +#if LLVM_MAJOR >= 11 /* use new pass manager */ cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; cc_params[cc_par_cnt++] = alloc_printf( "-fpass-plugin=%s/compare-transform-pass.so", obj_path); @@ -571,7 +571,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -#if LLVM_MAJOR == 13 // TODO: set to 14 when done FIXME +#if LLVM_MAJOR == 13 // TODO: set to 14 when done FIXME // Use the old pass manager in LLVM 13 which the afl++ passes still use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager"; #endif @@ -684,8 +684,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { #if LLVM_MAJOR >= 11 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path); + cc_params[cc_par_cnt++] = alloc_printf( + "-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path); #else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; -- cgit 1.4.1 From 0f7419fc9166b1f719372e1658efc4e3b9c88ac5 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Fri, 4 Mar 2022 05:41:40 +0100 Subject: write nyx crash logs to AFL++ work directory --- include/forkserver.h | 2 ++ src/afl-forkserver.c | 8 +++++++- src/afl-fuzz-bitmap.c | 14 ++++++++++++++ src/afl-fuzz.c | 4 ++++ 4 files changed, 27 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/include/forkserver.h b/include/forkserver.h index fd4d283c..cb68ce4f 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -70,6 +70,7 @@ typedef struct { enum NyxReturnValue (*nyx_exec)(void *qemu_process); uint8_t *(*nyx_get_bitmap_buffer)(void *qemu_process); size_t (*nyx_get_bitmap_buffer_size)(void *qemu_process); + uint32_t (*nyx_get_aux_string)(void *nyx_process, uint8_t *buffer, uint32_t size); } nyx_plugin_handler_t; @@ -173,6 +174,7 @@ typedef struct afl_forkserver { void * nyx_runner; /* nyx runner object */ u32 nyx_id; /* nyx runner id (0 -> master) */ u32 nyx_bind_cpu_id; /* nyx runner cpu id */ + char* nyx_aux_string; #endif } afl_forkserver_t; diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 8997781d..54f28852 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -450,6 +450,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0); fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner); + fsrv->nyx_aux_string = malloc(0x1000); + memset(fsrv->nyx_aux_string, 0, 0x1000); + /* dry run */ fsrv->nyx_handlers->nyx_set_afl_input(fsrv->nyx_runner, "INIT", 4); switch (fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)) { @@ -1253,7 +1256,10 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) { fsrv->child_pid = -1; #ifdef __linux__ - if (fsrv->nyx_mode) { fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); } + if (fsrv->nyx_mode) { + free(fsrv->nyx_aux_string); + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + } #endif } diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index b963caf8..bce1a195 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -771,6 +771,20 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ck_write(fd, mem, len, fn); close(fd); + if(afl->fsrv.nyx_mode && fault == FSRV_RUN_CRASH) { + u8 fn_log[PATH_MAX]; + + snprintf(fn_log, PATH_MAX, "%s.log", fn); + + fd = open(fn_log, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); + if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn_log); } + + u32 nyx_aux_string_len = afl->fsrv.nyx_handlers->nyx_get_aux_string(afl->fsrv.nyx_runner, afl->fsrv.nyx_aux_string, 0x1000); + + ck_write(fd, afl->fsrv.nyx_aux_string, nyx_aux_string_len, fn_log); + close(fd); + } + return keeping; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a3f57c1e..df6e5404 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -468,6 +468,10 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { dlsym(handle, "nyx_get_bitmap_buffer_size"); if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; } + plugin->nyx_get_aux_string = + dlsym(handle, "nyx_get_aux_string"); + if (plugin->nyx_get_aux_string == NULL) { goto fail; } + OKF("libnyx plugin is ready!"); return plugin; -- cgit 1.4.1 From 713b069f40094482fb41ef17b44150162c062249 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Fri, 4 Mar 2022 06:01:49 +0100 Subject: fix compile error on non linux targets --- src/afl-fuzz-bitmap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index bce1a195..226dfa5c 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -771,6 +771,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ck_write(fd, mem, len, fn); close(fd); +#ifdef __linux__ if(afl->fsrv.nyx_mode && fault == FSRV_RUN_CRASH) { u8 fn_log[PATH_MAX]; @@ -784,6 +785,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { ck_write(fd, afl->fsrv.nyx_aux_string, nyx_aux_string_len, fn_log); close(fd); } +#endif return keeping; -- cgit 1.4.1 From 2eeba2dbf085b1c679dc82d59a0ec0ddc2c05429 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 4 Mar 2022 09:41:21 +0100 Subject: code format --- include/forkserver.h | 5 +++-- nyx_mode/custom_harness/example.c | 7 ++++--- src/afl-forkserver.c | 5 ++++- src/afl-fuzz-bitmap.c | 11 +++++++---- src/afl-fuzz.c | 3 +-- 5 files changed, 19 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/include/forkserver.h b/include/forkserver.h index cb68ce4f..5b66e7ec 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -70,7 +70,8 @@ typedef struct { enum NyxReturnValue (*nyx_exec)(void *qemu_process); uint8_t *(*nyx_get_bitmap_buffer)(void *qemu_process); size_t (*nyx_get_bitmap_buffer_size)(void *qemu_process); - uint32_t (*nyx_get_aux_string)(void *nyx_process, uint8_t *buffer, uint32_t size); + uint32_t (*nyx_get_aux_string)(void *nyx_process, uint8_t *buffer, + uint32_t size); } nyx_plugin_handler_t; @@ -174,7 +175,7 @@ typedef struct afl_forkserver { void * nyx_runner; /* nyx runner object */ u32 nyx_id; /* nyx runner id (0 -> master) */ u32 nyx_bind_cpu_id; /* nyx runner cpu id */ - char* nyx_aux_string; + char * nyx_aux_string; #endif } afl_forkserver_t; diff --git a/nyx_mode/custom_harness/example.c b/nyx_mode/custom_harness/example.c index dd268534..a67d42c6 100644 --- a/nyx_mode/custom_harness/example.c +++ b/nyx_mode/custom_harness/example.c @@ -7,7 +7,7 @@ #define TRACE_BUFFER_SIZE (64) #define PAGE_SIZE 0x1000 -#define MMAP_SIZE(x) ((x & ~(PAGE_SIZE-1)) + PAGE_SIZE) +#define MMAP_SIZE(x) ((x & ~(PAGE_SIZE - 1)) + PAGE_SIZE) int main(int argc, char **argv) { @@ -30,8 +30,9 @@ int main(int argc, char **argv) { /* this is our "bitmap" that is later shared with the fuzzer (you can also * pass the pointer of the bitmap used by compile-time instrumentations in * your target) */ - uint8_t *trace_buffer = mmap(NULL, MMAP_SIZE(TRACE_BUFFER_SIZE), PROT_READ | - PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); + uint8_t *trace_buffer = + mmap(NULL, MMAP_SIZE(TRACE_BUFFER_SIZE), PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); memset(trace_buffer, 0, TRACE_BUFFER_SIZE); // makes sure that the bitmap buffer is already // mapped into the guest's memory (alternatively diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 54f28852..628ff590 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -1257,9 +1257,12 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) { #ifdef __linux__ if (fsrv->nyx_mode) { + free(fsrv->nyx_aux_string); - fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + } + #endif } diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 226dfa5c..a7c77aec 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -772,19 +772,22 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { close(fd); #ifdef __linux__ - if(afl->fsrv.nyx_mode && fault == FSRV_RUN_CRASH) { - u8 fn_log[PATH_MAX]; + if (afl->fsrv.nyx_mode && fault == FSRV_RUN_CRASH) { - snprintf(fn_log, PATH_MAX, "%s.log", fn); + u8 fn_log[PATH_MAX]; + snprintf(fn_log, PATH_MAX, "%s.log", fn); fd = open(fn_log, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn_log); } - u32 nyx_aux_string_len = afl->fsrv.nyx_handlers->nyx_get_aux_string(afl->fsrv.nyx_runner, afl->fsrv.nyx_aux_string, 0x1000); + u32 nyx_aux_string_len = afl->fsrv.nyx_handlers->nyx_get_aux_string( + afl->fsrv.nyx_runner, afl->fsrv.nyx_aux_string, 0x1000); ck_write(fd, afl->fsrv.nyx_aux_string, nyx_aux_string_len, fn_log); close(fd); + } + #endif return keeping; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index df6e5404..da1c7602 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -468,8 +468,7 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { dlsym(handle, "nyx_get_bitmap_buffer_size"); if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; } - plugin->nyx_get_aux_string = - dlsym(handle, "nyx_get_aux_string"); + plugin->nyx_get_aux_string = dlsym(handle, "nyx_get_aux_string"); if (plugin->nyx_get_aux_string == NULL) { goto fail; } OKF("libnyx plugin is ready!"); -- cgit 1.4.1 From 70cc32dc6ddac78b686a5b7d16bfd9ede3daa81a Mon Sep 17 00:00:00 2001 From: mchesser Date: Mon, 7 Mar 2022 14:28:45 +1030 Subject: Fix issue with trim in shared memory mode --- src/afl-fuzz-run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 5da0e583..2a9d186b 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -232,7 +232,7 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, memcpy(afl->fsrv.shmem_fuzz, mem, skip_at); - memcpy(afl->fsrv.shmem_fuzz, mem + skip_at + skip_len, tail_len); + memcpy(afl->fsrv.shmem_fuzz + skip_at, mem + skip_at + skip_len, tail_len); } -- cgit 1.4.1 From c2229b506e045bba1864e8b2f8140c8dc6e83a4d Mon Sep 17 00:00:00 2001 From: mchesser Date: Mon, 7 Mar 2022 14:35:25 +1030 Subject: Fix off by one bounds check `is_hex` reads two bytes but caller previously only ensured that one byte was in bounds. --- src/afl-fuzz-redqueen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 1e4b1b3c..66df5c6f 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -2136,7 +2136,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, if ((i % 2)) { - if (len > idx + i && is_hex(orig_buf + idx + i)) { + if (len > idx + i + 1 && is_hex(orig_buf + idx + i)) { fromhex += 2; -- cgit 1.4.1 From 2a00f32666a847b7babb160bb7c27db59cec9561 Mon Sep 17 00:00:00 2001 From: mchesser Date: Mon, 7 Mar 2022 14:39:36 +1030 Subject: Fix buffer overrun in `rtn_extended_encoding` `idx + i` can range from `0` to `buf.len`, but the memcpy may try and write to offsets from `idx + i` to `idx + 2 * i`. --- src/afl-fuzz-redqueen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 66df5c6f..2f32ef1e 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -2323,7 +2323,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } // fprintf(stderr, "RTN ATTEMPT fromhex %u result %u\n", fromhex, // *status); - memcpy(buf + idx + i, save + i, i + 1 + off); + memcpy(buf + idx, save, i + 1 + off); } -- cgit 1.4.1 From d29773825594e7249e8a3a80b344a69249e7ab9a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 7 Mar 2022 09:37:19 +0100 Subject: nits --- README.md | 2 +- src/afl-fuzz-bitmap.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/README.md b/README.md index 66b884e2..a29ce792 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ Step-by-step quick start: 5. You will find found crashes and hangs in the subdirectories `crashes/` and `hangs/` in the `-o output_dir` directory. You can replay the crashes by - feeding them to the target, e.g.: + feeding them to the target, e.g. if your target is using stdin: ``` cat output_dir/crashes/id:000000,* | /path/to/tested/program [...program's cmdline...] diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index a7c77aec..971ac494 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -423,10 +423,10 @@ void write_crash_readme(afl_state_t *afl) { "them to a vendor? Check out the afl-tmin that comes with the fuzzer!\n\n" "Found any cool bugs in open-source tools using afl-fuzz? If yes, please " - "drop\n" - "an mail at once the issues are fixed\n\n" - - " https://github.com/AFLplusplus/AFLplusplus\n\n", + "post\n" + "to https://github.com/AFLplusplus/AFLplusplus/issues/286 once the " + "issues\n" + " are fixed :)\n\n", afl->orig_cmdline, stringify_mem_size(val_buf, sizeof(val_buf), -- cgit 1.4.1 From c08304ad3d649df5033bd69a2096d454a28c36fc Mon Sep 17 00:00:00 2001 From: cd80 Date: Thu, 17 Mar 2022 14:36:41 +0900 Subject: fix typo for error message when using LD_PRELOAD --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c73ab38b..eac01c9a 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1675,7 +1675,7 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("LD_PRELOAD")) { WARNF( - "LD_PRELOAD is set, are you sure that is what to you want to do " + "LD_PRELOAD is set, are you sure that is what you want to do " "instead of using AFL_PRELOAD?"); } -- cgit 1.4.1 From 59eaed2f70cd495092d747fd872d429e14f4d6a9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 17 Mar 2022 13:52:48 +0100 Subject: make pcguard work --- .../SanitizerCoveragePCGUARD-alternative.so.cc | 1514 -------------------- instrumentation/SanitizerCoveragePCGUARD.so.cc | 142 +- src/afl-cc.c | 6 + 3 files changed, 80 insertions(+), 1582 deletions(-) delete mode 100644 instrumentation/SanitizerCoveragePCGUARD-alternative.so.cc (limited to 'src') diff --git a/instrumentation/SanitizerCoveragePCGUARD-alternative.so.cc b/instrumentation/SanitizerCoveragePCGUARD-alternative.so.cc deleted file mode 100644 index 982f610a..00000000 --- a/instrumentation/SanitizerCoveragePCGUARD-alternative.so.cc +++ /dev/null @@ -1,1514 +0,0 @@ -//===-- SanitizerCoverage.cpp - coverage instrumentation for sanitizers ---===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Coverage instrumentation done on LLVM IR level, works with Sanitizers. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Analysis/EHPersonalities.h" -#include "llvm/Analysis/PostDominators.h" -#include "llvm/IR/CFG.h" -#include "llvm/IR/Constant.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DebugInfo.h" -#include "llvm/IR/Dominators.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/GlobalVariable.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/InlineAsm.h" -#include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/Intrinsics.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/MDBuilder.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/PassManager.h" -#include "llvm/IR/Type.h" -#include "llvm/InitializePasses.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/SpecialCaseList.h" -#include "llvm/Support/VirtualFileSystem.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Transforms/Instrumentation.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Transforms/Utils/ModuleUtils.h" -#include "llvm/Passes/PassPlugin.h" -#include "llvm/Passes/PassBuilder.h" -#include "llvm/IR/PassManager.h" - -#include "config.h" -#include "debug.h" -#include "afl-llvm-common.h" - -using namespace llvm; - -#define DEBUG_TYPE "sancov" - -const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir"; -const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc"; -const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1"; -const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2"; -const char SanCovTraceCmp4[] = "__sanitizer_cov_trace_cmp4"; -const char SanCovTraceCmp8[] = "__sanitizer_cov_trace_cmp8"; -const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1"; -const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2"; -const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4"; -const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8"; -const char SanCovTraceDiv4[] = "__sanitizer_cov_trace_div4"; -const char SanCovTraceDiv8[] = "__sanitizer_cov_trace_div8"; -const char SanCovTraceGep[] = "__sanitizer_cov_trace_gep"; -const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch"; -const char SanCovModuleCtorTracePcGuardName[] = - "sancov.module_ctor_trace_pc_guard"; -const char SanCovModuleCtor8bitCountersName[] = - "sancov.module_ctor_8bit_counters"; -const char SanCovModuleCtorBoolFlagName[] = "sancov.module_ctor_bool_flag"; -static const uint64_t SanCtorAndDtorPriority = 2; - -const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard"; -const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init"; -const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init"; -const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init"; -const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init"; - -const char SanCovGuardsSectionName[] = "sancov_guards"; -const char SanCovCountersSectionName[] = "sancov_cntrs"; -const char SanCovBoolFlagSectionName[] = "sancov_bools"; -const char SanCovPCsSectionName[] = "sancov_pcs"; - -const char SanCovLowestStackName[] = "__sancov_lowest_stack"; - -static const char *skip_nozero; -static const char *use_threadsafe_counters; - -namespace { - -SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) { - - // Sets CoverageType and IndirectCalls. - // SanitizerCoverageOptions CLOpts = getOptions(ClCoverageLevel); - Options.CoverageType = - SanitizerCoverageOptions::SCK_Edge; // std::max(Options.CoverageType, - // CLOpts.CoverageType); - Options.IndirectCalls = false; // CLOpts.IndirectCalls; - Options.TraceCmp = false; //|= ClCMPTracing; - Options.TraceDiv = false; //|= ClDIVTracing; - Options.TraceGep = false; //|= ClGEPTracing; - Options.TracePC = false; //|= ClTracePC; - Options.TracePCGuard = true; // |= ClTracePCGuard; - Options.Inline8bitCounters = 0; //|= ClInline8bitCounters; - // Options.InlineBoolFlag = 0; //|= ClInlineBoolFlag; - Options.PCTable = false; //|= ClCreatePCTable; - Options.NoPrune = false; //|= !ClPruneBlocks; - Options.StackDepth = false; //|= ClStackDepth; - if (!Options.TracePCGuard && !Options.TracePC && - !Options.Inline8bitCounters && !Options.StackDepth /*&& - !Options.InlineBoolFlag*/) - Options.TracePCGuard = true; // TracePCGuard is default. - - return Options; - -} - -using DomTreeCallback = function_ref; -using PostDomTreeCallback = - function_ref; - -class ModuleSanitizerCoverageAFL - : public PassInfoMixin { - - public: - ModuleSanitizerCoverageAFL( - const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) - : Options(OverrideFromCL(Options)) { - - } - - PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); - - bool instrumentModule(Module &M, DomTreeCallback DTCallback, - PostDomTreeCallback PDTCallback); - - private: - void instrumentFunction(Function &F, DomTreeCallback DTCallback, - PostDomTreeCallback PDTCallback); - void InjectCoverageForIndirectCalls(Function & F, - ArrayRef IndirCalls); - void InjectTraceForCmp(Function &F, ArrayRef CmpTraceTargets); - void InjectTraceForDiv(Function & F, - ArrayRef DivTraceTargets); - void InjectTraceForGep(Function & F, - ArrayRef GepTraceTargets); - void InjectTraceForSwitch(Function & F, - ArrayRef SwitchTraceTargets); - bool InjectCoverage(Function &F, ArrayRef AllBlocks, - bool IsLeafFunc = true); - GlobalVariable *CreateFunctionLocalArrayInSection(size_t NumElements, - Function &F, Type *Ty, - const char *Section); - GlobalVariable *CreatePCArray(Function &F, ArrayRef AllBlocks); - void CreateFunctionLocalArrays(Function &F, ArrayRef AllBlocks, - uint32_t special); - void InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx, - bool IsLeafFunc = true); - Function *CreateInitCallsForSections(Module &M, const char *CtorName, - const char *InitFunctionName, Type *Ty, - const char *Section); - std::pair CreateSecStartEnd(Module &M, const char *Section, - Type *Ty); - - void SetNoSanitizeMetadata(Instruction *I) { - - I->setMetadata(I->getModule()->getMDKindID("nosanitize"), - MDNode::get(*C, None)); - - } - - std::string getSectionName(const std::string &Section) const; - std::string getSectionStart(const std::string &Section) const; - std::string getSectionEnd(const std::string &Section) const; - FunctionCallee SanCovTracePCIndir; - FunctionCallee SanCovTracePC, SanCovTracePCGuard; - FunctionCallee SanCovTraceCmpFunction[4]; - FunctionCallee SanCovTraceConstCmpFunction[4]; - FunctionCallee SanCovTraceDivFunction[2]; - FunctionCallee SanCovTraceGepFunction; - FunctionCallee SanCovTraceSwitchFunction; - GlobalVariable *SanCovLowestStack; - Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy, - *Int16Ty, *Int8Ty, *Int8PtrTy, *Int1Ty, *Int1PtrTy; - Module * CurModule; - std::string CurModuleUniqueId; - Triple TargetTriple; - LLVMContext * C; - const DataLayout *DL; - - GlobalVariable *FunctionGuardArray; // for trace-pc-guard. - GlobalVariable *Function8bitCounterArray; // for inline-8bit-counters. - GlobalVariable *FunctionBoolArray; // for inline-bool-flag. - GlobalVariable *FunctionPCsArray; // for pc-table. - SmallVector GlobalsToAppendToUsed; - SmallVector GlobalsToAppendToCompilerUsed; - - SanitizerCoverageOptions Options; - - uint32_t instr = 0, selects = 0, unhandled = 0; - GlobalVariable *AFLMapPtr = NULL; - ConstantInt * One = NULL; - ConstantInt * Zero = NULL; - -}; - -class ModuleSanitizerCoverageLegacyPass : public ModulePass { - - public: - ModuleSanitizerCoverageLegacyPass( - const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) - : ModulePass(ID), Options(Options) { - - initializeModuleSanitizerCoverageLegacyPassPass( - *PassRegistry::getPassRegistry()); - - } - - bool runOnModule(Module &M) override { - - ModuleSanitizerCoverageAFL ModuleSancov(Options); - auto DTCallback = [this](Function &F) -> const DominatorTree * { - - return &this->getAnalysis(F).getDomTree(); - - }; - - auto PDTCallback = [this](Function &F) -> const PostDominatorTree * { - - return &this->getAnalysis(F) - .getPostDomTree(); - - }; - - return ModuleSancov.instrumentModule(M, DTCallback, PDTCallback); - - } - - static char ID; // Pass identification, replacement for typeid - StringRef getPassName() const override { - - return "ModuleSanitizerCoverage"; - - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - - AU.addRequired(); - AU.addRequired(); - - } - - private: - SanitizerCoverageOptions Options; - -}; - -} // namespace - -#if 1 - -extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK -llvmGetPassPluginInfo() { - - return {LLVM_PLUGIN_API_VERSION, "SanitizerCoveragePCGUARD", "v0.1", - /* lambda to insert our pass into the pass pipeline. */ - [](PassBuilder &PB) { - - #if LLVM_VERSION_MAJOR <= 13 - using OptimizationLevel = typename PassBuilder::OptimizationLevel; - #endif - PB.registerOptimizerLastEPCallback( - [](ModulePassManager &MPM, OptimizationLevel OL) { - - MPM.addPass(ModuleSanitizerCoverageAFL()); - - }); - - }}; - -} - -#endif - -PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module & M, - ModuleAnalysisManager &MAM) { - - fprintf(stderr, "IS CALLED!\n"); - - ModuleSanitizerCoverageAFL ModuleSancov(Options); - auto &FAM = MAM.getResult(M).getManager(); - auto DTCallback = [&FAM](Function &F) -> const DominatorTree * { - - return &FAM.getResult(F); - - }; - - auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * { - - return &FAM.getResult(F); - - }; - - if (ModuleSancov.instrumentModule(M, DTCallback, PDTCallback)) - return PreservedAnalyses::none(); - return PreservedAnalyses::all(); - -} - -std::pair ModuleSanitizerCoverageAFL::CreateSecStartEnd( - Module &M, const char *Section, Type *Ty) { - - GlobalVariable *SecStart = new GlobalVariable( - M, Ty->getPointerElementType(), false, - GlobalVariable::ExternalWeakLinkage, nullptr, getSectionStart(Section)); - SecStart->setVisibility(GlobalValue::HiddenVisibility); - GlobalVariable *SecEnd = new GlobalVariable( - M, Ty->getPointerElementType(), false, - GlobalVariable::ExternalWeakLinkage, nullptr, getSectionEnd(Section)); - SecEnd->setVisibility(GlobalValue::HiddenVisibility); - IRBuilder<> IRB(M.getContext()); - if (!TargetTriple.isOSBinFormatCOFF()) - return std::make_pair(SecStart, SecEnd); - - // Account for the fact that on windows-msvc __start_* symbols actually - // point to a uint64_t before the start of the array. - auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy); - auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr, - ConstantInt::get(IntptrTy, sizeof(uint64_t))); - return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEnd); - -} - -Function *ModuleSanitizerCoverageAFL::CreateInitCallsForSections( - Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty, - const char *Section) { - - auto SecStartEnd = CreateSecStartEnd(M, Section, Ty); - auto SecStart = SecStartEnd.first; - auto SecEnd = SecStartEnd.second; - Function *CtorFunc; - std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions( - M, CtorName, InitFunctionName, {Ty, Ty}, {SecStart, SecEnd}); - assert(CtorFunc->getName() == CtorName); - - if (TargetTriple.supportsCOMDAT()) { - - // Use comdat to dedup CtorFunc. - CtorFunc->setComdat(M.getOrInsertComdat(CtorName)); - appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority, CtorFunc); - - } else { - - appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority); - - } - - if (TargetTriple.isOSBinFormatCOFF()) { - - // In COFF files, if the contructors are set as COMDAT (they are because - // COFF supports COMDAT) and the linker flag /OPT:REF (strip unreferenced - // functions and data) is used, the constructors get stripped. To prevent - // this, give the constructors weak ODR linkage and ensure the linker knows - // to include the sancov constructor. This way the linker can deduplicate - // the constructors but always leave one copy. - CtorFunc->setLinkage(GlobalValue::WeakODRLinkage); - appendToUsed(M, CtorFunc); - - } - - return CtorFunc; - -} - -bool ModuleSanitizerCoverageAFL::instrumentModule( - Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { - - setvbuf(stdout, NULL, _IONBF, 0); - if (getenv("AFL_DEBUG")) debug = 1; - - if ((isatty(2) && !getenv("AFL_QUIET")) || debug) { - - SAYF(cCYA "SanitizerCoveragePCGUARD" VERSION cRST "\n"); - - } else - - be_quiet = 1; - - skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO"); - use_threadsafe_counters = getenv("AFL_LLVM_THREADSAFE_INST"); - - initInstrumentList(); - scanForDangerousFunctions(&M); - - if (debug) { - - fprintf(stderr, - "SANCOV: covtype:%u indirect:%d stack:%d noprune:%d " - "createtable:%d tracepcguard:%d tracepc:%d\n", - Options.CoverageType, Options.IndirectCalls == true ? 1 : 0, - Options.StackDepth == true ? 1 : 0, Options.NoPrune == true ? 1 : 0, - // Options.InlineBoolFlag == true ? 1 : 0, - Options.PCTable == true ? 1 : 0, - Options.TracePCGuard == true ? 1 : 0, - Options.TracePC == true ? 1 : 0); - - } - - if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) return false; - C = &(M.getContext()); - DL = &M.getDataLayout(); - CurModule = &M; - CurModuleUniqueId = getUniqueModuleId(CurModule); - TargetTriple = Triple(M.getTargetTriple()); - FunctionGuardArray = nullptr; - Function8bitCounterArray = nullptr; - FunctionBoolArray = nullptr; - FunctionPCsArray = nullptr; - IntptrTy = Type::getIntNTy(*C, DL->getPointerSizeInBits()); - IntptrPtrTy = PointerType::getUnqual(IntptrTy); - Type * VoidTy = Type::getVoidTy(*C); - IRBuilder<> IRB(*C); - Int64PtrTy = PointerType::getUnqual(IRB.getInt64Ty()); - Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); - Int8PtrTy = PointerType::getUnqual(IRB.getInt8Ty()); - Int1PtrTy = PointerType::getUnqual(IRB.getInt1Ty()); - Int64Ty = IRB.getInt64Ty(); - Int32Ty = IRB.getInt32Ty(); - Int16Ty = IRB.getInt16Ty(); - Int8Ty = IRB.getInt8Ty(); - Int1Ty = IRB.getInt1Ty(); - LLVMContext &Ctx = M.getContext(); - - AFLMapPtr = - new GlobalVariable(M, PointerType::get(Int8Ty, 0), false, - GlobalValue::ExternalLinkage, 0, "__afl_area_ptr"); - One = ConstantInt::get(IntegerType::getInt8Ty(Ctx), 1); - Zero = ConstantInt::get(IntegerType::getInt8Ty(Ctx), 0); - - SanCovTracePCIndir = - M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy); - // Make sure smaller parameters are zero-extended to i64 if required by the - // target ABI. - AttributeList SanCovTraceCmpZeroExtAL; - SanCovTraceCmpZeroExtAL = - SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 0, Attribute::ZExt); - SanCovTraceCmpZeroExtAL = - SanCovTraceCmpZeroExtAL.addParamAttribute(*C, 1, Attribute::ZExt); - - SanCovTraceCmpFunction[0] = - M.getOrInsertFunction(SanCovTraceCmp1, SanCovTraceCmpZeroExtAL, VoidTy, - IRB.getInt8Ty(), IRB.getInt8Ty()); - SanCovTraceCmpFunction[1] = - M.getOrInsertFunction(SanCovTraceCmp2, SanCovTraceCmpZeroExtAL, VoidTy, - IRB.getInt16Ty(), IRB.getInt16Ty()); - SanCovTraceCmpFunction[2] = - M.getOrInsertFunction(SanCovTraceCmp4, SanCovTraceCmpZeroExtAL, VoidTy, - IRB.getInt32Ty(), IRB.getInt32Ty()); - SanCovTraceCmpFunction[3] = - M.getOrInsertFunction(SanCovTraceCmp8, VoidTy, Int64Ty, Int64Ty); - - SanCovTraceConstCmpFunction[0] = M.getOrInsertFunction( - SanCovTraceConstCmp1, SanCovTraceCmpZeroExtAL, VoidTy, Int8Ty, Int8Ty); - SanCovTraceConstCmpFunction[1] = M.getOrInsertFunction( - SanCovTraceConstCmp2, SanCovTraceCmpZeroExtAL, VoidTy, Int16Ty, Int16Ty); - SanCovTraceConstCmpFunction[2] = M.getOrInsertFunction( - SanCovTraceConstCmp4, SanCovTraceCmpZeroExtAL, VoidTy, Int32Ty, Int32Ty); - SanCovTraceConstCmpFunction[3] = - M.getOrInsertFunction(SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty); - - { - - AttributeList AL; - AL = AL.addParamAttribute(*C, 0, Attribute::ZExt); - SanCovTraceDivFunction[0] = - M.getOrInsertFunction(SanCovTraceDiv4, AL, VoidTy, IRB.getInt32Ty()); - - } - - SanCovTraceDivFunction[1] = - M.getOrInsertFunction(SanCovTraceDiv8, VoidTy, Int64Ty); - SanCovTraceGepFunction = - M.getOrInsertFunction(SanCovTraceGep, VoidTy, IntptrTy); - SanCovTraceSwitchFunction = - M.getOrInsertFunction(SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy); - - Constant *SanCovLowestStackConstant = - M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy); - SanCovLowestStack = dyn_cast(SanCovLowestStackConstant); - if (!SanCovLowestStack) { - - C->emitError(StringRef("'") + SanCovLowestStackName + - "' should not be declared by the user"); - return true; - - } - - SanCovLowestStack->setThreadLocalMode( - GlobalValue::ThreadLocalMode::InitialExecTLSModel); - if (Options.StackDepth && !SanCovLowestStack->isDeclaration()) - SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy)); - - SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy); - SanCovTracePCGuard = - M.getOrInsertFunction(SanCovTracePCGuardName, VoidTy, Int32PtrTy); - - for (auto &F : M) - instrumentFunction(F, DTCallback, PDTCallback); - - Function *Ctor = nullptr; - - if (FunctionGuardArray) - Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName, - SanCovTracePCGuardInitName, Int32PtrTy, - SanCovGuardsSectionName); - if (Function8bitCounterArray) - Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName, - SanCov8bitCountersInitName, Int8PtrTy, - SanCovCountersSectionName); - if (FunctionBoolArray) { - - Ctor = CreateInitCallsForSections(M, SanCovModuleCtorBoolFlagName, - SanCovBoolFlagInitName, Int1PtrTy, - SanCovBoolFlagSectionName); - - } - - if (Ctor && Options.PCTable) { - - auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy); - FunctionCallee InitFunction = declareSanitizerInitFunction( - M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy}); - IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator()); - IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second}); - - } - - // We don't reference these arrays directly in any of our runtime functions, - // so we need to prevent them from being dead stripped. - if (TargetTriple.isOSBinFormatMachO()) appendToUsed(M, GlobalsToAppendToUsed); - appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed); - - if (!be_quiet) { - - if (!instr) - WARNF("No instrumentation targets found."); - else { - - char modeline[100]; - snprintf(modeline, sizeof(modeline), "%s%s%s%s%s%s", - getenv("AFL_HARDEN") ? "hardened" : "non-hardened", - getenv("AFL_USE_ASAN") ? ", ASAN" : "", - getenv("AFL_USE_MSAN") ? ", MSAN" : "", - getenv("AFL_USE_TSAN") ? ", TSAN" : "", - getenv("AFL_USE_CFISAN") ? ", CFISAN" : "", - getenv("AFL_USE_UBSAN") ? ", UBSAN" : ""); - OKF("Instrumented %u locations with no collisions (%s mode) of which are " - "%u handled and %u unhandled selects.", - instr, modeline, selects, unhandled); - - } - - } - - return true; - -} - -// True if block has successors and it dominates all of them. -bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) { - - if (succ_begin(BB) == succ_end(BB)) return false; - - for (const BasicBlock *SUCC : make_range(succ_begin(BB), succ_end(BB))) { - - if (!DT->dominates(BB, SUCC)) return false; - - } - - return true; - -} - -// True if block has predecessors and it postdominates all of them. -bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree *PDT) { - - if (pred_begin(BB) == pred_end(BB)) return false; - - for (const BasicBlock *PRED : make_range(pred_begin(BB), pred_end(BB))) { - - if (!PDT->dominates(BB, PRED)) return false; - - } - - return true; - -} - -bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, - const DominatorTree * DT, - const PostDominatorTree * PDT, - const SanitizerCoverageOptions &Options) { - - // Don't insert coverage for blocks containing nothing but unreachable: we - // will never call __sanitizer_cov() for them, so counting them in - // NumberOfInstrumentedBlocks() might complicate calculation of code coverage - // percentage. Also, unreachable instructions frequently have no debug - // locations. - if (isa(BB->getFirstNonPHIOrDbgOrLifetime())) return false; - - // Don't insert coverage into blocks without a valid insertion point - // (catchswitch blocks). - if (BB->getFirstInsertionPt() == BB->end()) return false; - - if (Options.NoPrune || &F.getEntryBlock() == BB) return true; - - if (Options.CoverageType == SanitizerCoverageOptions::SCK_Function && - &F.getEntryBlock() != BB) - return false; - - // Do not instrument full dominators, or full post-dominators with multiple - // predecessors. - return !isFullDominator(BB, DT) && - !(isFullPostDominator(BB, PDT) && !BB->getSinglePredecessor()); - -} - -// Returns true iff From->To is a backedge. -// A twist here is that we treat From->To as a backedge if -// * To dominates From or -// * To->UniqueSuccessor dominates From -bool IsBackEdge(BasicBlock *From, BasicBlock *To, const DominatorTree *DT) { - - if (DT->dominates(To, From)) return true; - if (auto Next = To->getUniqueSuccessor()) - if (DT->dominates(Next, From)) return true; - return false; - -} - -// Prunes uninteresting Cmp instrumentation: -// * CMP instructions that feed into loop backedge branch. -// -// Note that Cmp pruning is controlled by the same flag as the -// BB pruning. -bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT, - const SanitizerCoverageOptions &Options) { - - if (!Options.NoPrune) - if (CMP->hasOneUse()) - if (auto BR = dyn_cast(CMP->user_back())) - for (BasicBlock *B : BR->successors()) - if (IsBackEdge(BR->getParent(), B, DT)) return false; - return true; - -} - -void ModuleSanitizerCoverageAFL::instrumentFunction( - Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { - - if (F.empty()) return; - if (!isInInstrumentList(&F, FMNAME)) return; - - if (F.getName().find(".module_ctor") != std::string::npos) - return; // Should not instrument sanitizer init functions. - if (F.getName().startswith("__sanitizer_")) - return; // Don't instrument __sanitizer_* callbacks. - // Don't touch available_externally functions, their actual body is elewhere. - if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage) return; - // Don't instrument MSVC CRT configuration helpers. They may run before normal - // initialization. - if (F.getName() == "__local_stdio_printf_options" || - F.getName() == "__local_stdio_scanf_options") - return; - if (isa(F.getEntryBlock().getTerminator())) return; - // Don't instrument functions using SEH for now. Splitting basic blocks like - // we do for coverage breaks WinEHPrepare. - // FIXME: Remove this when SEH no longer uses landingpad pattern matching. - if (F.hasPersonalityFn() && - isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) - return; - if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge) - SplitAllCriticalEdges( - F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests()); - SmallVector IndirCalls; - SmallVector BlocksToInstrument; - SmallVector CmpTraceTargets; - SmallVector SwitchTraceTargets; - SmallVector DivTraceTargets; - SmallVector GepTraceTargets; - - const DominatorTree * DT = DTCallback(F); - const PostDominatorTree *PDT = PDTCallback(F); - bool IsLeafFunc = true; - - for (auto &BB : F) { - - if (shouldInstrumentBlock(F, &BB, DT, PDT, Options)) - BlocksToInstrument.push_back(&BB); - for (auto &Inst : BB) { - - if (Options.IndirectCalls) { - - CallBase *CB = dyn_cast(&Inst); - if (CB && !CB->getCalledFunction()) IndirCalls.push_back(&Inst); - - } - - if (Options.TraceCmp) { - - if (ICmpInst *CMP = dyn_cast(&Inst)) - if (IsInterestingCmp(CMP, DT, Options)) - CmpTraceTargets.push_back(&Inst); - if (isa(&Inst)) SwitchTraceTargets.push_back(&Inst); - - } - - if (Options.TraceDiv) - if (BinaryOperator *BO = dyn_cast(&Inst)) - if (BO->getOpcode() == Instruction::SDiv || - BO->getOpcode() == Instruction::UDiv) - DivTraceTargets.push_back(BO); - if (Options.TraceGep) - if (GetElementPtrInst *GEP = dyn_cast(&Inst)) - GepTraceTargets.push_back(GEP); - if (Options.StackDepth) - if (isa(Inst) || - (isa(Inst) && !isa(Inst))) - IsLeafFunc = false; - - } - - } - - InjectCoverage(F, BlocksToInstrument, IsLeafFunc); - InjectCoverageForIndirectCalls(F, IndirCalls); - InjectTraceForCmp(F, CmpTraceTargets); - InjectTraceForSwitch(F, SwitchTraceTargets); - InjectTraceForDiv(F, DivTraceTargets); - InjectTraceForGep(F, GepTraceTargets); - -} - -GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection( - size_t NumElements, Function &F, Type *Ty, const char *Section) { - - ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); - auto Array = new GlobalVariable( - *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage, - Constant::getNullValue(ArrayTy), "__sancov_gen_"); - -#if LLVM_VERSION_MAJOR >= 13 - if (TargetTriple.supportsCOMDAT() && - (TargetTriple.isOSBinFormatELF() || !F.isInterposable())) - if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple)) - Array->setComdat(Comdat); -#else - if (TargetTriple.supportsCOMDAT() && !F.isInterposable()) - if (auto Comdat = - GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId)) - Array->setComdat(Comdat); -#endif - - Array->setSection(getSectionName(Section)); -#if (LLVM_VERSION_MAJOR >= 11) || \ - (LLVM_VERSION_MAJOR == 10 && LLVM_VERSION_MINOR >= 1) - Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize())); -#else - Array->setAlignment(Align(4)); // cheating -#endif - GlobalsToAppendToUsed.push_back(Array); - GlobalsToAppendToCompilerUsed.push_back(Array); - MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F)); - Array->addMetadata(LLVMContext::MD_associated, *MD); - - return Array; - -} - -GlobalVariable *ModuleSanitizerCoverageAFL::CreatePCArray( - Function &F, ArrayRef AllBlocks) { - - size_t N = AllBlocks.size(); - assert(N); - SmallVector PCs; - IRBuilder<> IRB(&*F.getEntryBlock().getFirstInsertionPt()); - for (size_t i = 0; i < N; i++) { - - if (&F.getEntryBlock() == AllBlocks[i]) { - - PCs.push_back((Constant *)IRB.CreatePointerCast(&F, IntptrPtrTy)); - PCs.push_back((Constant *)IRB.CreateIntToPtr( - ConstantInt::get(IntptrTy, 1), IntptrPtrTy)); - - } else { - - PCs.push_back((Constant *)IRB.CreatePointerCast( - BlockAddress::get(AllBlocks[i]), IntptrPtrTy)); - PCs.push_back((Constant *)IRB.CreateIntToPtr( - ConstantInt::get(IntptrTy, 0), IntptrPtrTy)); - - } - - } - - auto *PCArray = CreateFunctionLocalArrayInSection(N * 2, F, IntptrPtrTy, - SanCovPCsSectionName); - PCArray->setInitializer( - ConstantArray::get(ArrayType::get(IntptrPtrTy, N * 2), PCs)); - PCArray->setConstant(true); - - return PCArray; - -} - -void ModuleSanitizerCoverageAFL::CreateFunctionLocalArrays( - Function &F, ArrayRef AllBlocks, uint32_t special) { - - if (Options.TracePCGuard) - FunctionGuardArray = CreateFunctionLocalArrayInSection( - AllBlocks.size() + special, F, Int32Ty, SanCovGuardsSectionName); - - if (Options.Inline8bitCounters) - Function8bitCounterArray = CreateFunctionLocalArrayInSection( - AllBlocks.size(), F, Int8Ty, SanCovCountersSectionName); - /* - if (Options.InlineBoolFlag) - FunctionBoolArray = CreateFunctionLocalArrayInSection( - AllBlocks.size(), F, Int1Ty, SanCovBoolFlagSectionName); - */ - if (Options.PCTable) FunctionPCsArray = CreatePCArray(F, AllBlocks); - -} - -bool ModuleSanitizerCoverageAFL::InjectCoverage( - Function &F, ArrayRef AllBlocks, bool IsLeafFunc) { - - uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0; - - for (auto &BB : F) { - - for (auto &IN : BB) { - - CallInst *callInst = nullptr; - - if ((callInst = dyn_cast(&IN))) { - - Function *Callee = callInst->getCalledFunction(); - if (!Callee) continue; - if (callInst->getCallingConv() != llvm::CallingConv::C) continue; - StringRef FuncName = Callee->getName(); - if (!FuncName.compare(StringRef("dlopen")) || - !FuncName.compare(StringRef("_dlopen"))) { - - fprintf(stderr, - "WARNING: dlopen() detected. To have coverage for a library " - "that your target dlopen()'s this must either happen before " - "__AFL_INIT() or you must use AFL_PRELOAD to preload all " - "dlopen()'ed libraries!\n"); - continue; - - } - - if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue; - - cnt_cov++; - - } - - SelectInst *selectInst = nullptr; - - if ((selectInst = dyn_cast(&IN))) { - - Value *c = selectInst->getCondition(); - auto t = c->getType(); - if (t->getTypeID() == llvm::Type::IntegerTyID) { - - cnt_sel++; - cnt_sel_inc += 2; - - } - -#if (LLVM_VERSION_MAJOR >= 12) - else if (t->getTypeID() == llvm::Type::FixedVectorTyID) { - - FixedVectorType *tt = dyn_cast(t); - if (tt) { - - cnt_sel++; - cnt_sel_inc += tt->getElementCount().getKnownMinValue(); - - } - - } - -#endif - - } - - } - - } - - /* Create PCGUARD array */ - CreateFunctionLocalArrays(F, AllBlocks, cnt_cov + cnt_sel_inc); - selects += cnt_sel; - - uint32_t special = 0, local_selects = 0, skip_next = 0; - - for (auto &BB : F) { - - for (auto &IN : BB) { - - CallInst *callInst = nullptr; - - /* - std::string errMsg; - raw_string_ostream os(errMsg); - IN.print(os); - fprintf(stderr, "X: %s\n", os.str().c_str()); - */ - if ((callInst = dyn_cast(&IN))) { - - Function *Callee = callInst->getCalledFunction(); - if (!Callee) continue; - if (callInst->getCallingConv() != llvm::CallingConv::C) continue; - StringRef FuncName = Callee->getName(); - if (FuncName.compare(StringRef("__afl_coverage_interesting"))) continue; - - IRBuilder<> IRB(callInst); - - Value *GuardPtr = IRB.CreateIntToPtr( - IRB.CreateAdd( - IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get(IntptrTy, (++special + AllBlocks.size()) * 4)), - Int32PtrTy); - - LoadInst *Idx = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Idx); - - callInst->setOperand(1, Idx); - - } - - SelectInst *selectInst = nullptr; - - if (!skip_next && (selectInst = dyn_cast(&IN))) { - - uint32_t vector_cnt = 0; - Value * condition = selectInst->getCondition(); - Value * result; - auto t = condition->getType(); - IRBuilder<> IRB(selectInst->getNextNode()); - - if (t->getTypeID() == llvm::Type::IntegerTyID) { - - auto GuardPtr1 = IRB.CreateIntToPtr( - IRB.CreateAdd( - IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get( - IntptrTy, - (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), - Int32PtrTy); - - auto GuardPtr2 = IRB.CreateIntToPtr( - IRB.CreateAdd( - IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get( - IntptrTy, - (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), - Int32PtrTy); - - result = IRB.CreateSelect(condition, GuardPtr1, GuardPtr2); - - } else - -#if LLVM_VERSION_MAJOR >= 14 - if (t->getTypeID() == llvm::Type::FixedVectorTyID) { - - FixedVectorType *tt = dyn_cast(t); - if (tt) { - - uint32_t elements = tt->getElementCount().getFixedValue(); - vector_cnt = elements; - if (elements) { - - FixedVectorType *GuardPtr1 = - FixedVectorType::get(Int32PtrTy, elements); - FixedVectorType *GuardPtr2 = - FixedVectorType::get(Int32PtrTy, elements); - Value *x, *y; - - Value *val1 = IRB.CreateIntToPtr( - IRB.CreateAdd( - IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get( - IntptrTy, - (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), - Int32PtrTy); - x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0); - - Value *val2 = IRB.CreateIntToPtr( - IRB.CreateAdd( - IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get( - IntptrTy, - (cnt_cov + ++local_selects + AllBlocks.size()) * 4)), - Int32PtrTy); - y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0); - - for (uint64_t i = 1; i < elements; i++) { - - val1 = IRB.CreateIntToPtr( - IRB.CreateAdd( - IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects + - AllBlocks.size()) * - 4)), - Int32PtrTy); - x = IRB.CreateInsertElement(x, val1, i); - - val2 = IRB.CreateIntToPtr( - IRB.CreateAdd( - IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects + - AllBlocks.size()) * - 4)), - Int32PtrTy); - y = IRB.CreateInsertElement(y, val2, i); - - } - - /* - std::string errMsg; - raw_string_ostream os(errMsg); - x->print(os); - fprintf(stderr, "X: %s\n", os.str().c_str()); - */ - result = IRB.CreateSelect(condition, x, y); - - } - - } - - } else - -#endif - { - - unhandled++; - continue; - - } - - uint32_t vector_cur = 0; - - /* Load SHM pointer */ - - LoadInst *MapPtr = - IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr); - - /* - std::string errMsg; - raw_string_ostream os(errMsg); - result->print(os); - fprintf(stderr, "X: %s\n", os.str().c_str()); - */ - - while (1) { - - /* Get CurLoc */ - LoadInst *CurLoc = nullptr; - Value * MapPtrIdx = nullptr; - - /* Load counter for CurLoc */ - if (!vector_cnt) { - - CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), result); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(CurLoc); - MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc); - - } else { - - auto element = IRB.CreateExtractElement(result, vector_cur++); - auto elementptr = IRB.CreateIntToPtr(element, Int32PtrTy); - auto elementld = IRB.CreateLoad(IRB.getInt32Ty(), elementptr); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(elementld); - MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, elementld); - - } - - if (use_threadsafe_counters) { - - IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One, -#if LLVM_VERSION_MAJOR >= 13 - llvm::MaybeAlign(1), -#endif - llvm::AtomicOrdering::Monotonic); - - } else { - - LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Counter); - - /* Update bitmap */ - - Value *Incr = IRB.CreateAdd(Counter, One); - - if (skip_nozero == NULL) { - - auto cf = IRB.CreateICmpEQ(Incr, Zero); - auto carry = IRB.CreateZExt(cf, Int8Ty); - Incr = IRB.CreateAdd(Incr, carry); - - } - - StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx); - - } - - if (!vector_cnt) { - - vector_cnt = 2; - break; - - } else if (vector_cnt == vector_cur) { - - break; - - } - - } - - skip_next = 1; - instr += vector_cnt; - - } else { - - skip_next = 0; - - } - - } - - } - - if (AllBlocks.empty() && !special && !local_selects) return false; - - if (!AllBlocks.empty()) - for (size_t i = 0, N = AllBlocks.size(); i < N; i++) - InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc); - - return true; - -} - -// On every indirect call we call a run-time function -// __sanitizer_cov_indir_call* with two parameters: -// - callee address, -// - global cache array that contains CacheSize pointers (zero-initialized). -// The cache is used to speed up recording the caller-callee pairs. -// The address of the caller is passed implicitly via caller PC. -// CacheSize is encoded in the name of the run-time function. -void ModuleSanitizerCoverageAFL::InjectCoverageForIndirectCalls( - Function &F, ArrayRef IndirCalls) { - - if (IndirCalls.empty()) return; - for (auto I : IndirCalls) { - - IRBuilder<> IRB(I); - CallBase & CB = cast(*I); - Value * Callee = CB.getCalledOperand(); - if (isa(Callee)) continue; - IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy)); - - } - -} - -// For every switch statement we insert a call: -// __sanitizer_cov_trace_switch(CondValue, -// {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... }) - -void ModuleSanitizerCoverageAFL::InjectTraceForSwitch( - Function &, ArrayRef SwitchTraceTargets) { - - for (auto I : SwitchTraceTargets) { - - if (SwitchInst *SI = dyn_cast(I)) { - - IRBuilder<> IRB(I); - SmallVector Initializers; - Value * Cond = SI->getCondition(); - if (Cond->getType()->getScalarSizeInBits() > - Int64Ty->getScalarSizeInBits()) - continue; - Initializers.push_back(ConstantInt::get(Int64Ty, SI->getNumCases())); - Initializers.push_back( - ConstantInt::get(Int64Ty, Cond->getType()->getScalarSizeInBits())); - if (Cond->getType()->getScalarSizeInBits() < - Int64Ty->getScalarSizeInBits()) - Cond = IRB.CreateIntCast(Cond, Int64Ty, false); - for (auto It : SI->cases()) { - - Constant *C = It.getCaseValue(); - if (C->getType()->getScalarSizeInBits() < - Int64Ty->getScalarSizeInBits()) - C = ConstantExpr::getCast(CastInst::ZExt, It.getCaseValue(), Int64Ty); - Initializers.push_back(C); - - } - - llvm::sort(drop_begin(Initializers, 2), - [](const Constant *A, const Constant *B) { - - return cast(A)->getLimitedValue() < - cast(B)->getLimitedValue(); - - }); - - ArrayType *ArrayOfInt64Ty = ArrayType::get(Int64Ty, Initializers.size()); - GlobalVariable *GV = new GlobalVariable( - *CurModule, ArrayOfInt64Ty, false, GlobalVariable::InternalLinkage, - ConstantArray::get(ArrayOfInt64Ty, Initializers), - "__sancov_gen_cov_switch_values"); - IRB.CreateCall(SanCovTraceSwitchFunction, - {Cond, IRB.CreatePointerCast(GV, Int64PtrTy)}); - - } - - } - -} - -void ModuleSanitizerCoverageAFL::InjectTraceForDiv( - Function &, ArrayRef DivTraceTargets) { - - for (auto BO : DivTraceTargets) { - - IRBuilder<> IRB(BO); - Value * A1 = BO->getOperand(1); - if (isa(A1)) continue; - if (!A1->getType()->isIntegerTy()) continue; - uint64_t TypeSize = DL->getTypeStoreSizeInBits(A1->getType()); - int CallbackIdx = TypeSize == 32 ? 0 : TypeSize == 64 ? 1 : -1; - if (CallbackIdx < 0) continue; - auto Ty = Type::getIntNTy(*C, TypeSize); - IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx], - {IRB.CreateIntCast(A1, Ty, true)}); - - } - -} - -void ModuleSanitizerCoverageAFL::InjectTraceForGep( - Function &, ArrayRef GepTraceTargets) { - - for (auto GEP : GepTraceTargets) { - - IRBuilder<> IRB(GEP); - for (Use &Idx : GEP->indices()) - if (!isa(Idx) && Idx->getType()->isIntegerTy()) - IRB.CreateCall(SanCovTraceGepFunction, - {IRB.CreateIntCast(Idx, IntptrTy, true)}); - - } - -} - -void ModuleSanitizerCoverageAFL::InjectTraceForCmp( - Function &, ArrayRef CmpTraceTargets) { - - for (auto I : CmpTraceTargets) { - - if (ICmpInst *ICMP = dyn_cast(I)) { - - IRBuilder<> IRB(ICMP); - Value * A0 = ICMP->getOperand(0); - Value * A1 = ICMP->getOperand(1); - if (!A0->getType()->isIntegerTy()) continue; - uint64_t TypeSize = DL->getTypeStoreSizeInBits(A0->getType()); - int CallbackIdx = TypeSize == 8 ? 0 - : TypeSize == 16 ? 1 - : TypeSize == 32 ? 2 - : TypeSize == 64 ? 3 - : -1; - if (CallbackIdx < 0) continue; - // __sanitizer_cov_trace_cmp((type_size << 32) | predicate, A0, A1); - auto CallbackFunc = SanCovTraceCmpFunction[CallbackIdx]; - bool FirstIsConst = isa(A0); - bool SecondIsConst = isa(A1); - // If both are const, then we don't need such a comparison. - if (FirstIsConst && SecondIsConst) continue; - // If only one is const, then make it the first callback argument. - if (FirstIsConst || SecondIsConst) { - - CallbackFunc = SanCovTraceConstCmpFunction[CallbackIdx]; - if (SecondIsConst) std::swap(A0, A1); - - } - - auto Ty = Type::getIntNTy(*C, TypeSize); - IRB.CreateCall(CallbackFunc, {IRB.CreateIntCast(A0, Ty, true), - IRB.CreateIntCast(A1, Ty, true)}); - - } - - } - -} - -void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function & F, - BasicBlock &BB, - size_t Idx, - bool IsLeafFunc) { - - BasicBlock::iterator IP = BB.getFirstInsertionPt(); - bool IsEntryBB = &BB == &F.getEntryBlock(); - - if (IsEntryBB) { - - // Keep allocas and llvm.localescape calls in the entry block. Even - // if we aren't splitting the block, it's nice for allocas to be before - // calls. - IP = PrepareToSplitEntryBlock(BB, IP); - - } - - IRBuilder<> IRB(&*IP); - - if (Options.TracePC) { - - IRB.CreateCall(SanCovTracePC); - // ->setCannotMerge(); // gets the PC using GET_CALLER_PC. - - } - - if (Options.TracePCGuard) { - - /* Get CurLoc */ - - Value *GuardPtr = IRB.CreateIntToPtr( - IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), - ConstantInt::get(IntptrTy, Idx * 4)), - Int32PtrTy); - - LoadInst *CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(CurLoc); - - /* Load SHM pointer */ - - LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr); - - /* Load counter for CurLoc */ - - Value *MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc); - - if (use_threadsafe_counters) { - - IRB.CreateAtomicRMW(llvm::AtomicRMWInst::BinOp::Add, MapPtrIdx, One, -#if LLVM_VERSION_MAJOR >= 13 - llvm::MaybeAlign(1), -#endif - llvm::AtomicOrdering::Monotonic); - - } else { - - LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Counter); - - /* Update bitmap */ - - Value *Incr = IRB.CreateAdd(Counter, One); - - if (skip_nozero == NULL) { - - auto cf = IRB.CreateICmpEQ(Incr, Zero); - auto carry = IRB.CreateZExt(cf, Int8Ty); - Incr = IRB.CreateAdd(Incr, carry); - - } - - StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx); - - } - - // done :) - - // IRB.CreateCall(SanCovTracePCGuard, Offset)->setCannotMerge(); - // IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge(); - ++instr; - - } - - if (Options.Inline8bitCounters) { - - auto CounterPtr = IRB.CreateGEP( - Function8bitCounterArray->getValueType(), Function8bitCounterArray, - {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)}); - auto Load = IRB.CreateLoad(Int8Ty, CounterPtr); - auto Inc = IRB.CreateAdd(Load, ConstantInt::get(Int8Ty, 1)); - auto Store = IRB.CreateStore(Inc, CounterPtr); - SetNoSanitizeMetadata(Load); - SetNoSanitizeMetadata(Store); - - } - - /* - if (Options.InlineBoolFlag) { - - auto FlagPtr = IRB.CreateGEP( - FunctionBoolArray->getValueType(), FunctionBoolArray, - {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)}); - auto Load = IRB.CreateLoad(Int1Ty, FlagPtr); - auto ThenTerm = - SplitBlockAndInsertIfThen(IRB.CreateIsNull(Load), &*IP, false); - IRBuilder<> ThenIRB(ThenTerm); - auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr); - SetNoSanitizeMetadata(Load); - SetNoSanitizeMetadata(Store); - - } - - */ - - if (Options.StackDepth && IsEntryBB && !IsLeafFunc) { - - // Check stack depth. If it's the deepest so far, record it. - Module * M = F.getParent(); - Function *GetFrameAddr = Intrinsic::getDeclaration( - M, Intrinsic::frameaddress, - IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace())); - auto FrameAddrPtr = - IRB.CreateCall(GetFrameAddr, {Constant::getNullValue(Int32Ty)}); - auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy); - auto LowestStack = IRB.CreateLoad(IntptrTy, SanCovLowestStack); - auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack); - auto ThenTerm = SplitBlockAndInsertIfThen(IsStackLower, &*IP, false); - IRBuilder<> ThenIRB(ThenTerm); - auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack); - SetNoSanitizeMetadata(LowestStack); - SetNoSanitizeMetadata(Store); - - } - -} - -std::string ModuleSanitizerCoverageAFL::getSectionName( - const std::string &Section) const { - - if (TargetTriple.isOSBinFormatCOFF()) { - - if (Section == SanCovCountersSectionName) return ".SCOV$CM"; - if (Section == SanCovBoolFlagSectionName) return ".SCOV$BM"; - if (Section == SanCovPCsSectionName) return ".SCOVP$M"; - return ".SCOV$GM"; // For SanCovGuardsSectionName. - - } - - if (TargetTriple.isOSBinFormatMachO()) return "__DATA,__" + Section; - return "__" + Section; - -} - -std::string ModuleSanitizerCoverageAFL::getSectionStart( - const std::string &Section) const { - - if (TargetTriple.isOSBinFormatMachO()) - return "\1section$start$__DATA$__" + Section; - return "__start___" + Section; - -} - -std::string ModuleSanitizerCoverageAFL::getSectionEnd( - const std::string &Section) const { - - if (TargetTriple.isOSBinFormatMachO()) - return "\1section$end$__DATA$__" + Section; - return "__stop___" + Section; - -} - -#if 0 - -char ModuleSanitizerCoverageLegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", - "Pass for instrumenting coverage on functions", false, - false) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) -INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov", - "Pass for instrumenting coverage on functions", false, - false) -ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( - const SanitizerCoverageOptions &Options, - const std::vector &AllowlistFiles, - const std::vector &BlocklistFiles) { - - return new ModuleSanitizerCoverageLegacyPass(Options, AllowlistFiles, - BlocklistFiles); - -} - -#endif - diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index f87bc068..b837a033 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -42,6 +42,9 @@ #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" +#include "llvm/Passes/PassPlugin.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/IR/PassManager.h" #include "config.h" #include "debug.h" @@ -121,21 +124,18 @@ using DomTreeCallback = function_ref; using PostDomTreeCallback = function_ref; -class ModuleSanitizerCoverage { +class ModuleSanitizerCoverageAFL + : public PassInfoMixin { public: - ModuleSanitizerCoverage( - const SanitizerCoverageOptions &Options = SanitizerCoverageOptions() -#if (LLVM_VERSION_MAJOR >= 11) - , - const SpecialCaseList *Allowlist = nullptr, - const SpecialCaseList *Blocklist = nullptr -#endif - ) + ModuleSanitizerCoverageAFL( + const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : Options(OverrideFromCL(Options)) { } + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); + bool instrumentModule(Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback); @@ -213,15 +213,7 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { public: ModuleSanitizerCoverageLegacyPass( - const SanitizerCoverageOptions &Options = SanitizerCoverageOptions() -#if LLVM_VERSION_MAJOR >= 11 - , - const std::vector &AllowlistFiles = - std::vector(), - const std::vector &BlocklistFiles = - std::vector() -#endif - ) + const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : ModulePass(ID), Options(Options) { initializeModuleSanitizerCoverageLegacyPassPass( @@ -231,12 +223,7 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { bool runOnModule(Module &M) override { - ModuleSanitizerCoverage ModuleSancov(Options -#if (LLVM_VERSION_MAJOR >= 11) - , - Allowlist.get(), Blocklist.get() -#endif - ); + ModuleSanitizerCoverageAFL ModuleSancov(Options); auto DTCallback = [this](Function &F) -> const DominatorTree * { return &this->getAnalysis(F).getDomTree(); @@ -271,24 +258,39 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { private: SanitizerCoverageOptions Options; - std::unique_ptr Allowlist; - std::unique_ptr Blocklist; - }; } // namespace -PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, - ModuleAnalysisManager &MAM) { +#if 1 + +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "SanitizerCoveragePCGUARD", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { - fprintf(stderr, "ModuleSanitizerCoveragePass::run is called!\n"); + MPM.addPass(ModuleSanitizerCoverageAFL()); + + }); + + }}; + +} - ModuleSanitizerCoverage ModuleSancov(Options -#if (LLVM_VERSION_MAJOR >= 11) - , - Allowlist.get(), Blocklist.get() #endif - ); + +PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module & M, + ModuleAnalysisManager &MAM) { + + ModuleSanitizerCoverageAFL ModuleSancov(Options); auto &FAM = MAM.getResult(M).getManager(); auto DTCallback = [&FAM](Function &F) -> const DominatorTree * { @@ -308,7 +310,7 @@ PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, } -std::pair ModuleSanitizerCoverage::CreateSecStartEnd( +std::pair ModuleSanitizerCoverageAFL::CreateSecStartEnd( Module &M, const char *Section, Type *Ty) { GlobalVariable *SecStart = new GlobalVariable( @@ -332,7 +334,7 @@ std::pair ModuleSanitizerCoverage::CreateSecStartEnd( } -Function *ModuleSanitizerCoverage::CreateInitCallsForSections( +Function *ModuleSanitizerCoverageAFL::CreateInitCallsForSections( Module &M, const char *CtorName, const char *InitFunctionName, Type *Ty, const char *Section) { @@ -373,7 +375,7 @@ Function *ModuleSanitizerCoverage::CreateInitCallsForSections( } -bool ModuleSanitizerCoverage::instrumentModule( +bool ModuleSanitizerCoverageAFL::instrumentModule( Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { setvbuf(stdout, NULL, _IONBF, 0); @@ -656,7 +658,7 @@ bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT, } -void ModuleSanitizerCoverage::instrumentFunction( +void ModuleSanitizerCoverageAFL::instrumentFunction( Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { if (F.empty()) return; @@ -742,7 +744,7 @@ void ModuleSanitizerCoverage::instrumentFunction( } -GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( +GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection( size_t NumElements, Function &F, Type *Ty, const char *Section) { ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); @@ -778,7 +780,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( } -GlobalVariable *ModuleSanitizerCoverage::CreatePCArray( +GlobalVariable *ModuleSanitizerCoverageAFL::CreatePCArray( Function &F, ArrayRef AllBlocks) { size_t N = AllBlocks.size(); @@ -814,7 +816,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreatePCArray( } -void ModuleSanitizerCoverage::CreateFunctionLocalArrays( +void ModuleSanitizerCoverageAFL::CreateFunctionLocalArrays( Function &F, ArrayRef AllBlocks, uint32_t special) { if (Options.TracePCGuard) @@ -833,9 +835,8 @@ void ModuleSanitizerCoverage::CreateFunctionLocalArrays( } -bool ModuleSanitizerCoverage::InjectCoverage(Function & F, - ArrayRef AllBlocks, - bool IsLeafFunc) { +bool ModuleSanitizerCoverageAFL::InjectCoverage( + Function &F, ArrayRef AllBlocks, bool IsLeafFunc) { uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0; @@ -938,7 +939,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, Int32PtrTy); LoadInst *Idx = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Idx); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Idx); callInst->setOperand(1, Idx); @@ -1060,7 +1061,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr); /* std::string errMsg; @@ -1079,7 +1080,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, if (!vector_cnt) { CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), result); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(CurLoc); MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc); } else { @@ -1087,7 +1088,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, auto element = IRB.CreateExtractElement(result, vector_cur++); auto elementptr = IRB.CreateIntToPtr(element, Int32PtrTy); auto elementld = IRB.CreateLoad(IRB.getInt32Ty(), elementptr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(elementld); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(elementld); MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, elementld); } @@ -1103,7 +1104,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, } else { LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Counter); /* Update bitmap */ @@ -1118,7 +1119,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, } StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx); } @@ -1165,7 +1166,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, // The cache is used to speed up recording the caller-callee pairs. // The address of the caller is passed implicitly via caller PC. // CacheSize is encoded in the name of the run-time function. -void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( +void ModuleSanitizerCoverageAFL::InjectCoverageForIndirectCalls( Function &F, ArrayRef IndirCalls) { if (IndirCalls.empty()) return; @@ -1185,7 +1186,7 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( // __sanitizer_cov_trace_switch(CondValue, // {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... }) -void ModuleSanitizerCoverage::InjectTraceForSwitch( +void ModuleSanitizerCoverageAFL::InjectTraceForSwitch( Function &, ArrayRef SwitchTraceTargets) { for (auto I : SwitchTraceTargets) { @@ -1236,7 +1237,7 @@ void ModuleSanitizerCoverage::InjectTraceForSwitch( } -void ModuleSanitizerCoverage::InjectTraceForDiv( +void ModuleSanitizerCoverageAFL::InjectTraceForDiv( Function &, ArrayRef DivTraceTargets) { for (auto BO : DivTraceTargets) { @@ -1256,7 +1257,7 @@ void ModuleSanitizerCoverage::InjectTraceForDiv( } -void ModuleSanitizerCoverage::InjectTraceForGep( +void ModuleSanitizerCoverageAFL::InjectTraceForGep( Function &, ArrayRef GepTraceTargets) { for (auto GEP : GepTraceTargets) { @@ -1271,7 +1272,7 @@ void ModuleSanitizerCoverage::InjectTraceForGep( } -void ModuleSanitizerCoverage::InjectTraceForCmp( +void ModuleSanitizerCoverageAFL::InjectTraceForCmp( Function &, ArrayRef CmpTraceTargets) { for (auto I : CmpTraceTargets) { @@ -1313,9 +1314,10 @@ void ModuleSanitizerCoverage::InjectTraceForCmp( } -void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, - size_t Idx, - bool IsLeafFunc) { +void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function & F, + BasicBlock &BB, + size_t Idx, + bool IsLeafFunc) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); bool IsEntryBB = &BB == &F.getEntryBlock(); @@ -1348,12 +1350,12 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, Int32PtrTy); LoadInst *CurLoc = IRB.CreateLoad(IRB.getInt32Ty(), GuardPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(CurLoc); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(CurLoc); /* Load SHM pointer */ LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr); /* Load counter for CurLoc */ @@ -1370,7 +1372,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(Counter); /* Update bitmap */ @@ -1385,7 +1387,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } StoreInst *StoreCtx = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreCtx); + ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(StoreCtx); } @@ -1450,7 +1452,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } -std::string ModuleSanitizerCoverage::getSectionName( +std::string ModuleSanitizerCoverageAFL::getSectionName( const std::string &Section) const { if (TargetTriple.isOSBinFormatCOFF()) { @@ -1467,7 +1469,7 @@ std::string ModuleSanitizerCoverage::getSectionName( } -std::string ModuleSanitizerCoverage::getSectionStart( +std::string ModuleSanitizerCoverageAFL::getSectionStart( const std::string &Section) const { if (TargetTriple.isOSBinFormatMachO()) @@ -1476,7 +1478,7 @@ std::string ModuleSanitizerCoverage::getSectionStart( } -std::string ModuleSanitizerCoverage::getSectionEnd( +std::string ModuleSanitizerCoverageAFL::getSectionEnd( const std::string &Section) const { if (TargetTriple.isOSBinFormatMachO()) @@ -1485,13 +1487,15 @@ std::string ModuleSanitizerCoverage::getSectionEnd( } +#if 0 + char ModuleSanitizerCoverageLegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancovAFL", +INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", "Pass for instrumenting coverage on functions", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass) -INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancovAFL", +INITIALIZE_PASS_END(ModuleSanitizerCoverageLegacyPass, "sancov", "Pass for instrumenting coverage on functions", false, false) ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( @@ -1504,3 +1508,5 @@ ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( } +#endif + diff --git a/src/afl-cc.c b/src/afl-cc.c index fae572f6..a7248325 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -624,11 +624,17 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { + #if LLVM_MAJOR >= 11 /* use new pass manager */ + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = alloc_printf( + "-fpass-plugin=%s/SanitizerCoveragePCGUARD.so", obj_path); + #else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/SanitizerCoveragePCGUARD.so", obj_path); + #endif } -- cgit 1.4.1 From e4f201707fdfbf9a36b6a48c16f75b0fef2c9e75 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 17 Mar 2022 14:35:15 +0100 Subject: make LTO pass work too plus some fixes --- GNUmakefile | 2 +- GNUmakefile.gcc_plugin | 4 ++-- GNUmakefile.llvm | 14 +++++++------- instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 +- src/afl-cc.c | 3 +++ src/afl-ld-lto.c | 4 ++-- 6 files changed, 16 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/GNUmakefile b/GNUmakefile index 6392fceb..48dc6ddf 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -570,7 +570,7 @@ all_done: test_build .PHONY: clean clean: - rm -rf $(PROGS) afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-cs-proxy afl-qemu-trace afl-gcc-fast afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM + rm -rf $(PROGS) afl-fuzz-document afl-as as afl-g++ afl-clang afl-clang++ *.o src/*.o *~ a.out core core.[1-9][0-9]* *.stackdump .test .test1 .test2 test-instr .test-instr0 .test-instr1 afl-cs-proxy afl-qemu-trace afl-gcc-fast afl-g++-fast ld *.so *.8 test/unittests/*.o test/unittests/unit_maybe_alloc test/unittests/preallocable .afl-* afl-gcc afl-g++ afl-clang afl-clang++ test/unittests/unit_hash test/unittests/unit_rand *.dSYM lib*.a -$(MAKE) -f GNUmakefile.llvm clean -$(MAKE) -f GNUmakefile.gcc_plugin clean -$(MAKE) -C utils/libdislocator clean diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin index 63b22017..e21203ae 100644 --- a/GNUmakefile.gcc_plugin +++ b/GNUmakefile.gcc_plugin @@ -135,11 +135,11 @@ afl-common.o: ./src/afl-common.c ./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c @printf "[*] Building 32-bit variant of the runtime (-m32)... " - @$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-32.o afl-llvm-rt-32.o; else echo "failed (that's fine)"; fi + @$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi ./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c @printf "[*] Building 64-bit variant of the runtime (-m64)... " - @$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi + @$(CC) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi ./afl-gcc-pass.so: instrumentation/afl-gcc-pass.so.cc | test_deps $(CXX) $(CXXEFLAGS) $(PLUGIN_FLAGS) -shared $< -o $@ diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index f1de28a4..a8f019c6 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -394,7 +394,7 @@ endif ./SanitizerCoveragePCGUARD.so: instrumentation/SanitizerCoveragePCGUARD.so.cc instrumentation/afl-llvm-common.o | test_deps ifeq "$(LLVM_10_OK)" "1" - -$(CXX) $(CLANG_CPPFL) -Wdeprecated -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o + -$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-with-dtor -Wdeprecated instrumentation/afl-llvm-common.o endif ./afl-llvm-lto-instrumentlist.so: instrumentation/afl-llvm-lto-instrumentlist.so.cc instrumentation/afl-llvm-common.o @@ -447,11 +447,11 @@ document: ./afl-compiler-rt-32.o: instrumentation/afl-compiler-rt.o.c @printf "[*] Building 32-bit variant of the runtime (-m32)... " - @$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-32.o afl-llvm-rt-32.o; else echo "failed (that's fine)"; fi + @$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m32 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi ./afl-compiler-rt-64.o: instrumentation/afl-compiler-rt.o.c @printf "[*] Building 64-bit variant of the runtime (-m64)... " - @$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; ln -sf afl-compiler-rt-64.o afl-llvm-rt-64.o; else echo "failed (that's fine)"; fi + @$(CC) $(CLANG_CFL) $(CFLAGS_SAFE) $(CPPFLAGS) -O3 -Wno-unused-result -m64 -fPIC -c $< -o $@ 2>/dev/null; if [ "$$?" = "0" ]; then echo "success!"; else echo "failed (that's fine)"; fi .PHONY: test_build test_build: $(PROGS) @@ -474,11 +474,11 @@ install: all @install -d -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) @if [ -f ./afl-cc ]; then set -e; install -m 755 ./afl-cc $${DESTDIR}$(BIN_PATH); ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-c++; fi @rm -f $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt*.o $${DESTDIR}$(HELPER_PATH)/afl-gcc-rt*.o - @if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt.o ;fi + @if [ -f ./afl-compiler-rt.o ]; then set -e; install -m 755 ./afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt.o $${DESTDIR}$(HELPER_PATH)/afl-compiler-rt.o ;fi @if [ -f ./afl-lto ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-lto++; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto++; install -m 755 ./afl-llvm-rt-lto*.o ./afl-llvm-lto-instrumentlist.so $${DESTDIR}$(HELPER_PATH); fi @if [ -f ./afl-ld-lto ]; then set -e; install -m 755 ./afl-ld-lto $${DESTDIR}$(BIN_PATH); fi - @if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-32.o ;fi - @if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-llvm-rt-64.o ; fi + @if [ -f ./afl-compiler-rt-32.o ]; then set -e; install -m 755 ./afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-32.o $${DESTDIR}$(HELPER_PATH)/afl-compiler-rt-32.o ;fi + @if [ -f ./afl-compiler-rt-64.o ]; then set -e; install -m 755 ./afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH); ln -sf afl-compiler-rt-64.o $${DESTDIR}$(HELPER_PATH)/afl-compiler-rt-64.o ; fi @if [ -f ./compare-transform-pass.so ]; then set -e; install -m 755 ./*.so $${DESTDIR}$(HELPER_PATH); fi @if [ -f ./compare-transform-pass.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-fast ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-fast++ ; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang++ ; fi @if [ -f ./SanitizerCoverageLTO.so ]; then set -e; ln -sf afl-cc $${DESTDIR}$(BIN_PATH)/afl-clang-lto ; ln -sf ./afl-c++ $${DESTDIR}$(BIN_PATH)/afl-clang-lto++ ; fi @@ -520,4 +520,4 @@ endif .PHONY: clean clean: rm -f *.o *.so *~ a.out core core.[1-9][0-9]* .test2 test-instr .test-instr0 .test-instr1 *.dwo - rm -f $(PROGS) afl-common.o ./afl-c++ ./afl-lto ./afl-lto++ ./afl-clang-lto* ./afl-clang-fast* ./afl-clang*.8 ./ld ./afl-ld ./afl-llvm-rt*.o instrumentation/*.o + rm -f $(PROGS) afl-common.o ./afl-c++ ./afl-lto ./afl-lto++ ./afl-clang-lto* ./afl-clang-fast* ./afl-clang*.8 ./ld ./afl-ld ./afl-compiler-rt*.o ./afl-llvm-rt*.o instrumentation/*.o diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index b837a033..a5d8f895 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -241,7 +241,7 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { } - static char ID; // Pass identification, replacement for typeid + /*static*/ char ID; // Pass identification, replacement for typeid StringRef getPassName() const override { return "ModuleSanitizerCoverage"; diff --git a/src/afl-cc.c b/src/afl-cc.c index a7248325..4c977303 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -599,6 +599,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { free(ld_path); cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; +#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 15 + cc_params[cc_par_cnt++] = "-Wl,--lto-legacy-pass-manager"; +#endif cc_params[cc_par_cnt++] = alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path); cc_params[cc_par_cnt++] = lto_flag; diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 9b58125f..f2f95fd7 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -86,7 +86,7 @@ static void edit_params(int argc, char **argv) { for (i = 1; i < (u32)argc; i++) { if (strstr(argv[i], "/afl-llvm-rt-lto.o") != NULL) rt_lto_present = 1; - if (strstr(argv[i], "/afl-llvm-rt.o") != NULL) rt_present = 1; + if (strstr(argv[i], "/afl-compiler-rt.o") != NULL) rt_present = 1; if (strstr(argv[i], "/afl-llvm-lto-instr") != NULL) inst_present = 1; } @@ -237,7 +237,7 @@ static void edit_params(int argc, char **argv) { } if (!rt_present) - ld_params[ld_param_cnt++] = alloc_printf("%s/afl-llvm-rt.o", afl_path); + ld_params[ld_param_cnt++] = alloc_printf("%s/afl-compiler-rt.o", afl_path); if (!rt_lto_present) ld_params[ld_param_cnt++] = alloc_printf("%s/afl-llvm-rt-lto.o", afl_path); -- cgit 1.4.1 From 3c11a377570512efeb3a197148ff1b7dddbd8e32 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 17 Mar 2022 15:48:06 +0100 Subject: fixes for llvm < 11 --- instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 +- instrumentation/afl-llvm-dict2file.so.cc | 111 ++++++++++++------------- instrumentation/compare-transform-pass.so.cc | 19 +++-- src/afl-ld-lto.c | 3 +- 4 files changed, 69 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index a5d8f895..e234cf57 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -242,7 +242,7 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { } /*static*/ char ID; // Pass identification, replacement for typeid - StringRef getPassName() const override { + StringRef getPassName() const override { return "ModuleSanitizerCoverage"; diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 37cd8ad0..79cdf491 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -45,7 +45,6 @@ #include "llvm/IR/PassManager.h" #else #include "llvm/IR/LegacyPassManager.h" - #include "llvm/Transforms/IPO/PassManagerBuilder.h" #endif #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Module.h" @@ -67,47 +66,6 @@ #define O_DSYNC O_SYNC #endif -std::ofstream of; - -void dict2file(u8 *mem, u32 len) { - - u32 i, j, binary = 0; - char line[MAX_AUTO_EXTRA * 8], tmp[8]; - - strcpy(line, "\""); - j = 1; - for (i = 0; i < len; i++) { - - if (isprint(mem[i]) && mem[i] != '\\' && mem[i] != '"') { - - line[j++] = mem[i]; - - } else { - - if (i + 1 != len || mem[i] != 0 || binary || len == 4 || len == 8) { - - line[j] = 0; - sprintf(tmp, "\\x%02x", (u8)mem[i]); - strcat(line, tmp); - j = strlen(line); - - } - - binary = 1; - - } - - } - - line[j] = 0; - strcat(line, "\"\n"); - of << line; - of.flush(); - - if (!be_quiet) fprintf(stderr, "Found dictionary token: %s", line); - -} - using namespace llvm; namespace { @@ -115,14 +73,22 @@ namespace { #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ class AFLdict2filePass : public PassInfoMixin { + std::ofstream of; + void dict2file(u8 *, u32); + public: AFLdict2filePass() { #else + class AFLdict2filePass : public ModulePass { + std::ofstream of; + void dict2file(u8 *, u32); + public: - bool runOnModule(Module &M) override; + static char ID; + AFLdict2filePass() : ModulePass(ID) { #endif @@ -133,6 +99,8 @@ class AFLdict2filePass : public ModulePass { #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else + bool runOnModule(Module &M) override; #endif }; @@ -143,7 +111,7 @@ class AFLdict2filePass : public ModulePass { extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK llvmGetPassPluginInfo() { - return {LLVM_PLUGIN_API_VERSION, "dict2file", "v0.1", + return {LLVM_PLUGIN_API_VERSION, "AFLdict2filePass", "v0.1", /* lambda to insert our pass into the pass pipeline. */ [](PassBuilder &PB) { @@ -162,16 +130,52 @@ llvmGetPassPluginInfo() { } #else - char AFLdict2filePass::ID = 0; - #endif +void AFLdict2filePass::dict2file(u8 *mem, u32 len) { + + u32 i, j, binary = 0; + char line[MAX_AUTO_EXTRA * 8], tmp[8]; + + strcpy(line, "\""); + j = 1; + for (i = 0; i < len; i++) { + + if (isprint(mem[i]) && mem[i] != '\\' && mem[i] != '"') { + + line[j++] = mem[i]; + + } else { + + if (i + 1 != len || mem[i] != 0 || binary || len == 4 || len == 8) { + + line[j] = 0; + sprintf(tmp, "\\x%02x", (u8)mem[i]); + strcat(line, tmp); + j = strlen(line); + + } + + binary = 1; + + } + + } + + line[j] = 0; + strcat(line, "\"\n"); + of << line; + of.flush(); + + if (!be_quiet) fprintf(stderr, "Found dictionary token: %s", line); + +} + #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ PreservedAnalyses AFLdict2filePass::run(Module &M, ModuleAnalysisManager &MAM) { #else - bool AFLdict2filePass::runOnModule(Module &M) { #endif @@ -640,6 +644,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { if (optLen < 2) { continue; } if (literalLength + 1 == optLen) { // add null byte + thestring.append("\0", 1); } @@ -662,17 +667,11 @@ bool AFLdict2filePass::runOnModule(Module &M) { } */ - - if (!isStdString) { + if (!isStdString && thestring.find('\0', 0) != std::string::npos) { // ensure we do not have garbage size_t offset = thestring.find('\0', 0); - if (offset && offset < optLen && offset + 1 < optLen) { - - optLen = offset + 1; - - } - + if (offset + 1 < optLen) optLen = offset + 1; thestring = thestring.substr(0, optLen); } @@ -716,8 +715,6 @@ bool AFLdict2filePass::runOnModule(Module &M) { #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ auto PA = PreservedAnalyses::all(); -#endif -#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ return PA; #else return true; diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index 4e471ea3..34c88735 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -88,21 +88,26 @@ class CompareTransform : public ModulePass { const char *getPassName() const override { #endif + + return "cmplog transform"; + + } + #endif #if LLVM_MAJOR >= 11 /* use new pass manager */ - PreservedAnalyses run(Module & M, ModuleAnalysisManager & MAM); + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); #else bool runOnModule(Module &M) override; #endif - private: - bool transformCmps(Module & M, const bool processStrcmp, - const bool processMemcmp, const bool processStrncmp, - const bool processStrcasecmp, - const bool processStrncasecmp); + private: + bool transformCmps(Module &M, const bool processStrcmp, + const bool processMemcmp, const bool processStrncmp, + const bool processStrcasecmp, + const bool processStrncasecmp); - }; +}; } // namespace diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index f2f95fd7..5797def8 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -237,7 +237,8 @@ static void edit_params(int argc, char **argv) { } if (!rt_present) - ld_params[ld_param_cnt++] = alloc_printf("%s/afl-compiler-rt.o", afl_path); + ld_params[ld_param_cnt++] = + alloc_printf("%s/afl-compiler-rt.o", afl_path); if (!rt_lto_present) ld_params[ld_param_cnt++] = alloc_printf("%s/afl-llvm-rt-lto.o", afl_path); -- cgit 1.4.1 From 3d1be62c96f2f10963b8fa6f3946e44e40e6b8b3 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 17 Mar 2022 16:39:40 +0100 Subject: merge fixes --- instrumentation/afl-llvm-pass.so.cc | 91 +++++++++++++++++- instrumentation/cmplog-instructions-pass.cc | 8 +- instrumentation/compare-transform-pass.so.cc | 105 +++++++++++++++++++-- instrumentation/split-compares-pass.so.cc | 132 ++++++++++++++++++++++++--- instrumentation/split-switches-pass.so.cc | 107 ++++++++++++++++++++-- src/afl-cc.c | 37 ++++++-- 6 files changed, 435 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index 6419cd1d..be8099bb 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -46,12 +46,21 @@ typedef long double max_align_t; #include "llvm/IR/IRBuilder.h" #include "llvm/Pass.h" -#include "llvm/IR/LegacyPassManager.h" +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #if LLVM_VERSION_MAJOR >= 4 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) @@ -69,17 +78,30 @@ using namespace llvm; namespace { +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +class AFLCoverage : public PassInfoMixin { + + public: + AFLCoverage() { + +#else class AFLCoverage : public ModulePass { public: static char ID; AFLCoverage() : ModulePass(ID) { +#endif + initInstrumentList(); } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else bool runOnModule(Module &M) override; +#endif protected: uint32_t ngram_size = 0; @@ -93,7 +115,55 @@ class AFLCoverage : public ModulePass { } // namespace +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "AFLCoverage", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if 1 + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(AFLCoverage()); + + }); + + /* TODO LTO registration */ + #else + using PipelineElement = typename PassBuilder::PipelineElement; + PB.registerPipelineParsingCallback([](StringRef Name, + ModulePassManager &MPM, + ArrayRef) { + + if (Name == "AFLCoverage") { + + MPM.addPass(AFLCoverage()); + return true; + + } else { + + return false; + + } + + }); + + #endif + + }}; + +} + +#else + char AFLCoverage::ID = 0; +#endif /* needed up to 3.9.0 */ #if LLVM_VERSION_MAJOR == 3 && \ @@ -119,8 +189,15 @@ uint64_t PowerOf2Ceil(unsigned in) { (LLVM_VERSION_MAJOR == 4 && LLVM_VERSION_PATCH >= 1) #define AFL_HAVE_VECTOR_INTRINSICS 1 #endif + +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses AFLCoverage::run(Module &M, ModuleAnalysisManager &MAM) { + +#else bool AFLCoverage::runOnModule(Module &M) { +#endif + LLVMContext &C = M.getContext(); IntegerType *Int8Ty = IntegerType::getInt8Ty(C); @@ -134,6 +211,10 @@ bool AFLCoverage::runOnModule(Module &M) { u32 rand_seed; unsigned int cur_loc = 0; +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + auto PA = PreservedAnalyses::all(); +#endif + /* Setup random() so we get Actually Random(TM) outputs from AFL_R() */ gettimeofday(&tv, &tz); rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); @@ -998,10 +1079,15 @@ bool AFLCoverage::runOnModule(Module &M) { } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + return PA; +#else return true; +#endif } +#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ static void registerAFLPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -1014,4 +1100,5 @@ static RegisterStandardPasses RegisterAFLPass( static RegisterStandardPasses RegisterAFLPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass); +#endif diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 85dec437..7c95d9bb 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -28,7 +28,6 @@ #include "llvm/Config/llvm-config.h" #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -138,7 +137,7 @@ llvmGetPassPluginInfo() { #else char CmpLogInstructions::ID = 0; #endif - + template Iterator Unique(Iterator first, Iterator last) { @@ -686,10 +685,10 @@ bool CmpLogInstructions::runOnModule(Module &M) { #else return true; #endif - + } -#if LLVM_MAJOR < 11 /* use old pass manager */ +#if LLVM_MAJOR < 11 /* use old pass manager */ static void registerCmpLogInstructionsPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -710,3 +709,4 @@ static RegisterStandardPasses RegisterCmpLogInstructionsPassLTO( registerCmpLogInstructionsPass); #endif #endif + diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index 9a4e4f00..34c88735 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -26,14 +26,23 @@ #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" +#if LLVM_MAJOR >= 11 /* use new pass manager */ + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #if LLVM_VERSION_MAJOR >= 4 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4) @@ -52,12 +61,21 @@ using namespace llvm; namespace { +#if LLVM_MAJOR >= 11 /* use new pass manager */ +class CompareTransform : public PassInfoMixin { + + public: + CompareTransform() { + +#else class CompareTransform : public ModulePass { public: static char ID; CompareTransform() : ModulePass(ID) { +#endif + initInstrumentList(); } @@ -70,17 +88,18 @@ class CompareTransform : public ModulePass { const char *getPassName() const override { #endif - return "transforms compare functions"; + + return "cmplog transform"; } #endif - //#if LLVM_MAJOR >= 11 /* use new pass manager */ - // PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); - //#else +#if LLVM_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else bool runOnModule(Module &M) override; - //#endif +#endif private: bool transformCmps(Module &M, const bool processStrcmp, @@ -92,7 +111,54 @@ class CompareTransform : public ModulePass { } // namespace +#if LLVM_MAJOR >= 11 /* use new pass manager */ +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "comparetransform", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if 1 + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(CompareTransform()); + + }); + + /* TODO LTO registration */ + #else + using PipelineElement = typename PassBuilder::PipelineElement; + PB.registerPipelineParsingCallback([](StringRef Name, + ModulePassManager &MPM, + ArrayRef) { + + if (Name == "comparetransform") { + + MPM.addPass(CompareTransform()); + return true; + + } else { + + return false; + + } + + }); + + #endif + + }}; + +} + +#else char CompareTransform::ID = 0; +#endif bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, const bool processMemcmp, @@ -392,6 +458,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, bool isCaseInsensitive = false; bool needs_null = false; Function * Callee = callInst->getCalledFunction(); + if (Callee) { if (!Callee->getName().compare("memcmp") || @@ -649,8 +716,14 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, } +#if LLVM_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses CompareTransform::run(Module &M, ModuleAnalysisManager &MAM) { + +#else bool CompareTransform::runOnModule(Module &M) { +#endif + if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) printf( "Running compare-transform-pass by laf.intel@gmail.com, extended by " @@ -658,13 +731,28 @@ bool CompareTransform::runOnModule(Module &M) { else be_quiet = 1; +#if LLVM_MAJOR >= 11 /* use new pass manager */ + auto PA = PreservedAnalyses::all(); +#endif + transformCmps(M, true, true, true, true, true); verifyModule(M); +#if LLVM_MAJOR >= 11 /* use new pass manager */ + /* if (modified) { + + PA.abandon(); + + }*/ + + return PA; +#else return true; +#endif } +#if LLVM_MAJOR < 11 /* use old pass manager */ static void registerCompTransPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -679,8 +767,9 @@ static RegisterStandardPasses RegisterCompTransPass( static RegisterStandardPasses RegisterCompTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerCompTransPass); -#if LLVM_VERSION_MAJOR >= 11 + #if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterCompTransPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerCompTransPass); + #endif #endif diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 0f00fa96..d7bb7aba 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -1,6 +1,7 @@ /* * Copyright 2016 laf-intel * extended for floating point by Heiko Eißfeldt + * adapted to new pass manager by Heiko Eißfeldt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,10 +29,20 @@ #include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" + +#if LLVM_MAJOR >= 11 + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/IR/Module.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #include "llvm/IR/IRBuilder.h" #if LLVM_VERSION_MAJOR >= 4 || \ @@ -53,27 +64,31 @@ using namespace llvm; namespace { +#if LLVM_MAJOR >= 11 +class SplitComparesTransform : public PassInfoMixin { + + public: + // static char ID; + SplitComparesTransform() : enableFPSplit(0) { + +#else class SplitComparesTransform : public ModulePass { public: static char ID; SplitComparesTransform() : ModulePass(ID), enableFPSplit(0) { +#endif + initInstrumentList(); } - bool runOnModule(Module &M) override; -#if LLVM_VERSION_MAJOR >= 4 - StringRef getPassName() const override { - +#if LLVM_MAJOR >= 11 + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); #else - const char *getPassName() const override { - + bool runOnModule(Module &M) override; #endif - return "AFL_SplitComparesTransform"; - - } private: int enableFPSplit; @@ -162,7 +177,54 @@ class SplitComparesTransform : public ModulePass { } // namespace +#if LLVM_MAJOR >= 11 +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "splitcompares", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if 1 + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(SplitComparesTransform()); + + }); + + /* TODO LTO registration */ + #else + using PipelineElement = typename PassBuilder::PipelineElement; + PB.registerPipelineParsingCallback([](StringRef Name, + ModulePassManager &MPM, + ArrayRef) { + + if (Name == "splitcompares") { + + MPM.addPass(SplitComparesTransform()); + return true; + + } else { + + return false; + + } + + }); + + #endif + + }}; + +} + +#else char SplitComparesTransform::ID = 0; +#endif /// This function splits FCMP instructions with xGE or xLE predicates into two /// FCMP instructions with predicate xGT or xLT and EQ @@ -1421,8 +1483,15 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) { } +#if LLVM_MAJOR >= 11 +PreservedAnalyses SplitComparesTransform::run(Module & M, + ModuleAnalysisManager &MAM) { + +#else bool SplitComparesTransform::runOnModule(Module &M) { +#endif + char *bitw_env = getenv("AFL_LLVM_LAF_SPLIT_COMPARES_BITW"); if (!bitw_env) bitw_env = getenv("LAF_SPLIT_COMPARES_BITW"); if (bitw_env) { target_bitwidth = atoi(bitw_env); } @@ -1432,7 +1501,7 @@ bool SplitComparesTransform::runOnModule(Module &M) { if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) { - errs() << "Split-compare-pass by laf.intel@gmail.com, extended by " + errs() << "Split-compare-newpass by laf.intel@gmail.com, extended by " "heiko@hexco.de (splitting icmp to " << target_bitwidth << " bit)\n"; @@ -1444,6 +1513,10 @@ bool SplitComparesTransform::runOnModule(Module &M) { } +#if LLVM_MAJOR >= 11 + auto PA = PreservedAnalyses::all(); +#endif + if (enableFPSplit) { simplifyFPCompares(M); @@ -1473,7 +1546,16 @@ bool SplitComparesTransform::runOnModule(Module &M) { auto op0 = CI->getOperand(0); auto op1 = CI->getOperand(1); - if (!op0 || !op1) { return false; } + if (!op0 || !op1) { + +#if LLVM_MAJOR >= 11 + return PA; +#else + return false; +#endif + + } + auto iTy1 = dyn_cast(op0->getType()); if (iTy1 && isa(op1->getType())) { @@ -1522,10 +1604,29 @@ bool SplitComparesTransform::runOnModule(Module &M) { } + if ((isatty(2) && getenv("AFL_QUIET") == NULL) || + getenv("AFL_DEBUG") != NULL) { + + errs() << count << " comparisons found\n"; + + } + +#if LLVM_MAJOR >= 11 + /* if (modified) { + + PA.abandon(); + + }*/ + + return PA; +#else return true; +#endif } +#if LLVM_MAJOR < 11 /* use old pass manager */ + static void registerSplitComparesPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -1539,14 +1640,15 @@ static RegisterStandardPasses RegisterSplitComparesPass( static RegisterStandardPasses RegisterSplitComparesTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitComparesPass); -#if LLVM_VERSION_MAJOR >= 11 + #if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterSplitComparesTransPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerSplitComparesPass); -#endif + #endif static RegisterPass X("splitcompares", "AFL++ split compares", true /* Only looks at CFG */, true /* Analysis Pass */); +#endif diff --git a/instrumentation/split-switches-pass.so.cc b/instrumentation/split-switches-pass.so.cc index 9f9e7eca..96e01a8b 100644 --- a/instrumentation/split-switches-pass.so.cc +++ b/instrumentation/split-switches-pass.so.cc @@ -27,14 +27,23 @@ #include "llvm/ADT/Statistic.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/LegacyPassManager.h" +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + #include "llvm/Passes/PassPlugin.h" + #include "llvm/Passes/PassBuilder.h" + #include "llvm/IR/PassManager.h" +#else + #include "llvm/IR/LegacyPassManager.h" + #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#endif #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Pass.h" #include "llvm/Analysis/ValueTracking.h" +#if LLVM_VERSION_MAJOR >= 14 /* how about stable interfaces? */ + #include "llvm/Passes/OptimizationLevel.h" +#endif #include "llvm/IR/IRBuilder.h" #if LLVM_VERSION_MAJOR >= 4 || \ @@ -54,29 +63,42 @@ using namespace llvm; namespace { +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +class SplitSwitchesTransform : public PassInfoMixin { + + public: + SplitSwitchesTransform() { + +#else class SplitSwitchesTransform : public ModulePass { public: static char ID; SplitSwitchesTransform() : ModulePass(ID) { +#endif initInstrumentList(); } - bool runOnModule(Module &M) override; +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); +#else + bool runOnModule(Module &M) override; -#if LLVM_VERSION_MAJOR >= 4 + #if LLVM_VERSION_MAJOR >= 4 StringRef getPassName() const override { -#else + #else const char *getPassName() const override { -#endif + #endif return "splits switch constructs"; } +#endif + struct CaseExpr { ConstantInt *Val; @@ -103,7 +125,54 @@ class SplitSwitchesTransform : public ModulePass { } // namespace +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "splitswitches", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + + #if 1 + #if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + #endif + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(SplitSwitchesTransform()); + + }); + + /* TODO LTO registration */ + #else + using PipelineElement = typename PassBuilder::PipelineElement; + PB.registerPipelineParsingCallback([](StringRef Name, + ModulePassManager &MPM, + ArrayRef) { + + if (Name == "splitswitches") { + + MPM.addPass(SplitSwitchesTransform()); + return true; + + } else { + + return false; + + } + + }); + + #endif + + }}; + +} + +#else char SplitSwitchesTransform::ID = 0; +#endif /* switchConvert - Transform simple list of Cases into list of CaseRange's */ BasicBlock *SplitSwitchesTransform::switchConvert( @@ -413,19 +482,42 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) { } +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ +PreservedAnalyses SplitSwitchesTransform::run(Module & M, + ModuleAnalysisManager &MAM) { + +#else bool SplitSwitchesTransform::runOnModule(Module &M) { +#endif + if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL) printf("Running split-switches-pass by laf.intel@gmail.com\n"); else be_quiet = 1; + +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + auto PA = PreservedAnalyses::all(); +#endif + splitSwitches(M); verifyModule(M); +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + /* if (modified) { + + PA.abandon(); + + }*/ + + return PA; +#else return true; +#endif } +#if LLVM_VERSION_MAJOR < 11 /* use old pass manager */ static void registerSplitSwitchesTransPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) { @@ -440,9 +532,10 @@ static RegisterStandardPasses RegisterSplitSwitchesTransPass( static RegisterStandardPasses RegisterSplitSwitchesTransPass0( PassManagerBuilder::EP_EnabledOnOptLevel0, registerSplitSwitchesTransPass); -#if LLVM_VERSION_MAJOR >= 11 + #if LLVM_VERSION_MAJOR >= 11 static RegisterStandardPasses RegisterSplitSwitchesTransPassLTO( PassManagerBuilder::EP_FullLinkTimeOptimizationLast, registerSplitSwitchesTransPass); + #endif #endif diff --git a/src/afl-cc.c b/src/afl-cc.c index 051e4910..0d5951bb 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -434,21 +434,33 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (lto_mode && have_instr_env) { +#if LLVM_MAJOR >= 11 /* use new pass manager */ + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = alloc_printf( + "-fpass-plugin=%s/afl-llvm-lto-instrumentlist.so", obj_path); +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-lto-instrumentlist.so", obj_path); +#endif } if (getenv("AFL_LLVM_DICT2FILE")) { +#if LLVM_MAJOR >= 11 /* use new pass manager */ + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/afl-llvm-dict2file.so", obj_path); +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-dict2file.so", obj_path); +#endif } @@ -473,7 +485,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = alloc_printf("%s/split-switches-pass.so", obj_path); #endif - + } } @@ -499,7 +511,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = alloc_printf("%s/compare-transform-pass.so", obj_path); #endif - + } } @@ -560,10 +572,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { } -//#if LLVM_MAJOR >= 13 -// // Use the old pass manager in LLVM 14 which the afl++ passes still use. -// cc_params[cc_par_cnt++] = "-flegacy-pass-manager"; -//#endif + //#if LLVM_MAJOR >= 13 + // // Use the old pass manager in LLVM 14 which the afl++ passes still + // use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager"; + //#endif if (lto_mode && !have_c) { @@ -654,10 +666,17 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { +#if LLVM_MAJOR >= 11 /* use new pass manager */ + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path); +#else + cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path); +#endif } @@ -679,8 +698,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = alloc_printf( "-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path); cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = alloc_printf( - "-fpass-plugin=%s/cmplog-routines-pass.so", obj_path); + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/cmplog-routines-pass.so", obj_path); #else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; @@ -694,7 +713,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = alloc_printf("%s/cmplog-routines-pass.so", obj_path); #endif - + } } -- cgit 1.4.1 From bdfac291ba653b34a1d304d6135111d68b8d8267 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 18 Mar 2022 08:47:45 +0100 Subject: fix split pass loading --- docs/Changelog.md | 2 ++ src/afl-cc.c | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index 18a4debf..d672686d 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -24,6 +24,8 @@ sending a mail to . possible in the target (for afl-gcc-fast/afl-clang-fast/ afl-clang-lto) - afl-cc: + ! llvm15-dev with LTO and extra features (LAF/CMPLOG etc.) might have + issues at the moment - converted all passed to use the new llvm pass manager for llvm 11+ - frida_mode: - update to new frida release, handles now c++ throw/catch diff --git a/src/afl-cc.c b/src/afl-cc.c index 0d5951bb..487f394e 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -526,11 +526,17 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { +#if LLVM_MAJOR >= 11 /* use new pass manager */ + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path); +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/split-compares-pass.so", obj_path); +#endif } @@ -553,6 +559,16 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { + cc_params[cc_par_cnt++] = "-fno-inline"; + +#if LLVM_MAJOR >= 11 /* use new pass manager */ + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/cmplog-switches-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); +#else cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = "-load"; cc_params[cc_par_cnt++] = "-Xclang"; @@ -565,11 +581,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-Xclang"; cc_params[cc_par_cnt++] = alloc_printf("%s/split-switches-pass.so", obj_path); +#endif } - cc_params[cc_par_cnt++] = "-fno-inline"; - } //#if LLVM_MAJOR >= 13 -- cgit 1.4.1 From 69c9a176eb6ded2e7087ab437950a8ec324cdb1b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 18 Mar 2022 12:57:51 +0100 Subject: our own PCGUARD mode not for llvm 10.0.1 --- docs/Changelog.md | 1 + src/afl-cc.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/docs/Changelog.md b/docs/Changelog.md index d672686d..f47a9b7c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -27,6 +27,7 @@ sending a mail to . ! llvm15-dev with LTO and extra features (LAF/CMPLOG etc.) might have issues at the moment - converted all passed to use the new llvm pass manager for llvm 11+ + - AFL++ PCGUARD mode is not available for 10.0.1 anymore (11+ only) - frida_mode: - update to new frida release, handles now c++ throw/catch diff --git a/src/afl-cc.c b/src/afl-cc.c index 487f394e..df2957b4 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -626,7 +626,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (instrument_mode == INSTRUMENT_PCGUARD) { -#if LLVM_MAJOR >= 11 || (LLVM_MAJOR == 10 && LLVM_MINOR >= 1) +#if LLVM_MAJOR >= 11 #if defined __ANDROID__ || ANDROID cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard"; instrument_mode = INSTRUMENT_LLVMNATIVE; -- cgit 1.4.1 From fa2b0404763f69c3bff0912a44a11e2e8c3734ab Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 18 Mar 2022 15:00:24 +0100 Subject: fix LTO with cmplog and laf --- GNUmakefile.llvm | 2 +- docs/Changelog.md | 2 - instrumentation/SanitizerCoverageLTO.so.cc | 163 ++++++++++----------------- src/afl-cc.c | 171 ++++++++++------------------- src/afl-fuzz-run.c | 3 +- 5 files changed, 121 insertions(+), 220 deletions(-) (limited to 'src') diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index a8f019c6..f91ff0d1 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -394,7 +394,7 @@ endif ./SanitizerCoveragePCGUARD.so: instrumentation/SanitizerCoveragePCGUARD.so.cc instrumentation/afl-llvm-common.o | test_deps ifeq "$(LLVM_10_OK)" "1" - -$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-with-dtor -Wdeprecated instrumentation/afl-llvm-common.o + -$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-dtor -Wdeprecated instrumentation/afl-llvm-common.o endif ./afl-llvm-lto-instrumentlist.so: instrumentation/afl-llvm-lto-instrumentlist.so.cc instrumentation/afl-llvm-common.o diff --git a/docs/Changelog.md b/docs/Changelog.md index f47a9b7c..74631a88 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -24,8 +24,6 @@ sending a mail to . possible in the target (for afl-gcc-fast/afl-clang-fast/ afl-clang-lto) - afl-cc: - ! llvm15-dev with LTO and extra features (LAF/CMPLOG etc.) might have - issues at the moment - converted all passed to use the new llvm pass manager for llvm 11+ - AFL++ PCGUARD mode is not available for 10.0.1 anymore (11+ only) - frida_mode: diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 1bdc5376..9a48ae6d 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -34,7 +34,6 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Mangler.h" @@ -52,6 +51,9 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" +#include "llvm/Passes/PassPlugin.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/IR/PassManager.h" #include "config.h" #include "debug.h" @@ -162,27 +164,21 @@ using DomTreeCallback = function_ref; using PostDomTreeCallback = function_ref; -class ModuleSanitizerCoverage { +class ModuleSanitizerCoverageLTO + : public PassInfoMixin { public: - ModuleSanitizerCoverage( + ModuleSanitizerCoverageLTO( const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : Options(OverrideFromCL(Options)) { - /* , - const SpecialCaseList * Allowlist = nullptr, - const SpecialCaseList * Blocklist = nullptr) - , - Allowlist(Allowlist), - Blocklist(Blocklist) { - - */ - } bool instrumentModule(Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback); + PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); + private: void instrumentFunction(Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback); @@ -280,18 +276,6 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { const SanitizerCoverageOptions &Options = SanitizerCoverageOptions()) : ModulePass(ID), Options(Options) { - /* , - const std::vector &AllowlistFiles = - std::vector(), - const std::vector &BlocklistFiles = - std::vector()) - if (AllowlistFiles.size() > 0) - Allowlist = SpecialCaseList::createOrDie(AllowlistFiles, - *vfs::getRealFileSystem()); - if (BlocklistFiles.size() > 0) - Blocklist = SpecialCaseList::createOrDie(BlocklistFiles, - *vfs::getRealFileSystem()); - */ initializeModuleSanitizerCoverageLegacyPassPass( *PassRegistry::getPassRegistry()); @@ -299,8 +283,7 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { bool runOnModule(Module &M) override { - ModuleSanitizerCoverage ModuleSancov(Options); - // , Allowlist.get(), Blocklist.get()); + ModuleSanitizerCoverageLTO ModuleSancov(Options); auto DTCallback = [this](Function &F) -> const DominatorTree * { return &this->getAnalysis(F).getDomTree(); @@ -321,18 +304,36 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { private: SanitizerCoverageOptions Options; - // std::unique_ptr Allowlist; - // std::unique_ptr Blocklist; - }; } // namespace -PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, - ModuleAnalysisManager &MAM) { +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + + return {LLVM_PLUGIN_API_VERSION, "SanitizerCoverageLTO", "v0.1", + /* lambda to insert our pass into the pass pipeline. */ + [](PassBuilder &PB) { + +#if LLVM_VERSION_MAJOR <= 13 + using OptimizationLevel = typename PassBuilder::OptimizationLevel; +#endif + // PB.registerFullLinkTimeOptimizationLastEPCallback( + PB.registerOptimizerLastEPCallback( + [](ModulePassManager &MPM, OptimizationLevel OL) { + + MPM.addPass(ModuleSanitizerCoverageLTO()); + + }); + + }}; + +} + +PreservedAnalyses ModuleSanitizerCoverageLTO::run(Module & M, + ModuleAnalysisManager &MAM) { - ModuleSanitizerCoverage ModuleSancov(Options); - // Allowlist.get(), Blocklist.get()); + ModuleSanitizerCoverageLTO ModuleSancov(Options); auto &FAM = MAM.getResult(M).getManager(); auto DTCallback = [&FAM](Function &F) -> const DominatorTree * { @@ -353,35 +354,7 @@ PreservedAnalyses ModuleSanitizerCoveragePass::run(Module & M, } -/* -std::pair ModuleSanitizerCoverage::CreateSecStartEnd( - Module &M, const char *Section, Type *Ty) { - - GlobalVariable *SecStart = - new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, nullptr, - getSectionStart(Section)); - SecStart->setVisibility(GlobalValue::HiddenVisibility); - GlobalVariable *SecEnd = - new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage, nullptr, - getSectionEnd(Section)); - SecEnd->setVisibility(GlobalValue::HiddenVisibility); - IRBuilder<> IRB(M.getContext()); - Value * SecEndPtr = IRB.CreatePointerCast(SecEnd, Ty); - if (!TargetTriple.isOSBinFormatCOFF()) - return std::make_pair(IRB.CreatePointerCast(SecStart, Ty), SecEndPtr); - - // Account for the fact that on windows-msvc __start_* symbols actually - // point to a uint64_t before the start of the array. - auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy); - auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr, - ConstantInt::get(IntptrTy, sizeof(uint64_t))); - return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEndPtr); - -} - -*/ - -bool ModuleSanitizerCoverage::instrumentModule( +bool ModuleSanitizerCoverageLTO::instrumentModule( Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) return false; @@ -1045,7 +1018,7 @@ bool ModuleSanitizerCoverage::instrumentModule( M, Int64Tyi, true, GlobalValue::ExternalLinkage, 0, "__afl_map_addr"); ConstantInt *MapAddr = ConstantInt::get(Int64Tyi, map_addr); StoreInst * StoreMapAddr = IRB.CreateStore(MapAddr, AFLMapAddrFixed); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreMapAddr); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreMapAddr); } @@ -1060,7 +1033,7 @@ bool ModuleSanitizerCoverage::instrumentModule( "__afl_final_loc"); ConstantInt *const_loc = ConstantInt::get(Int32Tyi, write_loc); StoreInst * StoreFinalLoc = IRB.CreateStore(const_loc, AFLFinalLoc); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreFinalLoc); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreFinalLoc); } @@ -1108,7 +1081,7 @@ bool ModuleSanitizerCoverage::instrumentModule( 0, "__afl_dictionary_len"); ConstantInt *const_len = ConstantInt::get(Int32Tyi, offset); StoreInst *StoreDictLen = IRB.CreateStore(const_len, AFLDictionaryLen); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreDictLen); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreDictLen); ArrayType *ArrayTy = ArrayType::get(IntegerType::get(Ctx, 8), offset); GlobalVariable *AFLInternalDictionary = new GlobalVariable( @@ -1128,7 +1101,7 @@ bool ModuleSanitizerCoverage::instrumentModule( Value *AFLDictPtr = IRB.CreatePointerCast(AFLDictOff, PointerType::get(Int8Tyi, 0)); StoreInst *StoreDict = IRB.CreateStore(AFLDictPtr, AFLDictionary); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(StoreDict); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(StoreDict); } @@ -1235,7 +1208,7 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, } -void ModuleSanitizerCoverage::instrumentFunction( +void ModuleSanitizerCoverageLTO::instrumentFunction( Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) { if (F.empty()) return; @@ -1390,7 +1363,7 @@ void ModuleSanitizerCoverage::instrumentFunction( /* Load SHM pointer */ LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(MapPtr); while (1) { @@ -1420,7 +1393,7 @@ void ModuleSanitizerCoverage::instrumentFunction( } else { LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(Counter); /* Update bitmap */ @@ -1435,7 +1408,7 @@ void ModuleSanitizerCoverage::instrumentFunction( } auto nosan = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan); } @@ -1473,7 +1446,7 @@ void ModuleSanitizerCoverage::instrumentFunction( } -GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( +GlobalVariable *ModuleSanitizerCoverageLTO::CreateFunctionLocalArrayInSection( size_t NumElements, Function &F, Type *Ty, const char *Section) { ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); @@ -1503,7 +1476,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreateFunctionLocalArrayInSection( } -GlobalVariable *ModuleSanitizerCoverage::CreatePCArray( +GlobalVariable *ModuleSanitizerCoverageLTO::CreatePCArray( Function &F, ArrayRef AllBlocks) { size_t N = AllBlocks.size(); @@ -1539,7 +1512,7 @@ GlobalVariable *ModuleSanitizerCoverage::CreatePCArray( } -void ModuleSanitizerCoverage::CreateFunctionLocalArrays( +void ModuleSanitizerCoverageLTO::CreateFunctionLocalArrays( Function &F, ArrayRef AllBlocks) { if (Options.TracePCGuard) @@ -1555,9 +1528,8 @@ void ModuleSanitizerCoverage::CreateFunctionLocalArrays( } -bool ModuleSanitizerCoverage::InjectCoverage(Function & F, - ArrayRef AllBlocks, - bool IsLeafFunc) { +bool ModuleSanitizerCoverageLTO::InjectCoverage( + Function &F, ArrayRef AllBlocks, bool IsLeafFunc) { if (AllBlocks.empty()) return false; CreateFunctionLocalArrays(F, AllBlocks); @@ -1603,7 +1575,7 @@ bool ModuleSanitizerCoverage::InjectCoverage(Function & F, // The cache is used to speed up recording the caller-callee pairs. // The address of the caller is passed implicitly via caller PC. // CacheSize is encoded in the name of the run-time function. -void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( +void ModuleSanitizerCoverageLTO::InjectCoverageForIndirectCalls( Function &F, ArrayRef IndirCalls) { if (IndirCalls.empty()) return; @@ -1621,9 +1593,10 @@ void ModuleSanitizerCoverage::InjectCoverageForIndirectCalls( } -void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, - size_t Idx, - bool IsLeafFunc) { +void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function & F, + BasicBlock &BB, + size_t Idx, + bool IsLeafFunc) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); bool IsEntryBB = &BB == &F.getEntryBlock(); @@ -1678,7 +1651,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { LoadInst *MapPtr = IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(MapPtr); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(MapPtr); MapPtrIdx = IRB.CreateGEP(Int8Ty, MapPtr, CurLoc); } @@ -1695,7 +1668,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } else { LoadInst *Counter = IRB.CreateLoad(IRB.getInt8Ty(), MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(Counter); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(Counter); Value *Incr = IRB.CreateAdd(Counter, One); @@ -1708,7 +1681,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } auto nosan = IRB.CreateStore(Incr, MapPtrIdx); - ModuleSanitizerCoverage::SetNoSanitizeMetadata(nosan); + ModuleSanitizerCoverageLTO::SetNoSanitizeMetadata(nosan); } @@ -1760,7 +1733,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } -std::string ModuleSanitizerCoverage::getSectionName( +std::string ModuleSanitizerCoverageLTO::getSectionName( const std::string &Section) const { if (TargetTriple.isOSBinFormatCOFF()) { @@ -1777,27 +1750,6 @@ std::string ModuleSanitizerCoverage::getSectionName( } -/* -std::string ModuleSanitizerCoverage::getSectionStart( - const std::string &Section) const { - - if (TargetTriple.isOSBinFormatMachO()) - return "\1section$start$__DATA$__" + Section; - return "__start___" + Section; - -} - -std::string ModuleSanitizerCoverage::getSectionEnd( - const std::string &Section) const { - - if (TargetTriple.isOSBinFormatMachO()) - return "\1section$end$__DATA$__" + Section; - return "__stop___" + Section; - -} - -*/ - char ModuleSanitizerCoverageLegacyPass::ID = 0; INITIALIZE_PASS_BEGIN(ModuleSanitizerCoverageLegacyPass, "sancov", @@ -1815,7 +1767,6 @@ ModulePass *llvm::createModuleSanitizerCoverageLegacyPassPass( const std::vector &BlocklistFiles) { return new ModuleSanitizerCoverageLegacyPass(Options); - //, AllowlistFiles, BlocklistFiles); } diff --git a/src/afl-cc.c b/src/afl-cc.c index df2957b4..dfcb2a89 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -467,79 +467,52 @@ static void edit_params(u32 argc, char **argv, char **envp) { // laf if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) { - if (lto_mode && !have_c) { - - cc_params[cc_par_cnt++] = alloc_printf( - "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path); - - } else { - #if LLVM_MAJOR >= 11 /* use new pass manager */ - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); #else - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/split-switches-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/split-switches-pass.so", obj_path); #endif - } - } if (getenv("LAF_TRANSFORM_COMPARES") || getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) { - if (lto_mode && !have_c) { - - cc_params[cc_par_cnt++] = alloc_printf( - "-Wl,-mllvm=-load=%s/compare-transform-pass.so", obj_path); - - } else { - #if LLVM_MAJOR >= 11 /* use new pass manager */ - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = alloc_printf( - "-fpass-plugin=%s/compare-transform-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/compare-transform-pass.so", obj_path); #else - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/compare-transform-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/compare-transform-pass.so", obj_path); #endif - } - } if (getenv("LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_COMPARES") || getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) { - if (lto_mode && !have_c) { - - cc_params[cc_par_cnt++] = alloc_printf( - "-Wl,-mllvm=-load=%s/split-compares-pass.so", obj_path); - - } else { - #if LLVM_MAJOR >= 11 /* use new pass manager */ - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path); #else - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/split-compares-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/split-compares-pass.so", obj_path); #endif - } - } // /laf @@ -549,42 +522,30 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (cmplog_mode) { - if (lto_mode && !have_c) { - - cc_params[cc_par_cnt++] = alloc_printf( - "-Wl,-mllvm=-load=%s/cmplog-switches-pass.so", obj_path); - - cc_params[cc_par_cnt++] = alloc_printf( - "-Wl,-mllvm=-load=%s/split-switches-pass.so", obj_path); - - } else { - - cc_params[cc_par_cnt++] = "-fno-inline"; + cc_params[cc_par_cnt++] = "-fno-inline"; #if LLVM_MAJOR >= 11 /* use new pass manager */ - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/cmplog-switches-pass.so", obj_path); - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/cmplog-switches-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); #else - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/cmplog-switches-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/cmplog-switches-pass.so", obj_path); - // reuse split switches from laf - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/split-switches-pass.so", obj_path); + // reuse split switches from laf + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/split-switches-pass.so", obj_path); #endif - } - } //#if LLVM_MAJOR >= 13 @@ -614,10 +575,11 @@ static void edit_params(u32 argc, char **argv, char **envp) { #endif free(ld_path); - cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; -#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 15 +#if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 13 cc_params[cc_par_cnt++] = "-Wl,--lto-legacy-pass-manager"; #endif + + cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; cc_params[cc_par_cnt++] = alloc_printf("-Wl,-mllvm=-load=%s/SanitizerCoverageLTO.so", obj_path); cc_params[cc_par_cnt++] = lto_flag; @@ -699,38 +661,27 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (cmplog_mode) { - if (lto_mode && !have_c) { - - cc_params[cc_par_cnt++] = alloc_printf( - "-Wl,-mllvm=-load=%s/cmplog-instructions-pass.so", obj_path); - cc_params[cc_par_cnt++] = alloc_printf( - "-Wl,-mllvm=-load=%s/cmplog-routines-pass.so", obj_path); - - } else { - #if LLVM_MAJOR >= 11 - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = alloc_printf( - "-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path); - cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; - cc_params[cc_par_cnt++] = - alloc_printf("-fpass-plugin=%s/cmplog-routines-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = alloc_printf( + "-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + cc_params[cc_par_cnt++] = + alloc_printf("-fpass-plugin=%s/cmplog-routines-pass.so", obj_path); #else - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/cmplog-instructions-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/cmplog-instructions-pass.so", obj_path); - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = "-load"; - cc_params[cc_par_cnt++] = "-Xclang"; - cc_params[cc_par_cnt++] = - alloc_printf("%s/cmplog-routines-pass.so", obj_path); + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = "-load"; + cc_params[cc_par_cnt++] = "-Xclang"; + cc_params[cc_par_cnt++] = + alloc_printf("%s/cmplog-routines-pass.so", obj_path); #endif - } - } // cc_params[cc_par_cnt++] = "-Qunused-arguments"; diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 2a9d186b..ffba3475 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -232,7 +232,8 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, memcpy(afl->fsrv.shmem_fuzz, mem, skip_at); - memcpy(afl->fsrv.shmem_fuzz + skip_at, mem + skip_at + skip_len, tail_len); + memcpy(afl->fsrv.shmem_fuzz + skip_at, mem + skip_at + skip_len, + tail_len); } -- cgit 1.4.1 From c2ae24ab96f16242572b3618b36fa488d29dcc13 Mon Sep 17 00:00:00 2001 From: fuzzah Date: Mon, 21 Mar 2022 22:58:17 +0300 Subject: fix early return in AFL_TARGET_ENV --- src/afl-common.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/afl-common.c b/src/afl-common.c index 7c074acc..eca7d272 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -805,10 +805,7 @@ bool extract_and_set_env(u8 *env_str) { *rest = '\0'; // done with variable value rest += 1; - if (rest < end && *rest != ' ') { goto free_and_return; } - num_pairs++; - setenv(key, val, 1); } -- cgit 1.4.1 From a436ef47e5cf0cb16b4afddccc6530285a6bb6fa Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 30 Mar 2022 09:16:47 +0200 Subject: fix instrumentlist for LTO with clang < 13 --- src/afl-cc.c | 2 ++ test/test-llvm-lto.sh | 3 +++ 2 files changed, 5 insertions(+) (limited to 'src') diff --git a/src/afl-cc.c b/src/afl-cc.c index dfcb2a89..4cec7740 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -577,6 +577,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { #if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 13 cc_params[cc_par_cnt++] = "-Wl,--lto-legacy-pass-manager"; +#else + cc_params[cc_par_cnt++] = "-fno-experimental-new-pass-manager"; #endif cc_params[cc_par_cnt++] = "-Wl,--allow-multiple-definition"; diff --git a/test/test-llvm-lto.sh b/test/test-llvm-lto.sh index 9ff2ec10..bb4a9f7c 100755 --- a/test/test-llvm-lto.sh +++ b/test/test-llvm-lto.sh @@ -49,6 +49,9 @@ test -e ../afl-clang-lto -a -e ../SanitizerCoverageLTO.so && { grep -q "No instrumentation targets found" test.out && { $ECHO "$GREEN[+] llvm_mode LTO instrumentlist feature works correctly" } || { + echo CUT------------------------------------------------------------------CUT + cat test.out + echo CUT------------------------------------------------------------------CUT $ECHO "$RED[!] llvm_mode LTO instrumentlist feature failed" CODE=1 } -- cgit 1.4.1 From 772e33d5500d80f913f7183c616b2eb222b15fc9 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 30 Mar 2022 20:32:51 +0200 Subject: avoid compiler warning (format-truncation), needed for make DEBUG=1 all --- src/afl-fuzz-bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 971ac494..99f37cbf 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -776,7 +776,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { u8 fn_log[PATH_MAX]; - snprintf(fn_log, PATH_MAX, "%s.log", fn); + (void)(snprintf(fn_log, PATH_MAX, "%s.log", fn) + 1); fd = open(fn_log, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn_log); } -- cgit 1.4.1 From 285a5cb38b994b514744c49bad409a49210765d4 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 31 Mar 2022 15:35:38 +0000 Subject: Some scan-build fixes --- instrumentation/SanitizerCoveragePCGUARD.so.cc | 27 ++++++++++++++++++++++++++ instrumentation/afl-llvm-dict2file.so.cc | 8 +++++--- instrumentation/cmplog-instructions-pass.cc | 17 ++++++++-------- src/afl-cc.c | 14 ++++++++++++- src/afl-fuzz-cmplog.c | 10 +--------- src/afl-fuzz-redqueen.c | 2 +- 6 files changed, 56 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index e234cf57..f80b1a1e 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -932,6 +932,15 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( IRBuilder<> IRB(callInst); + if (!FunctionGuardArray) { + + fprintf(stderr, + "SANCOV: FunctionGuardArray is NULL, failed to emit " + "instrumentation."); + continue; + + } + Value *GuardPtr = IRB.CreateIntToPtr( IRB.CreateAdd( IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), @@ -957,6 +966,15 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( if (t->getTypeID() == llvm::Type::IntegerTyID) { + if (!FunctionGuardArray) { + + fprintf(stderr, + "SANCOV: FunctionGuardArray is NULL, failed to emit " + "instrumentation."); + continue; + + } + auto GuardPtr1 = IRB.CreateIntToPtr( IRB.CreateAdd( IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), @@ -993,6 +1011,15 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( FixedVectorType::get(Int32PtrTy, elements); Value *x, *y; + if (!FunctionGuardArray) { + + fprintf(stderr, + "SANCOV: FunctionGuardArray is NULL, failed to emit " + "instrumentation."); + continue; + + } + Value *val1 = IRB.CreateIntToPtr( IRB.CreateAdd( IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 79cdf491..31aaab07 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -536,15 +536,17 @@ bool AFLdict2filePass::runOnModule(Module &M) { } - if (optLength > Str2.length()) { optLength = Str2.length(); } - } valueMap[Str1P] = new std::string(Str2); - if (debug) + if (debug) { + fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), (void *)Str1P); + + } + continue; } diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 7c95d9bb..fd7930a1 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -515,7 +515,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { while (1) { std::vector args; - uint32_t skip = 0; + bool skip = true; if (vector_cnt) { @@ -537,16 +537,18 @@ bool CmpLogInstructions::hookInstrs(Module &M) { if (i0) { cur_val = (uint64_t)i0->getValue().convertToDouble(); - if (last_val0 && last_val0 == cur_val) { skip = 1; } - last_val0 = cur_val; + if (last_val0 && last_val0 == cur_val) { skip = true; + + } last_val0 = cur_val; } if (i1) { cur_val = (uint64_t)i1->getValue().convertToDouble(); - if (last_val1 && last_val1 == cur_val) { skip = 1; } - last_val1 = cur_val; + if (last_val1 && last_val1 == cur_val) { skip = true; + + } last_val1 = cur_val; } @@ -559,7 +561,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { if (i0 && i0->uge(0xffffffffffffffff) == false) { cur_val = i0->getZExtValue(); - if (last_val0 && last_val0 == cur_val) { skip = 1; } + if (last_val0 && last_val0 == cur_val) { skip = true; } last_val0 = cur_val; } @@ -567,7 +569,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) { if (i1 && i1->uge(0xffffffffffffffff) == false) { cur_val = i1->getZExtValue(); - if (last_val1 && last_val1 == cur_val) { skip = 1; } + if (last_val1 && last_val1 == cur_val) { skip = true; } last_val1 = cur_val; } @@ -649,7 +651,6 @@ bool CmpLogInstructions::hookInstrs(Module &M) { ++cur; if (cur >= vector_cnt) { break; } - skip = 0; } diff --git a/src/afl-cc.c b/src/afl-cc.c index 4cec7740..ffdda386 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -566,7 +566,19 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - if (!ld_path || !*ld_path) { ld_path = strdup("ld.lld"); } + if (!ld_path || !*ld_path) { + + if (ld_path) { + + // Freeing empty string + free(ld_path); + + } + + ld_path = strdup("ld.lld"); + + } + if (!ld_path) { PFATAL("Could not allocate mem for ld_path"); } #if defined(AFL_CLANG_LDPATH) && LLVM_MAJOR >= 12 cc_params[cc_par_cnt++] = alloc_printf("--ld-path=%s", ld_path); diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index 1a8052a0..7d94085d 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -49,7 +49,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; - len = write_to_testcase(afl, out_buf, len, 0); + write_to_testcase(afl, out_buf, len, 0); fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout); @@ -81,14 +81,6 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { } - /* This handles FAULT_ERROR for us: */ - - /* afl->queued_discovered += save_if_interesting(afl, argv, out_buf, len, - fault); - - if (!(afl->stage_cur % afl->stats_update_freq) || afl->stage_cur + 1 == - afl->stage_max) show_stats(afl); */ - return 0; } diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 2f32ef1e..2dbad5cf 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -1969,7 +1969,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 || l1 > 31 || ol0 > 31 || ol1 > 31) { - l0 = l1 = ol0 = ol1 = hshape; + l0 = ol0 = hshape; } -- cgit 1.4.1