1111#include < type_traits>
1212
1313#include " llvm/ADT/SmallSet.h"
14+ #include " llvm/IR/IntrinsicInst.h"
15+ #include " llvm/Support/Casting.h"
1416
1517#include " phasar/DB/ProjectIRDB.h"
1618#include " phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
3032#include " phasar/Utils/Utilities.h"
3133
3234namespace psr ::XTaint {
33- // Misc:
34-
35- template <typename ContainerTy>
36- inline void printValues (const ContainerTy &Facts,
37- std::ostream &OS = std::cerr) {
38- OS << " {" ;
39-
40- for (const auto *Fact : Facts) {
41- OS << " \n\t " << llvmIRToString (Fact);
42- }
43-
44- if (!Facts.empty ()) {
45- OS << " \n " ;
46- }
47- OS << " }" ;
48- }
4935
5036IDEExtendedTaintAnalysis::IDEExtendedTaintAnalysis (
5137 const ProjectIRDB *IRDB, const LLVMTypeHierarchy *TH,
@@ -138,15 +124,16 @@ IDEExtendedTaintAnalysis::getNormalFlowFunction(n_t Curr,
138124IDEExtendedTaintAnalysis::FlowFunctionPtrType
139125IDEExtendedTaintAnalysis::getStoreFF (const llvm::Value *PointerOp,
140126 const llvm::Value *ValueOp,
141- const llvm::Instruction *Store) {
127+ const llvm::Instruction *Store,
128+ unsigned PALevel) {
142129
143130 auto TV = makeFlowFact (ValueOp);
144131 auto PTS = this ->PT ->getPointsToSet (PointerOp, Store);
145132
146133 auto Mem = makeFlowFact (PointerOp);
147134 return makeLambdaFlow<d_t >([this , TV, Mem, PTS{std::move (PTS)}, PointerOp,
148- ValueOp,
149- Store ](d_t Source) mutable -> std::set<d_t > {
135+ ValueOp, Store,
136+ PALevel ](d_t Source) mutable -> std::set<d_t > {
150137 if (Source->isZero ()) {
151138 std::set<d_t > Ret = {Source};
152139 generateFromZero (Ret, Store, PointerOp, ValueOp,
@@ -160,7 +147,7 @@ IDEExtendedTaintAnalysis::getStoreFF(const llvm::Value *PointerOp,
160147 // / easily reachable from TV by simply doing dome pointer arithmetics.
161148 // / Hence, when loading the value of TV back from Mem this still holds and
162149 // / must be preserved by the analysis.
163- if (TV->equivalentExceptPointerArithmetics (Source)) {
150+ if (TV->equivalentExceptPointerArithmetics (Source, PALevel )) {
164151 auto Offset = Source - TV;
165152
166153 // generate all may-aliases of Store->getPointerOperand()
@@ -322,17 +309,14 @@ IDEExtendedTaintAnalysis::getCallFlowFunction(n_t CallStmt, f_t DestFun) {
322309 return {Source};
323310 }
324311 std::set<d_t > Ret;
325- // / Don't qualify the 'auto' here, because we should not rely on those
326- // / iterators to be pointers
327-
328- // NOLINTNEXTLINE(llvm-qualified-auto, readability-qualified-auto)
329- auto It = call->arg_begin ();
330- // NOLINTNEXTLINE(llvm-qualified-auto, readability-qualified-auto)
331- auto End = call->arg_end ();
332- // NOLINTNEXTLINE(llvm-qualified-auto, readability-qualified-auto)
333- auto FIt = DestFun->arg_begin ();
334- // NOLINTNEXTLINE(llvm-qualified-auto, readability-qualified-auto)
335- auto FEnd = DestFun->arg_end ();
312+
313+ using ArgIterator = llvm::User::const_op_iterator;
314+ using ParamIterator = llvm::Function::const_arg_iterator;
315+
316+ ArgIterator It = call->arg_begin ();
317+ ArgIterator End = call->arg_end ();
318+ ParamIterator FIt = DestFun->arg_begin ();
319+ ParamIterator FEnd = DestFun->arg_end ();
336320
337321 const std::string CalleeName =
338322 (DestFun->hasName ()) ? DestFun->getName ().str () : " none" ;
@@ -390,17 +374,13 @@ IDEExtendedTaintAnalysis::getRetFlowFunction(n_t CallSite, f_t CalleeFun,
390374 d_t Source) {
391375 std::set<d_t > Ret;
392376
393- // / Don't qualify the 'auto' here, because we should not rely on those
394- // / iterators to be pointers
377+ using ArgIterator = llvm::User::const_op_iterator;
378+ using ParamIterator = llvm::Function::const_arg_iterator;
395379
396- // NOLINTNEXTLINE(llvm-qualified-auto, readability-qualified-auto)
397- auto It = Call->arg_begin ();
398- // NOLINTNEXTLINE(llvm-qualified-auto, readability-qualified-auto)
399- auto End = Call->arg_end ();
400- // NOLINTNEXTLINE(llvm-qualified-auto, readability-qualified-auto)
401- auto FIt = CalleeFun->arg_begin ();
402- // NOLINTNEXTLINE(llvm-qualified-auto, readability-qualified-auto)
403- auto FEnd = CalleeFun->arg_end ();
380+ ArgIterator It = Call->arg_begin ();
381+ ArgIterator End = Call->arg_end ();
382+ ParamIterator FIt = CalleeFun->arg_begin ();
383+ ParamIterator FEnd = CalleeFun->arg_end ();
404384
405385 for (; FIt != FEnd && It != End; ++FIt, ++It) {
406386 // Only map back pointer parameters, since for all others we have
@@ -458,12 +438,18 @@ IDEExtendedTaintAnalysis::getSummaryFlowFunction(n_t CallStmt, f_t DestFun) {
458438 return handleConfig (CallStmt, std::move (SrcConfig), std::move (SinkConfig));
459439 }
460440
461- // / TODO: MemSet
462- // ...
463- // } else if (auto MemSet = llvm::dyn_cast<llvm::MemSetInst>(call)) {
464- // // Basically, MemSet is the same as Store
465- // return getStoreFF(MemSet->getDest(), MemSet->getValue(), MemSet);
466- // }
441+ if (const auto *MemSet = llvm::dyn_cast<llvm::MemSetInst>(CallStmt)) {
442+ // / Basically, MemSet is the same as Store
443+ return getStoreFF (MemSet->getRawDest (), MemSet->getValue (), MemSet);
444+ }
445+
446+ if (const auto *MemTrn = llvm::dyn_cast<llvm::MemTransferInst>(CallStmt)) {
447+ // / Basically, MemCpy/MemMove are the same as Store.
448+ // / We just need to take care about the additional level of indirection
449+ // / i.e., not the source itself is stored, but the value it is pointing to
450+ return getStoreFF (MemTrn->getRawDest (), MemTrn->getRawSource (), MemTrn,
451+ /* PALevel*/ 2 );
452+ }
467453
468454 return nullptr ;
469455}
@@ -484,8 +470,6 @@ auto IDEExtendedTaintAnalysis::getNormalEdgeFunction(n_t Curr, d_t CurrNode,
484470
485471 if (EntryPoints.count (Curr->getFunction ()->getName ().str ()) &&
486472 Curr == &Curr->getFunction ()->front ().front ()) {
487- // std::cout << "edge seed: " << CurrNode << " --> " << SuccNode
488- // << " with null\n";
489473 return getGenEdgeFunction (BBO);
490474 }
491475
@@ -494,10 +478,7 @@ auto IDEExtendedTaintAnalysis::getNormalEdgeFunction(n_t Curr, d_t CurrNode,
494478 if (const auto *Store = llvm::dyn_cast<llvm::StoreInst>(Curr)) {
495479 return {Store->getPointerOperand (), Store->getValueOperand ()};
496480 }
497- // / TODO: MemSetInst inherits from CallInst, so move it to summaryEF
498- // if (const auto *MemSet = llvm::dyn_cast<llvm::MemSetInst>(Curr)) {
499- // return {MemSet->getDest(), MemSet->getValue()};
500- // }
481+
501482 return {nullptr , nullptr };
502483 }();
503484
@@ -516,17 +497,12 @@ auto IDEExtendedTaintAnalysis::getNormalEdgeFunction(n_t Curr, d_t CurrNode,
516497
517498 auto SaniConfig = getSanitizerConfigAt (Curr);
518499 if (!SaniConfig.empty ()) {
519- // std::cerr << "NormalEF: handleEdgeConfig at " << llvmIRToString(Curr)
520- // << " on " << CurrNode << " --> " << SuccNode << "\n";
521500 if (isMustAlias (SaniConfig, CurrNode)) {
522501 return makeEF<GenEdgeFunction>(BBO, Curr);
523502 }
524503 }
525504 }
526505
527- // std::cerr << "StoreInst with EdgeID at " << llvmIRToString(Curr) << " on "
528- // << CurrNode << " --> " << SuccNode << "\n";
529-
530506 return getEdgeIdentity (Curr);
531507}
532508
@@ -642,7 +618,11 @@ auto IDEExtendedTaintAnalysis::getSummaryEdgeFunction(n_t Curr, d_t CurrNode,
642618 return makeEF<GenEdgeFunction>(BBO, Curr);
643619 }
644620
645- // / TODO: MemSet
621+ // MemIntrinsic covers memset, memcpy and memmove
622+ if (const auto *MemSet = llvm::dyn_cast<llvm::MemIntrinsic>(Curr);
623+ MemSet && CurrNode->mustAlias (makeFlowFact (MemSet->getRawDest ()), *PT)) {
624+ return makeEF<GenEdgeFunction>(BBO, Curr);
625+ }
646626
647627 return Ret;
648628}
@@ -782,11 +762,6 @@ void IDEExtendedTaintAnalysis::doPostProcessing(
782762 const auto *Load = getApproxLoadFrom (L);
783763
784764 switch (Sani.getKind ()) {
785- // case EdgeDomain::Bot:
786- // rem.push_back(L);
787- // std::cerr << "Sanitize " << llvmIRToShortString(L) << " with Bottom "
788- // << std::endl;
789- // break;
790765 case EdgeDomain::Sanitized:
791766 Rem.push_back (L);
792767 std::cerr << " Sanitize " << llvmIRToShortString (L) << " from parent "
0 commit comments