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;
147 std::vector<ValueSitePairType> &Sinks) {
163 const VulnerabilityTraceBuilder &TraceHistory,
164 SMTExprVec &Prerequisites) = 0;
177 const VulnerabilityTraceBuilder &TraceHistory) {
184 virtual bool finalCheck(
const VulnerabilityTraceBuilder &TraceHistory) {
196 std::list<shared_ptr<VulnerabilityTrace>> &AllTraces) {
211 virtual SiteType checkSite(
const SEGSiteBase *CurrSite,
212 const VulnerabilityTraceBuilder &TraceHistory) = 0;
216 virtual bool checkTrace(std::shared_ptr<VulnerabilityTrace> &Trace) {
242 VulnerabilityCategoryType getCategoryType()
const {
return CategoryType; }
249 void setParasitical(
bool B) { Parasitical = B; }
254 BugDescription::BugImportance getImportance()
const {
return Importance; }
256 BugDescription::BugClassification getClassification()
const {
257 return Classification;
263 virtual PSAReportDecoratorDefault *allocNewDecorator() {
264 return new PSAReportDecoratorDefault;
267 virtual void destroyDecorator(PSAReportDecoratorDefault *decorator) {
277 const char *Name,
const BugDescription::BugImportance importance,
278 const BugDescription::BugClassification classification,
const char *Desc)
279 :
Vulnerability(VCT_SinkMustReach, Name, importance, classification,
288 const char *Name,
const BugDescription::BugImportance Importance,
289 const BugDescription::BugClassification Classification,
const char *Desc)
290 :
Vulnerability(VCT_SinkMustNotReach, Name, Importance, Classification,
297 const BugDescription::BugImportance Importance,
298 const BugDescription::BugClassification Classification,
300 :
Vulnerability(CTy, Name, Importance, Classification, Desc) {}
303 std::vector<ValueSitePairType> &Sources) {
304 for (
auto It = SEG->value_node_begin(), E = SEG->value_node_end(); It != E;
308 for (
auto SiteIt = Node->use_site_begin(), SiteE = Node->use_site_end();
309 SiteIt != SiteE; SiteIt++) {
310 if (isSource(Node, *SiteIt)) {
311 Sources.emplace_back(Node, *SiteIt);
315 if (!Node->use_site_size()) {
316 if (isSource(Node,
nullptr)) {
317 Sources.emplace_back(Node,
nullptr);
325 const VulnerabilityTraceBuilder &TraceHistory)
override {
330 }
else if (isa<SEGReturnSite>(CurrSite)) {
332 }
else if (isa<SEGCallSite>(CurrSite)) {
344 const VulnerabilityTraceBuilder &TraceHistory,
345 SMTExprVec &Prerequisites)
override {
356 std::vector<const SEGNodeBase *> &TransferDsts) {}
360 return vuln->getCategoryType() > VCT_Begin &&
361 vuln->getCategoryType() < VCT_End;
369 BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
370 BugDescription::BugClassification Classification =
371 BugDescription::BC_SECURITY,
372 const char *Desc =
"CUSTOMIZED")
374 Classification, Desc) {}
381 BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
382 BugDescription::BugClassification Classification =
383 BugDescription::BC_SECURITY,
384 const char *Desc =
"CUSTOMIZED")
386 Classification, Desc) {}
406 std::vector<const SEGNodeBase *> &TransferDsts) {}
414 const char *Name,
const BugDescription::BugImportance importance,
415 const BugDescription::BugClassification classification,
const char *Desc)
416 :
Vulnerability(VCT_Taint, Name, importance, classification, Desc) {}
418 virtual PSAReportDecoratorDefault *allocNewDecorator()
override {
419 return new PSATaintReportDecorator;
428 std::vector<std::shared_ptr<Vulnerability>>
Vulns;
434 std::map<std::shared_ptr<Vulnerability>,
435 std::set<std::shared_ptr<Vulnerability>>>
440 std::map<std::shared_ptr<Vulnerability>,
441 std::set<std::shared_ptr<Vulnerability>>>
444 typedef std::pair<std::shared_ptr<Vulnerability>,
445 std::shared_ptr<Vulnerability>>
447 typedef std::function<
const SEGObject *(std::shared_ptr<VulnerabilityTrace>)>
449 std::map<VulnPairTy, GetTraceFunctionTy> HeadDepFctorMap;
450 std::map<VulnPairTy, GetTraceFunctionTy> TailDepFctorMap;
458 bool add(std::shared_ptr<Vulnerability> V) {
463 std::shared_ptr<Vulnerability> get(
size_t Index)
const {
467 size_t size()
const {
return Vulns.size(); }
469 std::vector<std::shared_ptr<Vulnerability>>::const_iterator begin()
const {
470 return Vulns.begin();
473 std::vector<std::shared_ptr<Vulnerability>>::const_iterator end()
const {
479 virtual const char *getFullName() = 0;
482 virtual const char *getAbbrName() = 0;
493 virtual void buildDependence() = 0;
498 std::shared_ptr<Vulnerability> V2,
499 GetTraceFunctionTy &Func) {
500 HeadDeps[V1].insert(V2);
501 HeadDepFctorMap[std::make_pair(V1, V2)] = Func;
507 std::shared_ptr<Vulnerability> V2,
508 GetTraceFunctionTy &Func) {
509 TailDeps[V1].insert(V2);
510 TailDepFctorMap[std::make_pair(V1, V2)] = Func;
515 std::set<std::shared_ptr<Vulnerability>>::iterator
517 return HeadDeps[V].begin();
520 std::set<std::shared_ptr<Vulnerability>>::iterator
521 head_dep_end(std::shared_ptr<Vulnerability> V) {
522 return HeadDeps[V].end();
525 std::set<std::shared_ptr<Vulnerability>>::iterator
526 tail_dep_begin(std::shared_ptr<Vulnerability> V) {
527 return TailDeps[V].begin();
530 std::set<std::shared_ptr<Vulnerability>>::iterator
531 tail_dep_end(std::shared_ptr<Vulnerability> V) {
532 return TailDeps[V].end();
544 std::shared_ptr<VulnerabilityTrace> T1,
545 std::shared_ptr<Vulnerability> V2) {
546 auto It = HeadDepFctorMap.find(std::make_pair(V1, V2));
547 if (It != HeadDepFctorMap.end()) {
548 return It->second(T1);
553 const SEGObject *getTraceTail(std::shared_ptr<Vulnerability> V1,
554 std::shared_ptr<VulnerabilityTrace> T1,
555 std::shared_ptr<Vulnerability> V2) {
556 auto It = TailDepFctorMap.find(std::make_pair(V1, V2));
557 if (It != TailDepFctorMap.end()) {
558 return It->second(T1);