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;
110 const char *VulnName;
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), VulnName(Name), Importance(Importance),
123 Classification(Classification), VulnDescription(Desc) {}
142 std::vector<ValueSitePairType> &Sources) = 0;
156 const VulnerabilityTraceBuilder &TraceHistory,
157 SMTExprVec &Prerequisites) = 0;
170 const VulnerabilityTraceBuilder &TraceHistory) {
177 virtual bool finalCheck(
const VulnerabilityTraceBuilder &TraceHistory) {
189 std::list<shared_ptr<VulnerabilityTrace>> &AllTraces) {
205 const VulnerabilityTraceBuilder &TraceHistory) = 0;
209 virtual bool checkTrace(std::shared_ptr<VulnerabilityTrace> &Trace) {
242 void setParasitical(
bool B) { Parasitical = B; }
247 BugDescription::BugImportance getImportance()
const {
return Importance; }
249 BugDescription::BugClassification getClassification()
const {
250 return Classification;
256 virtual PSAReportDecoratorDefault *allocNewDecorator() {
257 return new PSAReportDecoratorDefault;
260 virtual void destroyDecorator(PSAReportDecoratorDefault *decorator) {
270 const char *Name,
const BugDescription::BugImportance importance,
271 const BugDescription::BugClassification classification,
const char *Desc)
272 :
Vulnerability(VCT_SinkMustReach, Name, importance, classification,
281 const char *Name,
const BugDescription::BugImportance Importance,
282 const BugDescription::BugClassification Classification,
const char *Desc)
283 :
Vulnerability(VCT_SinkMustNotReach, Name, Importance, Classification,
290 const BugDescription::BugImportance Importance,
291 const BugDescription::BugClassification Classification,
293 :
Vulnerability(CTy, Name, Importance, Classification, Desc) {}
296 std::vector<ValueSitePairType> &Sources) {
297 for (
auto It = SEG->value_node_begin(), E = SEG->value_node_end(); It != E;
301 for (
auto SiteIt = Node->use_site_begin(), SiteE = Node->use_site_end();
302 SiteIt != SiteE; SiteIt++) {
303 if (isSource(Node, *SiteIt)) {
304 Sources.emplace_back(Node, *SiteIt);
308 if (!Node->use_site_size()) {
309 if (isSource(Node,
nullptr)) {
310 Sources.emplace_back(Node,
nullptr);
318 const VulnerabilityTraceBuilder &TraceHistory)
override {
323 }
else if (isa<SEGReturnSite>(CurrSite)) {
325 }
else if (isa<SEGCallSite>(CurrSite)) {
337 const VulnerabilityTraceBuilder &TraceHistory,
338 SMTExprVec &Prerequisites)
override {
349 std::vector<const SEGNodeBase *> &TransferDsts) {}
353 return vuln->getCategoryType() > VCT_Begin &&
354 vuln->getCategoryType() < VCT_End;
362 BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
363 BugDescription::BugClassification Classification =
364 BugDescription::BC_SECURITY,
365 const char *Desc =
"CUSTOMIZED")
367 Classification, Desc) {}
374 BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
375 BugDescription::BugClassification Classification =
376 BugDescription::BC_SECURITY,
377 const char *Desc =
"CUSTOMIZED")
379 Classification, Desc) {}
399 std::vector<const SEGNodeBase *> &TransferDsts) {}
407 const char *Name,
const BugDescription::BugImportance importance,
408 const BugDescription::BugClassification classification,
const char *Desc)
409 :
Vulnerability(VCT_Taint, Name, importance, classification, Desc) {}
411 virtual PSAReportDecoratorDefault *allocNewDecorator()
override {
412 return new PSATaintReportDecorator;
421 std::vector<std::shared_ptr<Vulnerability>>
Vulns;
427 std::map<std::shared_ptr<Vulnerability>,
428 std::set<std::shared_ptr<Vulnerability>>>
433 std::map<std::shared_ptr<Vulnerability>,
434 std::set<std::shared_ptr<Vulnerability>>>
437 typedef std::pair<std::shared_ptr<Vulnerability>,
438 std::shared_ptr<Vulnerability>>
440 typedef std::function<
const SEGObject *(std::shared_ptr<VulnerabilityTrace>)>
442 std::map<VulnPairTy, GetTraceFunctionTy> HeadDepFctorMap;
443 std::map<VulnPairTy, GetTraceFunctionTy> TailDepFctorMap;
451 bool add(std::shared_ptr<Vulnerability> V) {
456 std::shared_ptr<Vulnerability> get(
size_t Index)
const {
460 size_t size()
const {
return Vulns.size(); }
462 std::vector<std::shared_ptr<Vulnerability>>::const_iterator begin()
const {
463 return Vulns.begin();
466 std::vector<std::shared_ptr<Vulnerability>>::const_iterator end()
const {
472 virtual const char *getFullName() = 0;
475 virtual const char *getAbbrName() = 0;
486 virtual void buildDependence() = 0;
491 std::shared_ptr<Vulnerability> V2,
492 GetTraceFunctionTy &Func) {
493 HeadDeps[V1].insert(V2);
494 HeadDepFctorMap[std::make_pair(V1, V2)] = Func;
500 std::shared_ptr<Vulnerability> V2,
501 GetTraceFunctionTy &Func) {
502 TailDeps[V1].insert(V2);
503 TailDepFctorMap[std::make_pair(V1, V2)] = Func;
508 std::set<std::shared_ptr<Vulnerability>>::iterator
510 return HeadDeps[V].begin();
513 std::set<std::shared_ptr<Vulnerability>>::iterator
514 head_dep_end(std::shared_ptr<Vulnerability> V) {
515 return HeadDeps[V].end();
518 std::set<std::shared_ptr<Vulnerability>>::iterator
519 tail_dep_begin(std::shared_ptr<Vulnerability> V) {
520 return TailDeps[V].begin();
523 std::set<std::shared_ptr<Vulnerability>>::iterator
524 tail_dep_end(std::shared_ptr<Vulnerability> V) {
525 return TailDeps[V].end();
537 std::shared_ptr<VulnerabilityTrace> T1,
538 std::shared_ptr<Vulnerability> V2) {
539 auto It = HeadDepFctorMap.find(std::make_pair(V1, V2));
540 if (It != HeadDepFctorMap.end()) {
541 return It->second(T1);
546 const SEGObject *getTraceTail(std::shared_ptr<Vulnerability> V1,
547 std::shared_ptr<VulnerabilityTrace> T1,
548 std::shared_ptr<Vulnerability> V2) {
549 auto It = TailDepFctorMap.find(std::make_pair(V1, V2));
550 if (It != TailDepFctorMap.end()) {
551 return It->second(T1);