18 #ifndef CHECKER_PSA_VULNERABILITY_H
19 #define CHECKER_PSA_VULNERABILITY_H
21 #include <llvm/Pass.h>
23 #include "IR/SEG/SEGCallSite.h"
24 #include "IR/SEG/SEGReturnSite.h"
25 #include "IR/SEG/SymbolicExprGraph.h"
26 #include "IR/SEG/SymbolicExprGraphSolver.h"
27 #include "Report/BugReport/BugReportMgr.h"
28 #include "VulnerabilityTrace.h"
29 #include "VulnerabilityTraceBuilder.h"
31 #include "Checker/PSA/PSAReportDecoratorDefault.h"
32 #include "Checker/PSA/PSATaintReportDecorator.h"
33 #include "IR/SEG/SEGCallSiteOutputNode.h"
34 #include "IR/SEG/SEGSimpleSite.h"
90 typedef typename std::pair<const SEGOperandNode *, const SEGSiteBase *>
109 bool Parasitical =
true;
111 const char *VulnName;
112 const BugDescription::BugImportance Importance;
113 const BugDescription::BugClassification Classification;
114 const char *VulnDescription;
120 const BugDescription::BugImportance Importance,
121 const BugDescription::BugClassification Classification,
123 : CategoryType(CTy), VulnName(Name), Importance(Importance),
124 Classification(Classification), VulnDescription(Desc) {}
132 friend class TSAVulnerability;
144 std::vector<ValueSitePairType> &Sources) = 0;
158 const VulnerabilityTraceBuilder &TraceHistory,
159 SMTExprVec &Prerequisites) = 0;
172 const VulnerabilityTraceBuilder &TraceHistory) {
179 virtual bool finalCheck(
const VulnerabilityTraceBuilder &TraceHistory) {
191 std::list<shared_ptr<VulnerabilityTrace>> &AllTraces) {
206 virtual SiteType checkSite(
const SEGSiteBase *CurrSite,
207 const VulnerabilityTraceBuilder &TraceHistory) = 0;
211 virtual bool checkTrace(std::shared_ptr<VulnerabilityTrace> &Trace) {
237 VulnerabilityCategoryType getCategoryType()
const {
return CategoryType; }
244 void setParasitical(
bool B) { Parasitical = B; }
249 BugDescription::BugImportance getImportance()
const {
return Importance; }
251 BugDescription::BugClassification getClassification()
const {
252 return Classification;
258 virtual PSAReportDecoratorDefault *allocNewDecorator() {
259 return new PSAReportDecoratorDefault;
262 virtual void destroyDecorator(PSAReportDecoratorDefault *decorator) {
272 const char *Name,
const BugDescription::BugImportance importance,
273 const BugDescription::BugClassification classification,
const char *Desc)
274 :
Vulnerability(VCT_SinkMustReach, Name, importance, classification,
283 const char *Name,
const BugDescription::BugImportance Importance,
284 const BugDescription::BugClassification Classification,
const char *Desc)
285 :
Vulnerability(VCT_SinkMustNotReach, Name, Importance, Classification,
292 const BugDescription::BugImportance Importance,
293 const BugDescription::BugClassification Classification,
295 :
Vulnerability(CTy, Name, Importance, Classification, Desc) {}
298 std::vector<ValueSitePairType> &Sources) {
299 for (
auto It = SEG->value_node_begin(), E = SEG->value_node_end(); It != E;
303 for (
auto SiteIt = Node->use_site_begin(), SiteE = Node->use_site_end();
304 SiteIt != SiteE; SiteIt++) {
305 if (isSource(Node, *SiteIt)) {
306 Sources.emplace_back(Node, *SiteIt);
310 if (!Node->use_site_size()) {
311 if (isSource(Node,
nullptr)) {
312 Sources.emplace_back(Node,
nullptr);
320 const VulnerabilityTraceBuilder &TraceHistory)
override {
325 }
else if (isa<SEGReturnSite>(CurrSite)) {
327 }
else if (isa<SEGCallSite>(CurrSite)) {
339 const VulnerabilityTraceBuilder &TraceHistory,
340 SMTExprVec &Prerequisites)
override {
351 std::vector<const SEGNodeBase *> &TransferDsts) {}
355 return vuln->getCategoryType() > VCT_Begin &&
356 vuln->getCategoryType() < VCT_End;
364 BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
365 BugDescription::BugClassification Classification =
366 BugDescription::BC_SECURITY,
367 const char *Desc =
"CUSTOMIZED")
369 Classification, Desc) {}
376 BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
377 BugDescription::BugClassification Classification =
378 BugDescription::BC_SECURITY,
379 const char *Desc =
"CUSTOMIZED")
381 Classification, Desc) {}
401 std::vector<const SEGNodeBase *> &TransferDsts) {}
409 const char *Name,
const BugDescription::BugImportance importance,
410 const BugDescription::BugClassification classification,
const char *Desc)
411 :
Vulnerability(VCT_Taint, Name, importance, classification, Desc) {}
413 virtual PSAReportDecoratorDefault *allocNewDecorator()
override {
414 return new PSATaintReportDecorator;
423 std::vector<std::shared_ptr<Vulnerability>>
Vulns;
429 std::map<std::shared_ptr<Vulnerability>,
430 std::set<std::shared_ptr<Vulnerability>>>
435 std::map<std::shared_ptr<Vulnerability>,
436 std::set<std::shared_ptr<Vulnerability>>>
439 typedef std::pair<std::shared_ptr<Vulnerability>,
440 std::shared_ptr<Vulnerability>>
442 typedef std::function<
const SEGObject *(std::shared_ptr<VulnerabilityTrace>)>
444 std::map<VulnPairTy, GetTraceFunctionTy> HeadDepFctorMap;
445 std::map<VulnPairTy, GetTraceFunctionTy> TailDepFctorMap;
453 bool add(std::shared_ptr<Vulnerability> V) {
458 std::shared_ptr<Vulnerability> get(
size_t Index)
const {
462 size_t size()
const {
return Vulns.size(); }
464 std::vector<std::shared_ptr<Vulnerability>>::const_iterator begin()
const {
465 return Vulns.begin();
468 std::vector<std::shared_ptr<Vulnerability>>::const_iterator end()
const {
474 virtual const char *getFullName() = 0;
477 virtual const char *getAbbrName() = 0;
488 virtual void buildDependence() = 0;
493 std::shared_ptr<Vulnerability> V2,
494 GetTraceFunctionTy &Func) {
495 HeadDeps[V1].insert(V2);
496 HeadDepFctorMap[std::make_pair(V1, V2)] = Func;
502 std::shared_ptr<Vulnerability> V2,
503 GetTraceFunctionTy &Func) {
504 TailDeps[V1].insert(V2);
505 TailDepFctorMap[std::make_pair(V1, V2)] = Func;
510 std::set<std::shared_ptr<Vulnerability>>::iterator
512 return HeadDeps[V].begin();
515 std::set<std::shared_ptr<Vulnerability>>::iterator
516 head_dep_end(std::shared_ptr<Vulnerability> V) {
517 return HeadDeps[V].end();
520 std::set<std::shared_ptr<Vulnerability>>::iterator
521 tail_dep_begin(std::shared_ptr<Vulnerability> V) {
522 return TailDeps[V].begin();
525 std::set<std::shared_ptr<Vulnerability>>::iterator
526 tail_dep_end(std::shared_ptr<Vulnerability> V) {
527 return TailDeps[V].end();
539 std::shared_ptr<VulnerabilityTrace> T1,
540 std::shared_ptr<Vulnerability> V2) {
541 auto It = HeadDepFctorMap.find(std::make_pair(V1, V2));
542 if (It != HeadDepFctorMap.end()) {
543 return It->second(T1);
548 const SEGObject *getTraceTail(std::shared_ptr<Vulnerability> V1,
549 std::shared_ptr<VulnerabilityTrace> T1,
550 std::shared_ptr<Vulnerability> V2) {
551 auto It = TailDepFctorMap.find(std::make_pair(V1, V2));
552 if (It != TailDepFctorMap.end()) {
553 return It->second(T1);