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  const 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), VulnName(Name), Importance(Importance),
123  Classification(Classification), VulnDescription(Desc) {}
124 
125  friend class SinkMustReachVulnerability;
126  friend class SinkMustNotReachVulnerability;
127  friend class TaintStyleVulnerability;
129  friend class SrcMustReachSinkVulnerability;
130  friend class SailFishVulnerability;
131 
132 public:
133  virtual ~Vulnerability() {}
134 
141  virtual void setSources(const SymbolicExprGraph *SEG,
142  std::vector<ValueSitePairType> &Sources) = 0;
143 
154  virtual void setPrerequisites(SymbolicExprGraphSolver *Solver,
155  const SEGSiteBase *CurrSite,
156  const VulnerabilityTraceBuilder &TraceHistory,
157  SMTExprVec &Prerequisites) = 0;
158 
169  virtual bool checkNode(const SEGNodeBase *CurrNode,
170  const VulnerabilityTraceBuilder &TraceHistory) {
171  return false;
172  }
173 
177  virtual bool finalCheck(const VulnerabilityTraceBuilder &TraceHistory) {
178  return true;
179  }
180 
187  virtual void
189  std::list<shared_ptr<VulnerabilityTrace>> &AllTraces) {
190  return;
191  }
192 
200  virtual bool isFlowInsensitive() { return false; }
201 
204  virtual SiteType checkSite(const SEGSiteBase *CurrSite,
205  const VulnerabilityTraceBuilder &TraceHistory) = 0;
206 
209  virtual bool checkTrace(std::shared_ptr<VulnerabilityTrace> &Trace) {
210  return true;
211  }
212 
219  virtual void getAnalysisUsage(AnalysisUsage &AU) {}
220 
231  virtual void initializeAnalysis(Pass *P) {}
233 
234 public:
235  VulnerabilityCategoryType getCategoryType() const { return CategoryType; }
236 
240  bool isParasitical() const { return Parasitical; }
241 
242  void setParasitical(bool B) { Parasitical = B; }
243 
245  const char *getDescription() { return VulnDescription; }
246 
247  BugDescription::BugImportance getImportance() const { return Importance; }
248 
249  BugDescription::BugClassification getClassification() const {
250  return Classification;
251  }
252 
254  const char *getName() { return VulnName; }
255 
256  virtual PSAReportDecoratorDefault *allocNewDecorator() {
257  return new PSAReportDecoratorDefault;
258  }
259 
260  virtual void destroyDecorator(PSAReportDecoratorDefault *decorator) {
261  delete decorator;
262  }
263 };
264 
268 public:
270  const char *Name, const BugDescription::BugImportance importance,
271  const BugDescription::BugClassification classification, const char *Desc)
272  : Vulnerability(VCT_SinkMustReach, Name, importance, classification,
273  Desc) {}
274 };
275 
279 public:
281  const char *Name, const BugDescription::BugImportance Importance,
282  const BugDescription::BugClassification Classification, const char *Desc)
283  : Vulnerability(VCT_SinkMustNotReach, Name, Importance, Classification,
284  Desc) {}
285 };
286 
288 public:
289  SailFishVulnerability(VulnerabilityCategoryType CTy, const char *Name,
290  const BugDescription::BugImportance Importance,
291  const BugDescription::BugClassification Classification,
292  const char *Desc)
293  : Vulnerability(CTy, Name, Importance, Classification, Desc) {}
294 
295  virtual void setSources(const SymbolicExprGraph *SEG,
296  std::vector<ValueSitePairType> &Sources) {
297  for (auto It = SEG->value_node_begin(), E = SEG->value_node_end(); It != E;
298  It++) {
299  SEGOperandNode *Node = It->second;
300 
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);
305  }
306  }
307 
308  if (!Node->use_site_size()) {
309  if (isSource(Node, nullptr)) {
310  Sources.emplace_back(Node, nullptr);
311  }
312  }
313  }
314  }
315 
317  checkSite(const SEGSiteBase *CurrSite,
318  const VulnerabilityTraceBuilder &TraceHistory) override {
319  auto *Node = TraceHistory.recentObjAs<SEGOperandNode>();
320 
321  if (isSink((SEGNodeBase *)Node, const_cast<SEGSiteBase *>(CurrSite))) {
322  return ST_Sink;
323  } else if (isa<SEGReturnSite>(CurrSite)) {
324  return ST_Return;
325  } else if (isa<SEGCallSite>(CurrSite)) {
326  return ST_Call;
327  }
328  return ST_Others;
329  }
330 
331  virtual bool isSource(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
332 
333  virtual bool isSink(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
334 
336  const SEGSiteBase *CurrSite,
337  const VulnerabilityTraceBuilder &TraceHistory,
338  SMTExprVec &Prerequisites) override {
339  // Prerequisites.push_back(
340  // Solver->getOrInsertExpr(TraceHistory.recentObjAs<SEGNodeBase>())
341  // == 0);
342  }
343 
348  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
349  std::vector<const SEGNodeBase *> &TransferDsts) {}
350 
351 public:
352  static bool classof(const Vulnerability *vuln) {
353  return vuln->getCategoryType() > VCT_Begin &&
354  vuln->getCategoryType() < VCT_End;
355  }
356 };
357 
359 public:
361  const char *Name,
362  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
363  BugDescription::BugClassification Classification =
364  BugDescription::BC_SECURITY,
365  const char *Desc = "CUSTOMIZED")
366  : SailFishVulnerability(VCT_SinkMustReach, Name, Importance,
367  Classification, Desc) {}
368 };
369 
371 public:
373  const char *Name,
374  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
375  BugDescription::BugClassification Classification =
376  BugDescription::BC_SECURITY,
377  const char *Desc = "CUSTOMIZED")
378  : SailFishVulnerability(VCT_SinkMustNotReach, Name, Importance,
379  Classification, Desc) {}
380 };
381 
385 class TaintExtras {
386 private:
387  TaintExtras() {}
388  friend class TaintStyleVulnerability;
389 
390 public:
391  virtual ~TaintExtras() {}
392  virtual bool isSinkFunction(const SymbolicExprGraph *G,
393  const SEGArgumentNode *Arg) const = 0;
398  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
399  std::vector<const SEGNodeBase *> &TransferDsts) {}
400 };
401 
405 public:
407  const char *Name, const BugDescription::BugImportance importance,
408  const BugDescription::BugClassification classification, const char *Desc)
409  : Vulnerability(VCT_Taint, Name, importance, classification, Desc) {}
410 
411  virtual PSAReportDecoratorDefault *allocNewDecorator() override {
412  return new PSATaintReportDecorator;
413  }
414 };
415 
419 protected:
421  std::vector<std::shared_ptr<Vulnerability>> Vulns;
422 
427  std::map<std::shared_ptr<Vulnerability>,
428  std::set<std::shared_ptr<Vulnerability>>>
430 
433  std::map<std::shared_ptr<Vulnerability>,
434  std::set<std::shared_ptr<Vulnerability>>>
436 
437  typedef std::pair<std::shared_ptr<Vulnerability>,
438  std::shared_ptr<Vulnerability>>
439  VulnPairTy;
440  typedef std::function<const SEGObject *(std::shared_ptr<VulnerabilityTrace>)>
441  GetTraceFunctionTy;
442  std::map<VulnPairTy, GetTraceFunctionTy> HeadDepFctorMap;
443  std::map<VulnPairTy, GetTraceFunctionTy> TailDepFctorMap;
445 
446 public:
447  virtual ~MultiVulnerability() {}
448 
451  bool add(std::shared_ptr<Vulnerability> V) {
452  Vulns.push_back(V);
453  return true;
454  }
455 
456  std::shared_ptr<Vulnerability> get(size_t Index) const {
457  return Vulns[Index];
458  }
459 
460  size_t size() const { return Vulns.size(); }
461 
462  std::vector<std::shared_ptr<Vulnerability>>::const_iterator begin() const {
463  return Vulns.begin();
464  }
465 
466  std::vector<std::shared_ptr<Vulnerability>>::const_iterator end() const {
467  return Vulns.end();
468  }
470 
472  virtual const char *getFullName() = 0;
473 
475  virtual const char *getAbbrName() = 0;
476 
486  virtual void buildDependence() = 0;
487 
490  void insertHeadDependence(std::shared_ptr<Vulnerability> V1,
491  std::shared_ptr<Vulnerability> V2,
492  GetTraceFunctionTy &Func) {
493  HeadDeps[V1].insert(V2);
494  HeadDepFctorMap[std::make_pair(V1, V2)] = Func;
495  }
496 
499  void insertTailDependence(std::shared_ptr<Vulnerability> V1,
500  std::shared_ptr<Vulnerability> V2,
501  GetTraceFunctionTy &Func) {
502  TailDeps[V1].insert(V2);
503  TailDepFctorMap[std::make_pair(V1, V2)] = Func;
504  }
505 
508  std::set<std::shared_ptr<Vulnerability>>::iterator
509  head_dep_begin(std::shared_ptr<Vulnerability> V) {
510  return HeadDeps[V].begin();
511  }
512 
513  std::set<std::shared_ptr<Vulnerability>>::iterator
514  head_dep_end(std::shared_ptr<Vulnerability> V) {
515  return HeadDeps[V].end();
516  }
517 
518  std::set<std::shared_ptr<Vulnerability>>::iterator
519  tail_dep_begin(std::shared_ptr<Vulnerability> V) {
520  return TailDeps[V].begin();
521  }
522 
523  std::set<std::shared_ptr<Vulnerability>>::iterator
524  tail_dep_end(std::shared_ptr<Vulnerability> V) {
525  return TailDeps[V].end();
526  }
529 
536  const SEGObject *getTraceHead(std::shared_ptr<Vulnerability> V1,
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);
542  }
543  return nullptr;
544  }
545 
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);
552  }
553  return nullptr;
554  }
555 
557 };
558 
559 #endif /* CHECKER_PSA_VULNERABILITY_H */
MultiVulnerability::TailDeps
std::map< std::shared_ptr< Vulnerability >, std::set< std::shared_ptr< Vulnerability > > > TailDeps
Definition: Vulnerability.h:435
Vulnerability::initializeAnalysis
virtual void initializeAnalysis(Pass *P)
Definition: Vulnerability.h:231
SEGOperandNode
Definition: SymbolicExprGraph.h:456
MultiVulnerability::insertHeadDependence
void insertHeadDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:490
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:169
Vulnerability::checkTrace
virtual bool checkTrace(std::shared_ptr< VulnerabilityTrace > &Trace)
Definition: Vulnerability.h:209
SinkMustReachVulnerability
Definition: Vulnerability.h:267
SymbolicExprGraph
Definition: SymbolicExprGraph.h:708
Vulnerability::isFlowInsensitive
virtual bool isFlowInsensitive()
Definition: Vulnerability.h:200
MultiVulnerability::add
bool add(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:451
SrcMustNotReachSinkVulnerability
Definition: Vulnerability.h:370
Vulnerability::SiteType
SiteType
Definition: Vulnerability.h:58
SailFishVulnerability
Definition: Vulnerability.h:287
Vulnerability::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &AU)
Definition: Vulnerability.h:219
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:536
Vulnerability::finalCheck
virtual bool finalCheck(const VulnerabilityTraceBuilder &TraceHistory)
Definition: Vulnerability.h:177
SymbolicExprGraphSolver
Definition: SymbolicExprGraphSolver.h:48
SEGObject
Definition: SymbolicExprGraph.h:76
MultiVulnerability::HeadDeps
std::map< std::shared_ptr< Vulnerability >, std::set< std::shared_ptr< Vulnerability > > > HeadDeps
Definition: Vulnerability.h:429
Vulnerability::ConstantCheck
virtual void ConstantCheck(const SymbolicExprGraph *SEG, std::list< shared_ptr< VulnerabilityTrace >> &AllTraces)
Definition: Vulnerability.h:188
MultiVulnerability
Definition: Vulnerability.h:418
SrcMustReachSinkVulnerability
Definition: Vulnerability.h:358
MultiVulnerability::head_dep_begin
std::set< std::shared_ptr< Vulnerability > >::iterator head_dep_begin(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:509
Vulnerability
Definition: Vulnerability.h:44
SailFishVulnerability::setSources
virtual void setSources(const SymbolicExprGraph *SEG, std::vector< ValueSitePairType > &Sources)
Definition: Vulnerability.h:295
MultiVulnerability::Vulns
std::vector< std::shared_ptr< Vulnerability > > Vulns
What the multi-vulnerability consists of.
Definition: Vulnerability.h:421
SailFishVulnerability::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:348
TaintStyleVulnerability
Definition: Vulnerability.h:404
Vulnerability::getDescription
const char * getDescription()
Return the description of the vulnerability.
Definition: Vulnerability.h:245
SailFishVulnerability::checkSite
virtual Vulnerability::SiteType checkSite(const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory) override
Definition: Vulnerability.h:317
MultiVulnerability::insertTailDependence
void insertTailDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:499
SailFishVulnerability::setPrerequisites
virtual void setPrerequisites(SymbolicExprGraphSolver *Solver, const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory, SMTExprVec &Prerequisites) override
Definition: Vulnerability.h:335
SinkMustNotReachVulnerability
Definition: Vulnerability.h:278
TaintExtras
Definition: Vulnerability.h:385
SEGSiteBase
Definition: SymbolicExprGraph.h:663
Vulnerability::isParasitical
bool isParasitical() const
Definition: Vulnerability.h:240
SEGNodeBase
The node base of symbolic expression graph.
Definition: SymbolicExprGraph.h:244
Vulnerability::getName
const char * getName()
Return the name of the vulnerability.
Definition: Vulnerability.h:254
TaintExtras::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:398