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"
89 typedef typename std::pair<const SEGOperandNode *, const SEGSiteBase *>
108 bool Parasitical =
true;
111 const BugDescription::BugImportance Importance;
112 const BugDescription::BugClassification Classification;
113 const char *VulnDescription;
119 const BugDescription::BugImportance Importance,
120 const BugDescription::BugClassification Classification,
122 : CategoryType(CTy), Importance(Importance),
123 Classification(Classification), VulnDescription(Desc) {
124 VulnName = (
char *)malloc(300);
125 std::strcpy(VulnName, (
char *)Name);
145 std::vector<ValueSitePairType> &Sources) = 0;
159 const VulnerabilityTraceBuilder &TraceHistory,
160 SMTExprVec &Prerequisites) = 0;
173 const VulnerabilityTraceBuilder &TraceHistory) {
180 virtual bool finalCheck(
const VulnerabilityTraceBuilder &TraceHistory) {
192 std::list<shared_ptr<VulnerabilityTrace>> &AllTraces) {
208 const VulnerabilityTraceBuilder &TraceHistory) = 0;
212 virtual bool checkTrace(std::shared_ptr<VulnerabilityTrace> &Trace) {
245 void setParasitical(
bool B) { Parasitical = B; }
250 BugDescription::BugImportance getImportance()
const {
return Importance; }
252 BugDescription::BugClassification getClassification()
const {
253 return Classification;
259 virtual PSAReportDecoratorDefault *allocNewDecorator() {
260 return new PSAReportDecoratorDefault;
263 virtual void destroyDecorator(PSAReportDecoratorDefault *decorator) {
273 const char *Name,
const BugDescription::BugImportance importance,
274 const BugDescription::BugClassification classification,
const char *Desc)
275 :
Vulnerability(VCT_SinkMustReach, Name, importance, classification,
284 const char *Name,
const BugDescription::BugImportance Importance,
285 const BugDescription::BugClassification Classification,
const char *Desc)
286 :
Vulnerability(VCT_SinkMustNotReach, Name, Importance, Classification,
293 const BugDescription::BugImportance Importance,
294 const BugDescription::BugClassification Classification,
296 :
Vulnerability(CTy, Name, Importance, Classification, Desc) {}
299 std::vector<ValueSitePairType> &Sources) {
300 for (
auto It = SEG->value_node_begin(), E = SEG->value_node_end(); It != E;
304 if (Node->use_site_size()) {
305 for (
auto SiteIt = Node->use_site_begin(), SiteE = Node->use_site_end();
306 SiteIt != SiteE; SiteIt++) {
307 if (isSource(Node, *SiteIt)) {
312 Sources.emplace_back(Node, *SiteIt);
315 }
else if (isSource(Node,
nullptr)) {
319 Sources.emplace_back(Node,
nullptr);
324 for (
auto it = SEG->seg_callsite_begin(), E = SEG->seg_callsite_end();
326 if (*it ==
nullptr) {
330 if (!(*it)->hasCommonOutput()) {
334 auto CO = (*it)->getCommonOutput();
336 if (isSource(CSO, *it)) {
340 Sources.emplace_back(CSO, *it);
348 const VulnerabilityTraceBuilder &TraceHistory)
override {
360 }
else if (isa<SEGReturnSite>(CurrSite)) {
362 }
else if (isa<SEGCallSite>(CurrSite)) {
374 const VulnerabilityTraceBuilder &TraceHistory,
375 SMTExprVec &Prerequisites)
override {
386 std::vector<const SEGNodeBase *> &TransferDsts) {}
390 return vuln->getCategoryType() > VCT_Begin &&
391 vuln->getCategoryType() < VCT_End;
399 BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
400 BugDescription::BugClassification Classification =
401 BugDescription::BC_SECURITY,
402 const char *Desc =
"CUSTOMIZED")
404 Classification, Desc) {}
411 BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
412 BugDescription::BugClassification Classification =
413 BugDescription::BC_SECURITY,
414 const char *Desc =
"CUSTOMIZED")
416 Classification, Desc) {}
436 std::vector<const SEGNodeBase *> &TransferDsts) {}
444 const char *Name,
const BugDescription::BugImportance importance,
445 const BugDescription::BugClassification classification,
const char *Desc)
446 :
Vulnerability(VCT_Taint, Name, importance, classification, Desc) {}
448 virtual PSAReportDecoratorDefault *allocNewDecorator()
override {
449 return new PSATaintReportDecorator;
458 std::vector<std::shared_ptr<Vulnerability>>
Vulns;
464 std::map<std::shared_ptr<Vulnerability>,
465 std::set<std::shared_ptr<Vulnerability>>>
470 std::map<std::shared_ptr<Vulnerability>,
471 std::set<std::shared_ptr<Vulnerability>>>
474 typedef std::pair<std::shared_ptr<Vulnerability>,
475 std::shared_ptr<Vulnerability>>
477 typedef std::function<
const SEGObject *(std::shared_ptr<VulnerabilityTrace>)>
479 std::map<VulnPairTy, GetTraceFunctionTy> HeadDepFctorMap;
480 std::map<VulnPairTy, GetTraceFunctionTy> TailDepFctorMap;
488 bool add(std::shared_ptr<Vulnerability> V) {
493 std::shared_ptr<Vulnerability> get(
size_t Index)
const {
497 size_t size()
const {
return Vulns.size(); }
499 std::vector<std::shared_ptr<Vulnerability>>::const_iterator begin()
const {
500 return Vulns.begin();
503 std::vector<std::shared_ptr<Vulnerability>>::const_iterator end()
const {
509 virtual const char *getFullName() = 0;
512 virtual const char *getAbbrName() = 0;
523 virtual void buildDependence() = 0;
528 std::shared_ptr<Vulnerability> V2,
529 GetTraceFunctionTy &Func) {
530 HeadDeps[V1].insert(V2);
531 HeadDepFctorMap[std::make_pair(V1, V2)] = Func;
537 std::shared_ptr<Vulnerability> V2,
538 GetTraceFunctionTy &Func) {
539 TailDeps[V1].insert(V2);
540 TailDepFctorMap[std::make_pair(V1, V2)] = Func;
545 std::set<std::shared_ptr<Vulnerability>>::iterator
547 return HeadDeps[V].begin();
550 std::set<std::shared_ptr<Vulnerability>>::iterator
551 head_dep_end(std::shared_ptr<Vulnerability> V) {
552 return HeadDeps[V].end();
555 std::set<std::shared_ptr<Vulnerability>>::iterator
556 tail_dep_begin(std::shared_ptr<Vulnerability> V) {
557 return TailDeps[V].begin();
560 std::set<std::shared_ptr<Vulnerability>>::iterator
561 tail_dep_end(std::shared_ptr<Vulnerability> V) {
562 return TailDeps[V].end();
574 std::shared_ptr<VulnerabilityTrace> T1,
575 std::shared_ptr<Vulnerability> V2) {
576 auto It = HeadDepFctorMap.find(std::make_pair(V1, V2));
577 if (It != HeadDepFctorMap.end()) {
578 return It->second(T1);
583 const SEGObject *getTraceTail(std::shared_ptr<Vulnerability> V1,
584 std::shared_ptr<VulnerabilityTrace> T1,
585 std::shared_ptr<Vulnerability> V2) {
586 auto It = TailDepFctorMap.find(std::make_pair(V1, V2));
587 if (It != TailDepFctorMap.end()) {
588 return It->second(T1);