Skip to content

Commit

Permalink
Resolver Injection (secure-software-engineering#717)
Browse files Browse the repository at this point in the history
* Add ctor to LLVMBasedICFG that allows injecting a CG resolver

* Low-hanging fruits in resolvers

* Remove out-commented code + unnecessary includes

* Make the docker push pipeline work again
  • Loading branch information
fabianbs96 authored Apr 25, 2024
1 parent fc0147f commit 488da6a
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 40 deletions.
10 changes: 10 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
namespace psr {
class LLVMTypeHierarchy;
class LLVMProjectIRDB;
class Resolver;

class LLVMBasedICFG;
template <> struct CFGTraits<LLVMBasedICFG> : CFGTraits<LLVMBasedCFG> {};
Expand Down Expand Up @@ -87,6 +88,11 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
LLVMAliasInfoRef PT = nullptr,
Soundness S = Soundness::Soundy,
bool IncludeGlobals = true);
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints = {},
LLVMTypeHierarchy *TH = nullptr,
Soundness S = Soundness::Soundy,
bool IncludeGlobals = true);

/// Creates an ICFG with an already given call-graph
explicit LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB,
Expand Down Expand Up @@ -157,6 +163,10 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
[[nodiscard]] llvm::Function *buildCRuntimeGlobalCtorsDtorsModel(
llvm::Module &M, llvm::ArrayRef<llvm::Function *> UserEntryPoints);

void initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints,
LLVMTypeHierarchy *TH, Soundness S, bool IncludeGlobals);

// ---

CallGraph<const llvm::Instruction *, const llvm::Function *> CG;
Expand Down
4 changes: 1 addition & 3 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/OTFResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,14 @@ class Value;

namespace psr {

class LLVMBasedICFG;
class LLVMTypeHierarchy;

class OTFResolver : public Resolver {
protected:
LLVMBasedICFG &ICF;
LLVMAliasInfoRef PT;

public:
OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH, LLVMBasedICFG &ICF,
OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH,
LLVMAliasInfoRef PT);

~OTFResolver() override = default;
Expand Down
8 changes: 4 additions & 4 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ namespace psr {
class LLVMProjectIRDB;
class LLVMTypeHierarchy;
enum class CallGraphAnalysisType;
class LLVMBasedICFG;
class LLVMPointsToInfo;

[[nodiscard]] std::optional<unsigned>
Expand Down Expand Up @@ -83,9 +82,10 @@ class Resolver {

[[nodiscard]] virtual std::string str() const = 0;

static std::unique_ptr<Resolver>
create(CallGraphAnalysisType Ty, LLVMProjectIRDB *IRDB, LLVMTypeHierarchy *TH,
LLVMBasedICFG *ICF = nullptr, LLVMAliasInfoRef PT = nullptr);
static std::unique_ptr<Resolver> create(CallGraphAnalysisType Ty,
LLVMProjectIRDB *IRDB,
LLVMTypeHierarchy *TH,
LLVMAliasInfoRef PT = nullptr);
};
} // namespace psr

Expand Down
58 changes: 37 additions & 21 deletions lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"

#include "phasar/Config/Configuration.h"
#include "phasar/ControlFlow/CallGraph.h"
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
Expand All @@ -24,27 +23,22 @@
#include "phasar/Utils/MaybeUniquePtr.h"
#include "phasar/Utils/PAMMMacros.h"
#include "phasar/Utils/Soundness.h"
#include "phasar/Utils/TypeTraits.h"
#include "phasar/Utils/Utilities.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/Support/ErrorHandling.h"

#include <cstdint>
#include <utility>

namespace psr {
struct LLVMBasedICFG::Builder {
LLVMProjectIRDB *IRDB = nullptr;
LLVMAliasInfoRef PT{};
LLVMTypeHierarchy *TH{};
Resolver *Res = nullptr;
CallGraphBuilder<const llvm::Instruction *, const llvm::Function *>
CGBuilder{};
std::unique_ptr<Resolver> Res = nullptr;
llvm::DenseSet<const llvm::Function *> VisitedFunctions{};
llvm::SmallVector<llvm::Function *, 1> UserEntryPoints{};

Expand Down Expand Up @@ -321,6 +315,28 @@ bool LLVMBasedICFG::Builder::constructDynamicCall(const llvm::Instruction *CS) {
return NewTargetsFound;
}

void LLVMBasedICFG::initialize(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints,
LLVMTypeHierarchy *TH, Soundness S,
bool IncludeGlobals) {
Builder B{IRDB, this->TH.get(), &CGResolver};

B.initEntryPoints(EntryPoints);
B.initGlobalsAndWorkList(this, IncludeGlobals);

PHASAR_LOG_LEVEL_CAT(
INFO, "LLVMBasedICFG",
"Starting ICFG construction "
<< std::chrono::steady_clock::now().time_since_epoch().count());

this->CG = B.buildCallGraph(S);

PHASAR_LOG_LEVEL_CAT(
INFO, "LLVMBasedICFG",
"Finished ICFG construction "
<< std::chrono::steady_clock::now().time_since_epoch().count());
}

LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB,
CallGraphAnalysisType CGType,
llvm::ArrayRef<std::string> EntryPoints,
Expand All @@ -333,29 +349,29 @@ LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB,
this->TH = std::make_unique<LLVMTypeHierarchy>(*IRDB);
}

Builder B{IRDB, PT, this->TH.get()};
LLVMAliasInfo PTOwn;

if (!PT && CGType == CallGraphAnalysisType::OTF) {
PTOwn = std::make_unique<LLVMAliasSet>(IRDB);
B.PT = PTOwn.asRef();
PT = PTOwn.asRef();
}

B.Res = Resolver::create(CGType, IRDB, this->TH.get(), this, B.PT);
B.initEntryPoints(EntryPoints);
B.initGlobalsAndWorkList(this, IncludeGlobals);
auto CGRes = Resolver::create(CGType, IRDB, this->TH.get(), PT);
initialize(IRDB, *CGRes, EntryPoints, TH, S, IncludeGlobals);
}

PHASAR_LOG_LEVEL_CAT(
INFO, "LLVMBasedICFG",
"Starting ICFG construction "
<< std::chrono::steady_clock::now().time_since_epoch().count());
LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints,
LLVMTypeHierarchy *TH, Soundness S,
bool IncludeGlobals)
: IRDB(IRDB), TH(TH) {
assert(IRDB != nullptr);

this->CG = B.buildCallGraph(S);
if (!TH) {
this->TH = std::make_unique<LLVMTypeHierarchy>(*IRDB);
}

PHASAR_LOG_LEVEL_CAT(
INFO, "LLVMBasedICFG",
"Finished ICFG construction "
<< std::chrono::steady_clock::now().time_since_epoch().count());
initialize(IRDB, CGResolver, EntryPoints, TH, S, IncludeGlobals);
}

LLVMBasedICFG::LLVMBasedICFG(CallGraph<n_t, f_t> CG, LLVMProjectIRDB *IRDB,
Expand Down
6 changes: 3 additions & 3 deletions lib/PhasarLLVM/ControlFlow/Resolver/OTFResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
using namespace psr;

OTFResolver::OTFResolver(LLVMProjectIRDB &IRDB, LLVMTypeHierarchy &TH,
LLVMBasedICFG &ICF, LLVMAliasInfoRef PT)
: Resolver(IRDB, TH), ICF(ICF), PT(PT) {}
LLVMAliasInfoRef PT)
: Resolver(IRDB, TH), PT(PT) {}

void OTFResolver::preCall(const llvm::Instruction *Inst) {}

Expand All @@ -55,7 +55,7 @@ void OTFResolver::handlePossibleTargets(const llvm::CallBase *CallSite,
}
// handle return value
if (CalleeTarget->getReturnType()->isPointerTy()) {
for (const auto &ExitPoint : ICF.getExitPointsOf(CalleeTarget)) {
for (const auto &ExitPoint : psr::getAllExitPoints(CalleeTarget)) {
// get the function's return value
if (const auto *Ret = llvm::dyn_cast<llvm::ReturnInst>(ExitPoint)) {
// introduce alias to the returned value
Expand Down
5 changes: 1 addition & 4 deletions lib/PhasarLLVM/ControlFlow/Resolver/RTAResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ void RTAResolver::resolveAllocatedStructTypes() {
}

llvm::DenseSet<const llvm::StructType *> AllocatedStructTypes;
const llvm::StringSet<> MemAllocatingFunctions = {"_Znwm", "_Znam", "malloc",
"calloc", "realloc"};

for (const auto *Fun : IRDB.getAllFunctions()) {
for (const auto &Inst : llvm::instructions(Fun)) {
Expand All @@ -114,8 +112,7 @@ void RTAResolver::resolveAllocatedStructTypes() {
// check if an instance of a user-defined type is allocated on the
// heap

if (!MemAllocatingFunctions.contains(
CallSite->getCalledFunction()->getName())) {
if (!isHeapAllocatingFunction(CallSite->getCalledFunction())) {
continue;
}
/// TODO: Does this iteration over the users make sense?
Expand Down
6 changes: 2 additions & 4 deletions lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ auto Resolver::resolveFunctionPointer(const llvm::CallBase *CallSite)
FunctionSetTy CalleeTargets;

for (const auto *F : IRDB.getAllFunctions()) {
if (isConsistentCall(CallSite, F)) {
if (F->hasAddressTaken() && isConsistentCall(CallSite, F)) {
CalleeTargets.insert(F);
}
}
Expand All @@ -158,7 +158,6 @@ void Resolver::otherInst(const llvm::Instruction *Inst) {}
std::unique_ptr<Resolver> Resolver::create(CallGraphAnalysisType Ty,
LLVMProjectIRDB *IRDB,
LLVMTypeHierarchy *TH,
LLVMBasedICFG *ICF,
LLVMAliasInfoRef PT) {
assert(IRDB != nullptr);

Expand All @@ -179,9 +178,8 @@ std::unique_ptr<Resolver> Resolver::create(CallGraphAnalysisType Ty,
"The VTA callgraph algorithm is not implemented yet");
case CallGraphAnalysisType::OTF:
assert(TH != nullptr);
assert(ICF != nullptr);
assert(PT);
return std::make_unique<OTFResolver>(*IRDB, *TH, *ICF, PT);
return std::make_unique<OTFResolver>(*IRDB, *TH, PT);
case CallGraphAnalysisType::Invalid:
llvm::report_fatal_error("Invalid callgraph algorithm specified");
}
Expand Down
2 changes: 1 addition & 1 deletion utils/InstallAptDependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ set -e

sudo apt-get update
sudo apt-get install git -y
sudo apt-get install zlib1g-dev python3 g++ ninja-build cmake -y
sudo apt-get install zlib1g-dev python3 python3-pip g++ ninja-build cmake -y

0 comments on commit 488da6a

Please sign in to comment.