ClearBlue
Vulnerability.h
1 /*
2  * Vulnerability.h
3  *
4  * Vulnerability is the base class of different
5  * vulnerabilities.
6  *
7  * Each Vulnerability provides the same interfaces
8  * whose implementations are customized for one kind of
9  * vulnerability, e.g. NPD.
10  *
11  * The instance of the class should be passed to
12  * PPPathSensitiveChecker as an input, so that the checker
13  * can use it to detect specific bugs.
14  *
15  * Author: Qingkai
16  */
17 
18 #ifndef CHECKER_PSA_VULNERABILITY_H
19 #define CHECKER_PSA_VULNERABILITY_H
20 
21 #include <llvm/Pass.h>
22 
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"
30 
31 #include "Checker/PSA/PSAReportDecoratorDefault.h"
32 #include "Checker/PSA/PSATaintReportDecorator.h"
33 #include "IR/SEG/SEGCallSiteOutputNode.h"
34 #include "IR/SEG/SEGSimpleSite.h"
35 
36 using namespace llvm;
37 
45 public:
58  enum SiteType {
59  ST_Return = 1 << 0,
60  ST_Call = 1 << 1,
61  ST_Sink = 1 << 2,
62  ST_Others = 1 << 3,
63  };
64 
79  VCT_Begin,
80  VCT_SinkMustReach,
81  VCT_SinkMustNotReach,
82  VCT_Taint,
83  VCT_End
84  };
85 
89  typedef typename std::pair<const SEGOperandNode *, const SEGSiteBase *>
91 
92 private:
94  VulnerabilityCategoryType CategoryType;
95 
108  bool Parasitical = true;
109 
110  char *VulnName;
111  const BugDescription::BugImportance Importance;
112  const BugDescription::BugClassification Classification;
113  const char *VulnDescription;
114 
115  // The constructor is made private and, thus it cannot be extended.
116  // Users must extend its sub-classes to implement different types of
117  // vulnerabilities.
118  Vulnerability(VulnerabilityCategoryType CTy, const char *Name,
119  const BugDescription::BugImportance Importance,
120  const BugDescription::BugClassification Classification,
121  const char *Desc)
122  : CategoryType(CTy), Importance(Importance),
123  Classification(Classification), VulnDescription(Desc) {
124  VulnName = (char *)malloc(300);
125  std::strcpy(VulnName, (char *)Name);
126  }
127 
128  friend class SinkMustReachVulnerability;
129  friend class SinkMustNotReachVulnerability;
130  friend class TaintStyleVulnerability;
132  friend class SrcMustReachSinkVulnerability;
133  friend class SailFishVulnerability;
134 
135 public:
136  virtual ~Vulnerability() {}
137 
144  virtual void setSources(const SymbolicExprGraph *SEG,
145  std::vector<ValueSitePairType> &Sources) = 0;
146 
157  virtual void setPrerequisites(SymbolicExprGraphSolver *Solver,
158  const SEGSiteBase *CurrSite,
159  const VulnerabilityTraceBuilder &TraceHistory,
160  SMTExprVec &Prerequisites) = 0;
161 
172  virtual bool checkNode(const SEGNodeBase *CurrNode,
173  const VulnerabilityTraceBuilder &TraceHistory) {
174  return false;
175  }
176 
180  virtual bool finalCheck(const VulnerabilityTraceBuilder &TraceHistory) {
181  return true;
182  }
183 
190  virtual void
192  std::list<shared_ptr<VulnerabilityTrace>> &AllTraces) {
193  return;
194  }
195 
203  virtual bool isFlowInsensitive() { return false; }
204 
207  virtual SiteType checkSite(const SEGSiteBase *CurrSite,
208  const VulnerabilityTraceBuilder &TraceHistory) = 0;
209 
212  virtual bool checkTrace(std::shared_ptr<VulnerabilityTrace> &Trace) {
213  return true;
214  }
215 
222  virtual void getAnalysisUsage(AnalysisUsage &AU) {}
223 
234  virtual void initializeAnalysis(Pass *P) {}
236 
237 public:
238  VulnerabilityCategoryType getCategoryType() const { return CategoryType; }
239 
243  bool isParasitical() const { return Parasitical; }
244 
245  void setParasitical(bool B) { Parasitical = B; }
246 
248  const char *getDescription() { return VulnDescription; }
249 
250  BugDescription::BugImportance getImportance() const { return Importance; }
251 
252  BugDescription::BugClassification getClassification() const {
253  return Classification;
254  }
255 
257  const char *getName() { return VulnName; }
258 
259  virtual PSAReportDecoratorDefault *allocNewDecorator() {
260  return new PSAReportDecoratorDefault;
261  }
262 
263  virtual void destroyDecorator(PSAReportDecoratorDefault *decorator) {
264  delete decorator;
265  }
266 };
267 
271 public:
273  const char *Name, const BugDescription::BugImportance importance,
274  const BugDescription::BugClassification classification, const char *Desc)
275  : Vulnerability(VCT_SinkMustReach, Name, importance, classification,
276  Desc) {}
277 };
278 
282 public:
284  const char *Name, const BugDescription::BugImportance Importance,
285  const BugDescription::BugClassification Classification, const char *Desc)
286  : Vulnerability(VCT_SinkMustNotReach, Name, Importance, Classification,
287  Desc) {}
288 };
289 
291 public:
292  SailFishVulnerability(VulnerabilityCategoryType CTy, const char *Name,
293  const BugDescription::BugImportance Importance,
294  const BugDescription::BugClassification Classification,
295  const char *Desc)
296  : Vulnerability(CTy, Name, Importance, Classification, Desc) {}
297 
298  virtual void setSources(const SymbolicExprGraph *SEG,
299  std::vector<ValueSitePairType> &Sources) {
300  for (auto It = SEG->value_node_begin(), E = SEG->value_node_end(); It != E;
301  It++) {
302  SEGOperandNode *Node = It->second;
303 
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)) {
308  // outs() << "[Find Source]: " << *Node << " in func: "
309  // <<
310  // Node->getParentGraph()->getBaseFunc()->getName()
311  // << "\n";
312  Sources.emplace_back(Node, *SiteIt);
313  }
314  }
315  } else if (isSource(Node, nullptr)) {
316  // outs() << "[Find Source]: " << *Node << " in func: "
317  // << Node->getParentGraph()->getBaseFunc()->getName() <<
318  // "\n";
319  Sources.emplace_back(Node, nullptr);
320  }
321  }
322 
323  // Add modeling common output value node
324  for (auto it = SEG->seg_callsite_begin(), E = SEG->seg_callsite_end();
325  it != E; it++) {
326  if (*it == nullptr) {
327  continue;
328  }
329 
330  if (!(*it)->hasCommonOutput()) {
331  continue;
332  }
333 
334  auto CO = (*it)->getCommonOutput();
335  if (auto *CSO = const_cast<SEGCallSiteCommonOutputNode *>(CO)) {
336  if (isSource(CSO, *it)) {
337  // outs() << "[Find Source]: " << *CSO << " in func: "
338  // << CSO->getParentGraph()->getBaseFunc()->getName()
339  // << "\n";
340  Sources.emplace_back(CSO, *it);
341  }
342  }
343  }
344  }
345 
347  checkSite(const SEGSiteBase *CurrSite,
348  const VulnerabilityTraceBuilder &TraceHistory) override {
349  auto *Node = TraceHistory.recentObjAs<SEGOperandNode>();
350 
351  if (isSink((SEGNodeBase *)Node, const_cast<SEGSiteBase *>(CurrSite))) {
352  // outs() << "[Find Sink]: " << *Node
353  // << " in func: " <<
354  // Node->getParentGraph()->getBaseFunc()->getName()
355  // << "\n";
356  if (CurrSite) {
357  // outs() << "[Find Sink Site]: " << *CurrSite << "\n";
358  }
359  return ST_Sink;
360  } else if (isa<SEGReturnSite>(CurrSite)) {
361  return ST_Return;
362  } else if (isa<SEGCallSite>(CurrSite)) {
363  return ST_Call;
364  }
365  return ST_Others;
366  }
367 
368  virtual bool isSource(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
369 
370  virtual bool isSink(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
371 
373  const SEGSiteBase *CurrSite,
374  const VulnerabilityTraceBuilder &TraceHistory,
375  SMTExprVec &Prerequisites) override {
376  // Prerequisites.push_back(
377  // Solver->getOrInsertExpr(TraceHistory.recentObjAs<SEGNodeBase>())
378  // == 0);
379  }
380 
385  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
386  std::vector<const SEGNodeBase *> &TransferDsts) {}
387 
388 public:
389  static bool classof(const Vulnerability *vuln) {
390  return vuln->getCategoryType() > VCT_Begin &&
391  vuln->getCategoryType() < VCT_End;
392  }
393 };
394 
396 public:
398  const char *Name,
399  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
400  BugDescription::BugClassification Classification =
401  BugDescription::BC_SECURITY,
402  const char *Desc = "CUSTOMIZED")
403  : SailFishVulnerability(VCT_SinkMustReach, Name, Importance,
404  Classification, Desc) {}
405 };
406 
408 public:
410  const char *Name,
411  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
412  BugDescription::BugClassification Classification =
413  BugDescription::BC_SECURITY,
414  const char *Desc = "CUSTOMIZED")
415  : SailFishVulnerability(VCT_SinkMustNotReach, Name, Importance,
416  Classification, Desc) {}
417 };
418 
422 class TaintExtras {
423 private:
424  TaintExtras() {}
425  friend class TaintStyleVulnerability;
426 
427 public:
428  virtual ~TaintExtras() {}
429  virtual bool isSinkFunction(const SymbolicExprGraph *G,
430  const SEGArgumentNode *Arg) const = 0;
435  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
436  std::vector<const SEGNodeBase *> &TransferDsts) {}
437 };
438 
442 public:
444  const char *Name, const BugDescription::BugImportance importance,
445  const BugDescription::BugClassification classification, const char *Desc)
446  : Vulnerability(VCT_Taint, Name, importance, classification, Desc) {}
447 
448  virtual PSAReportDecoratorDefault *allocNewDecorator() override {
449  return new PSATaintReportDecorator;
450  }
451 };
452 
456 protected:
458  std::vector<std::shared_ptr<Vulnerability>> Vulns;
459 
464  std::map<std::shared_ptr<Vulnerability>,
465  std::set<std::shared_ptr<Vulnerability>>>
467 
470  std::map<std::shared_ptr<Vulnerability>,
471  std::set<std::shared_ptr<Vulnerability>>>
473 
474  typedef std::pair<std::shared_ptr<Vulnerability>,
475  std::shared_ptr<Vulnerability>>
476  VulnPairTy;
477  typedef std::function<const SEGObject *(std::shared_ptr<VulnerabilityTrace>)>
478  GetTraceFunctionTy;
479  std::map<VulnPairTy, GetTraceFunctionTy> HeadDepFctorMap;
480  std::map<VulnPairTy, GetTraceFunctionTy> TailDepFctorMap;
482 
483 public:
484  virtual ~MultiVulnerability() {}
485 
488  bool add(std::shared_ptr<Vulnerability> V) {
489  Vulns.push_back(V);
490  return true;
491  }
492 
493  std::shared_ptr<Vulnerability> get(size_t Index) const {
494  return Vulns[Index];
495  }
496 
497  size_t size() const { return Vulns.size(); }
498 
499  std::vector<std::shared_ptr<Vulnerability>>::const_iterator begin() const {
500  return Vulns.begin();
501  }
502 
503  std::vector<std::shared_ptr<Vulnerability>>::const_iterator end() const {
504  return Vulns.end();
505  }
507 
509  virtual const char *getFullName() = 0;
510 
512  virtual const char *getAbbrName() = 0;
513 
523  virtual void buildDependence() = 0;
524 
527  void insertHeadDependence(std::shared_ptr<Vulnerability> V1,
528  std::shared_ptr<Vulnerability> V2,
529  GetTraceFunctionTy &Func) {
530  HeadDeps[V1].insert(V2);
531  HeadDepFctorMap[std::make_pair(V1, V2)] = Func;
532  }
533 
536  void insertTailDependence(std::shared_ptr<Vulnerability> V1,
537  std::shared_ptr<Vulnerability> V2,
538  GetTraceFunctionTy &Func) {
539  TailDeps[V1].insert(V2);
540  TailDepFctorMap[std::make_pair(V1, V2)] = Func;
541  }
542 
545  std::set<std::shared_ptr<Vulnerability>>::iterator
546  head_dep_begin(std::shared_ptr<Vulnerability> V) {
547  return HeadDeps[V].begin();
548  }
549 
550  std::set<std::shared_ptr<Vulnerability>>::iterator
551  head_dep_end(std::shared_ptr<Vulnerability> V) {
552  return HeadDeps[V].end();
553  }
554 
555  std::set<std::shared_ptr<Vulnerability>>::iterator
556  tail_dep_begin(std::shared_ptr<Vulnerability> V) {
557  return TailDeps[V].begin();
558  }
559 
560  std::set<std::shared_ptr<Vulnerability>>::iterator
561  tail_dep_end(std::shared_ptr<Vulnerability> V) {
562  return TailDeps[V].end();
563  }
566 
573  const SEGObject *getTraceHead(std::shared_ptr<Vulnerability> V1,
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);
579  }
580  return nullptr;
581  }
582 
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);
589  }
590  return nullptr;
591  }
592 
594 };
595 
596 #endif /* CHECKER_PSA_VULNERABILITY_H */
MultiVulnerability::TailDeps
std::map< std::shared_ptr< Vulnerability >, std::set< std::shared_ptr< Vulnerability > > > TailDeps
Definition: Vulnerability.h:472
Vulnerability::initializeAnalysis
virtual void initializeAnalysis(Pass *P)
Definition: Vulnerability.h:234
SEGOperandNode
Definition: SymbolicExprGraph.h:469
MultiVulnerability::insertHeadDependence
void insertHeadDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:527
Vulnerability::VulnerabilityCategoryType
VulnerabilityCategoryType
Definition: Vulnerability.h:78
Vulnerability::ValueSitePairType
std::pair< const SEGOperandNode *, const SEGSiteBase * > ValueSitePairType
Definition: Vulnerability.h:90
Vulnerability::checkNode
virtual bool checkNode(const SEGNodeBase *CurrNode, const VulnerabilityTraceBuilder &TraceHistory)
Definition: Vulnerability.h:172
Vulnerability::checkTrace
virtual bool checkTrace(std::shared_ptr< VulnerabilityTrace > &Trace)
Definition: Vulnerability.h:212
SinkMustReachVulnerability
Definition: Vulnerability.h:270
SymbolicExprGraph
Definition: SymbolicExprGraph.h:720
SEGCallSiteCommonOutputNode
Definition: SEGCallSiteOutputNode.h:50
Vulnerability::isFlowInsensitive
virtual bool isFlowInsensitive()
Definition: Vulnerability.h:203
MultiVulnerability::add
bool add(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:488
SrcMustNotReachSinkVulnerability
Definition: Vulnerability.h:407
Vulnerability::SiteType
SiteType
Definition: Vulnerability.h:58
SailFishVulnerability
Definition: Vulnerability.h:290
Vulnerability::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &AU)
Definition: Vulnerability.h:222
SEGArgumentNode
Definition: SEGArgumentNode.h:18
MultiVulnerability::getTraceHead
const SEGObject * getTraceHead(std::shared_ptr< Vulnerability > V1, std::shared_ptr< VulnerabilityTrace > T1, std::shared_ptr< Vulnerability > V2)
Definition: Vulnerability.h:573
Vulnerability::finalCheck
virtual bool finalCheck(const VulnerabilityTraceBuilder &TraceHistory)
Definition: Vulnerability.h:180
SymbolicExprGraphSolver
Definition: SymbolicExprGraphSolver.h:48
SEGObject
Definition: SymbolicExprGraph.h:78
MultiVulnerability::HeadDeps
std::map< std::shared_ptr< Vulnerability >, std::set< std::shared_ptr< Vulnerability > > > HeadDeps
Definition: Vulnerability.h:466
Vulnerability::ConstantCheck
virtual void ConstantCheck(const SymbolicExprGraph *SEG, std::list< shared_ptr< VulnerabilityTrace >> &AllTraces)
Definition: Vulnerability.h:191
MultiVulnerability
Definition: Vulnerability.h:455
SrcMustReachSinkVulnerability
Definition: Vulnerability.h:395
MultiVulnerability::head_dep_begin
std::set< std::shared_ptr< Vulnerability > >::iterator head_dep_begin(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:546
Vulnerability
Definition: Vulnerability.h:44
SailFishVulnerability::setSources
virtual void setSources(const SymbolicExprGraph *SEG, std::vector< ValueSitePairType > &Sources)
Definition: Vulnerability.h:298
MultiVulnerability::Vulns
std::vector< std::shared_ptr< Vulnerability > > Vulns
What the multi-vulnerability consists of.
Definition: Vulnerability.h:458
SailFishVulnerability::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:385
TaintStyleVulnerability
Definition: Vulnerability.h:441
Vulnerability::getDescription
const char * getDescription()
Return the description of the vulnerability.
Definition: Vulnerability.h:248
SailFishVulnerability::checkSite
virtual Vulnerability::SiteType checkSite(const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory) override
Definition: Vulnerability.h:347
MultiVulnerability::insertTailDependence
void insertTailDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:536
SailFishVulnerability::setPrerequisites
virtual void setPrerequisites(SymbolicExprGraphSolver *Solver, const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory, SMTExprVec &Prerequisites) override
Definition: Vulnerability.h:372
SinkMustNotReachVulnerability
Definition: Vulnerability.h:281
TaintExtras
Definition: Vulnerability.h:422
SEGSiteBase
Definition: SymbolicExprGraph.h:676
Vulnerability::isParasitical
bool isParasitical() const
Definition: Vulnerability.h:243
SEGNodeBase
The node base of symbolic expression graph.
Definition: SymbolicExprGraph.h:248
Vulnerability::getName
const char * getName()
Return the name of the vulnerability.
Definition: Vulnerability.h:257
TaintExtras::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:435