Skip to content

Commit

Permalink
Add test
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianbs96 committed May 10, 2024
1 parent 1710a27 commit 6f2c0a2
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 10 deletions.
13 changes: 6 additions & 7 deletions include/phasar/PhasarLLVM/Pointer/FilteredLLVMAliasSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "phasar/Pointer/AliasSetOwner.h"
#include "phasar/Utils/AnalysisProperties.h"
#include "phasar/Utils/MaybeUniquePtr.h"
#include "phasar/Utils/StableVector.h"

#include "llvm/Support/ErrorHandling.h"

Expand Down Expand Up @@ -53,9 +52,10 @@ class FilteredLLVMAliasSet {

FilteredLLVMAliasSet(const FilteredLLVMAliasSet &) = delete;
FilteredLLVMAliasSet &operator=(const FilteredLLVMAliasSet &) = delete;
FilteredLLVMAliasSet(FilteredLLVMAliasSet &&) = delete;
FilteredLLVMAliasSet &operator=(FilteredLLVMAliasSet &&) = delete;

FilteredLLVMAliasSet(FilteredLLVMAliasSet &&) noexcept = default;

~FilteredLLVMAliasSet();

template <typename... ArgsT,
Expand Down Expand Up @@ -95,9 +95,9 @@ class FilteredLLVMAliasSet {
llvm::report_fatal_error("Not Supported");
}

void introduceAlias(const llvm::Value *V1, const llvm::Value *V2,
const llvm::Instruction *I = nullptr,
AliasResult Kind = AliasResult::MustAlias) {
void introduceAlias(const llvm::Value * /*V1*/, const llvm::Value * /*V2*/,
const llvm::Instruction * /*I*/ = nullptr,
AliasResult /*Kind*/ = AliasResult::MustAlias) {
llvm::report_fatal_error("Not Supported");
}

Expand All @@ -115,8 +115,7 @@ class FilteredLLVMAliasSet {
FilteredLLVMAliasSet(MaybeUniquePtr<LLVMAliasSet, true> AS) noexcept;

MaybeUniquePtr<LLVMAliasSet, true> AS;
AliasSetOwner<AliasSetTy>::memory_resource_type MRes;
AliasSetOwner<AliasSetTy> Owner{&MRes};
AliasSetOwner<AliasSetTy> Owner;
llvm::DenseMap<std::pair<const llvm::Function *, v_t>, AliasSetPtrTy>
AliasSetMap;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ void IFDSTaintAnalysis::populateWithMayAliases(
container_type &Facts, const llvm::Instruction *Context) const {
container_type Tmp = Facts;
for (const auto *Fact : Facts) {
auto Aliases = PT.getAliasSet(Fact);
auto Aliases = PT.getAliasSet(Fact, Context);
for (const auto *Alias : *Aliases) {
if (canSkipAtContext(Alias, Context)) {
continue;
Expand Down
6 changes: 4 additions & 2 deletions lib/PhasarLLVM/Pointer/FilteredLLVMAliasSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,13 @@ static void fillAliasSet(FilteredLLVMAliasSet::AliasSetTy &Set,
}

FilteredLLVMAliasSet::FilteredLLVMAliasSet(LLVMAliasSet *AS) noexcept
: AS(AS) {}
: AS(AS), Owner(&AS->MRes) {}

FilteredLLVMAliasSet::FilteredLLVMAliasSet(
MaybeUniquePtr<LLVMAliasSet, true> AS) noexcept
: AS(std::move(AS)) {}
: AS(std::move(AS)), Owner(&this->AS->MRes) {}

FilteredLLVMAliasSet::~FilteredLLVMAliasSet() = default;

AliasAnalysisType FilteredLLVMAliasSet::getAliasAnalysisType() const noexcept {
return AS->getAliasAnalysisType();
Expand Down
1 change: 1 addition & 0 deletions unittests/PhasarLLVM/Pointer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(ControlFlowSources
LLVMAliasSetTest.cpp
LLVMAliasSetSerializationTest.cpp
FilteredLLVMAliasSetTest.cpp
)

foreach(TEST_SRC ${ControlFlowSources})
Expand Down
138 changes: 138 additions & 0 deletions unittests/PhasarLLVM/Pointer/FilteredLLVMAliasSetTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include "phasar/PhasarLLVM/Pointer/FilteredLLVMAliasSet.h"

#include "phasar/ControlFlow/CallGraphAnalysisType.h"
#include "phasar/DataFlow/IfdsIde/Solver/IFDSSolver.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"
#include "phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IFDSTaintAnalysis.h"
#include "phasar/PhasarLLVM/Pointer/LLVMAliasSet.h"
#include "phasar/PhasarLLVM/TaintConfig/LLVMTaintConfig.h"
#include "phasar/PhasarLLVM/Utils/LLVMShorthands.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/IR/InstrTypes.h"

#include "TestConfig.h"
#include "gtest/gtest.h"

using namespace psr;

namespace {

static LLVMTaintConfig getDefaultConfig() {
auto SourceCB = [](const llvm::Instruction *Inst) {
std::set<const llvm::Value *> Ret;
if (const auto *Call = llvm::dyn_cast<llvm::CallBase>(Inst);
Call && Call->getCalledFunction() &&
Call->getCalledFunction()->getName() == "_Z6sourcev") {
Ret.insert(Call);
}
return Ret;
};
auto SinkCB = [](const llvm::Instruction *Inst) {
std::set<const llvm::Value *> Ret;
if (const auto *Call = llvm::dyn_cast<llvm::CallBase>(Inst);
Call && Call->getCalledFunction() &&
Call->getCalledFunction()->getName() == "_Z4sinki") {
assert(Call->arg_size() > 0);
Ret.insert(Call->getArgOperand(0));
}
return Ret;
};
return LLVMTaintConfig(std::move(SourceCB), std::move(SinkCB));
}

static LLVMTaintConfig getDoubleFreeConfig() {
auto SourceCB = [](const llvm::Instruction *Inst) {
std::set<const llvm::Value *> Ret;
if (const auto *Call = llvm::dyn_cast<llvm::CallBase>(Inst);
Call && Call->getCalledFunction() &&
Call->getCalledFunction()->getName() == "free") {
Ret.insert(Call->getArgOperand(0));
}
return Ret;
};

return LLVMTaintConfig(SourceCB, SourceCB);
}

class TaintAnalysis : public ::testing::TestWithParam<std::string_view> {
protected:
static constexpr auto PathToLlFiles =
PHASAR_BUILD_SUBFOLDER("taint_analysis/");
const std::vector<std::string> EntryPoints = {"main"};

}; // Test Fixture

TEST_P(TaintAnalysis, LeaksWithAndWithoutAliasFilteringEqual) {

LLVMProjectIRDB IRDB(PathToLlFiles + GetParam());
LLVMAliasSet AS(&IRDB, false);
FilteredLLVMAliasSet FAS(&AS);
LLVMBasedICFG ICF(&IRDB, CallGraphAnalysisType::OTF, EntryPoints, nullptr,
&AS);

auto TSF = llvm::StringRef(GetParam()).startswith("double_free")
? getDoubleFreeConfig()
: getDefaultConfig();

IFDSTaintAnalysis TaintProblem(&IRDB, &AS, &TSF, EntryPoints);
IFDSTaintAnalysis FilterTaintProblem(&IRDB, &FAS, &TSF, EntryPoints);

solveIFDSProblem(TaintProblem, ICF).dumpResults(ICF);
solveIFDSProblem(FilterTaintProblem, ICF).dumpResults(ICF);

EXPECT_EQ(TaintProblem.Leaks.size(), FilterTaintProblem.Leaks.size());

for (const auto &[LeakInst, LeakFacts] : TaintProblem.Leaks) {
const auto It = FilterTaintProblem.Leaks.find(LeakInst);

EXPECT_NE(It, FilterTaintProblem.Leaks.end())
<< "Expected to find leak at " + llvmIRToString(LeakInst);

if (It == FilterTaintProblem.Leaks.end()) {
continue;
}

for (const auto *LeakFact : LeakFacts) {
EXPECT_TRUE(It->second.count(LeakFact))
<< "Expected to find leak-fact " + llvmIRToShortString(LeakFact) +
" at " + llvmIRToString(LeakInst);
}
}
}

static constexpr std::string_view TaintTestFiles[] = {
// -- dummy-source-sink
"dummy_source_sink/taint_01_cpp_dbg.ll",
"dummy_source_sink/taint_01_cpp_m2r_dbg.ll",
"dummy_source_sink/taint_02_cpp_dbg.ll",
"dummy_source_sink/taint_03_cpp_dbg.ll",
"dummy_source_sink/taint_04_cpp_dbg.ll",
"dummy_source_sink/taint_05_cpp_dbg.ll",
"dummy_source_sink/taint_06_cpp_m2r_dbg.ll",
"dummy_source_sink/taint_exception_01_cpp_dbg.ll",
"dummy_source_sink/taint_exception_01_cpp_m2r_dbg.ll",
"dummy_source_sink/taint_exception_02_cpp_dbg.ll",
"dummy_source_sink/taint_exception_03_cpp_dbg.ll",
"dummy_source_sink/taint_exception_04_cpp_dbg.ll",
"dummy_source_sink/taint_exception_05_cpp_dbg.ll",
"dummy_source_sink/taint_exception_06_cpp_dbg.ll",
"dummy_source_sink/taint_exception_07_cpp_dbg.ll",
"dummy_source_sink/taint_exception_08_cpp_dbg.ll",
"dummy_source_sink/taint_exception_09_cpp_dbg.ll",
"dummy_source_sink/taint_exception_10_cpp_dbg.ll",
// -- double-free
"double_free_01_c.ll",
"double_free_02_c.ll",
};

INSTANTIATE_TEST_SUITE_P(InteractiveIDESolverTest, TaintAnalysis,
::testing::ValuesIn(TaintTestFiles));

} // namespace

int main(int Argc, char **Argv) {
::testing::InitGoogleTest(&Argc, Argv);
return RUN_ALL_TESTS();
}

0 comments on commit 6f2c0a2

Please sign in to comment.