diff --git a/include/phasar/PhasarLLVM/TaintConfig/LLVMTaintConfig.h b/include/phasar/PhasarLLVM/TaintConfig/LLVMTaintConfig.h index 31115da094..cec911eeba 100644 --- a/include/phasar/PhasarLLVM/TaintConfig/LLVMTaintConfig.h +++ b/include/phasar/PhasarLLVM/TaintConfig/LLVMTaintConfig.h @@ -87,7 +87,7 @@ class LLVMTaintConfig : public TaintConfigBase { [[nodiscard]] std::map> - makeInitialSeedsImpl() const; + makeInitialSeedsImpl(SeedConfig Conf) const; void printImpl(llvm::raw_ostream &OS) const; diff --git a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigBase.h b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigBase.h index 422a06a5bd..d3473739af 100644 --- a/include/phasar/PhasarLLVM/TaintConfig/TaintConfigBase.h +++ b/include/phasar/PhasarLLVM/TaintConfig/TaintConfigBase.h @@ -41,6 +41,13 @@ template class TaintConfigBase { using TaintDescriptionCallBackTy = llvm::unique_function(n_t) const>; + enum class [[clang::flag_enum]] SeedConfig { + Arguments = 1, + Instructions = 2, + + All = Arguments | Instructions, + }; + void registerSourceCallBack(TaintDescriptionCallBackTy CB) noexcept { SourceCallBack = std::move(CB); } @@ -124,8 +131,9 @@ template class TaintConfigBase { return self().getCategoryImpl(std::move(Val)); } - [[nodiscard]] std::map> makeInitialSeeds() const { - return self().makeInitialSeedsImpl(); + [[nodiscard]] std::map> + makeInitialSeeds(SeedConfig Conf = SeedConfig::All) const { + return self().makeInitialSeedsImpl(Conf); } void print(llvm::raw_ostream &OS = llvm::outs()) const { diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/LibCSummary.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/LibCSummary.cpp index aa6c64f1bc..4dff8c690c 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/LibCSummary.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/LibCSummary.cpp @@ -8,6 +8,8 @@ using namespace psr::library_summary; static library_summary::FunctionDataFlowFacts createLibCSummary() { FunctionDataFlowFacts Sum; + Sum.addElement("atoi", 0, ReturnValue{}); + // abs Sum.addElement("abs", 0, ReturnValue{}); diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp index 8d1c1d9a73..83e0d91788 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEExtendedTaintAnalysis.cpp @@ -30,6 +30,7 @@ #include "llvm/IR/GlobalValue.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/WithColor.h" #include #include @@ -54,9 +55,10 @@ IDEExtendedTaintAnalysis::initialSeeds() { this->base_t::getZeroValue(), bottomElement()); if (Seeds.empty()) { - llvm::errs() << "WARNING: No initial seeds specified, skip the analysis. " - "Please specify an entrypoint function or in the " - "TaintConfig a source llvm::Instruction*\n"; + llvm::WithColor::warning() + << "No initial seeds specified, skip the analysis. " + "Please specify an entrypoint function or in the " + "TaintConfig a source llvm::Instruction*\n"; } return Seeds; diff --git a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.cpp b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.cpp index 28b8b65f0a..977da7ab7f 100644 --- a/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.cpp +++ b/lib/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.cpp @@ -33,6 +33,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include @@ -280,8 +281,8 @@ auto IFDSTaintAnalysis::getNormalFlowFunction(n_t Curr, Gen.insert(Store->getValueOperand()); } - return lambdaFlow( - [Store, Gen{std::move(Gen)}](d_t Source) -> container_type { + auto Ret = + lambdaFlow([Store, Gen{std::move(Gen)}](d_t Source) -> container_type { if (Store->getPointerOperand() == Source) { return {}; } @@ -291,6 +292,21 @@ auto IFDSTaintAnalysis::getNormalFlowFunction(n_t Curr, return {Source}; }); + if (Config->isSink(Store->getPointerOperand())) { + // Handle sink variables: + + return lambdaFlow([this, Store, Ret = std::move(Ret)](d_t Source) { + if (Store->getValueOperand() == Source) { + if (Leaks[Store].insert(Source).second) { + Printer->onResult(Store, Source, + DataFlowAnalysisType::IFDSTaintAnalysis); + } + } + + return Ret->computeTargets(Source); + }); + } + return Ret; } // If a tainted value is loaded, the loaded value is of course tainted if (const auto *Load = llvm::dyn_cast(Curr)) { @@ -316,6 +332,16 @@ auto IFDSTaintAnalysis::getNormalFlowFunction(n_t Curr, return transferFlow(Cast, Cast->getOperand(0)); } + if (llvm::isa(Curr)) { + return lambdaFlow([Curr](d_t Source) -> container_type { + if (llvm::is_contained(Curr->operand_values(), Source)) { + return {Source, Curr}; + } + + return {Source}; + }); + } + // Otherwise we do not care and leave everything as it is return identityFlow(); } @@ -489,7 +515,10 @@ auto IFDSTaintAnalysis::getSummaryFlowFunction([[maybe_unused]] n_t CallSite, auto IFDSTaintAnalysis::initialSeeds() -> InitialSeeds { PHASAR_LOG_LEVEL(DEBUG, "IFDSTaintAnalysis::initialSeeds()"); - InitialSeeds Seeds; + // Instructions are generated from zero on-the-fly, but args must be generated + // explicitly as seeds + InitialSeeds Seeds = + Config->makeInitialSeeds(LLVMTaintConfig::SeedConfig::Arguments); LLVMBasedCFG C; addSeedsForStartingPoints(EntryPoints, IRDB, C, Seeds, getZeroValue(), @@ -507,6 +536,13 @@ auto IFDSTaintAnalysis::initialSeeds() -> InitialSeeds { } } + if (Seeds.empty()) { + llvm::WithColor::warning() + << "No initial seeds specified, skip the analysis. " + "Please specify an entrypoint function or in the " + "TaintConfig a source llvm::Instruction*\n"; + } + return Seeds; } diff --git a/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp b/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp index a6ece0452f..885adf8339 100644 --- a/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp +++ b/lib/PhasarLLVM/TaintConfig/LLVMTaintConfig.cpp @@ -14,6 +14,7 @@ #include "phasar/PhasarLLVM/TaintConfig/TaintConfigBase.h" #include "phasar/PhasarLLVM/Utils/Annotation.h" #include "phasar/PhasarLLVM/Utils/LLVMShorthands.h" +#include "phasar/Utils/EnumFlags.h" #include "phasar/Utils/Logger.h" #include "llvm/ADT/SmallVector.h" @@ -457,17 +458,21 @@ TaintCategory LLVMTaintConfig::getCategoryImpl(const llvm::Value *V) const { } std::map> -LLVMTaintConfig::makeInitialSeedsImpl() const { +LLVMTaintConfig::makeInitialSeedsImpl(SeedConfig Conf) const { std::map> InitialSeeds; for (const auto *SourceValue : SourceValues) { if (const auto *Inst = llvm::dyn_cast(SourceValue)) { - InitialSeeds[Inst].insert(Inst); + if (hasFlag(Conf, SeedConfig::Instructions)) { + InitialSeeds[Inst].insert(Inst); + } } else if (const auto *Arg = llvm::dyn_cast(SourceValue); Arg && !Arg->getParent()->isDeclaration()) { - LLVMBasedCFG C; - for (const auto *SP : C.getStartPointsOf(Arg->getParent())) { - InitialSeeds[SP].insert(Arg); + if (hasFlag(Conf, SeedConfig::Arguments)) { + LLVMBasedCFG C; + for (const auto *SP : C.getStartPointsOf(Arg->getParent())) { + InitialSeeds[SP].insert(Arg); + } } } } diff --git a/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp b/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp index 0d410ccbc1..9d91efd7d0 100644 --- a/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp +++ b/tools/phasar-cli/Controller/AnalysisControllerXIFDSTaint.cpp @@ -15,5 +15,8 @@ using namespace psr; void controller::executeIFDSTaint(AnalysisController &Data) { auto Config = makeTaintConfig(Data); - executeIFDSAnalysis(Data, &Config, Data.EntryPoints); + // Note: Don't blindly generate argc and argv. Use a proper taint config + // instead + executeIFDSAnalysis(Data, &Config, Data.EntryPoints, + false); }