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_TypeState,
84  VCT_End
85  };
86 
90  typedef typename std::pair<const SEGOperandNode *, const SEGSiteBase *>
92 
93 private:
95  VulnerabilityCategoryType CategoryType;
96 
109  bool Parasitical = true;
110 
111  const char *VulnName;
112  const BugDescription::BugImportance Importance;
113  const BugDescription::BugClassification Classification;
114  const char *VulnDescription;
115 
116  // The constructor is made private and, thus it cannot be extended.
117  // Users must extend its sub-classes to implement different types of
118  // vulnerabilities.
119  Vulnerability(VulnerabilityCategoryType CTy, const char *Name,
120  const BugDescription::BugImportance Importance,
121  const BugDescription::BugClassification Classification,
122  const char *Desc)
123  : CategoryType(CTy), VulnName(Name), Importance(Importance),
124  Classification(Classification), VulnDescription(Desc) {}
125 
126  friend class SinkMustReachVulnerability;
127  friend class SinkMustNotReachVulnerability;
128  friend class TaintStyleVulnerability;
130  friend class SrcMustReachSinkVulnerability;
131  friend class SailFishVulnerability;
132  friend class TSAVulnerability;
133 
134 public:
135  virtual ~Vulnerability() {}
136 
143  virtual void setSources(const SymbolicExprGraph *SEG,
144  std::vector<ValueSitePairType> &Sources) = 0;
145 
156  virtual void setPrerequisites(SymbolicExprGraphSolver *Solver,
157  const SEGSiteBase *CurrSite,
158  const VulnerabilityTraceBuilder &TraceHistory,
159  SMTExprVec &Prerequisites) = 0;
160 
171  virtual bool checkNode(const SEGNodeBase *CurrNode,
172  const VulnerabilityTraceBuilder &TraceHistory) {
173  return false;
174  }
175 
179  virtual bool finalCheck(const VulnerabilityTraceBuilder &TraceHistory) {
180  return true;
181  }
182 
189  virtual void
191  std::list<shared_ptr<VulnerabilityTrace>> &AllTraces) {
192  return;
193  }
194 
202  virtual bool isFlowInsensitive() { return false; }
203 
206  virtual SiteType checkSite(const SEGSiteBase *CurrSite,
207  const VulnerabilityTraceBuilder &TraceHistory) = 0;
208 
211  virtual bool checkTrace(std::shared_ptr<VulnerabilityTrace> &Trace) {
212  return true;
213  }
214 
221  virtual void getAnalysisUsage(AnalysisUsage &AU) {}
222 
233  virtual void initializeAnalysis(Pass *P) {}
235 
236 public:
237  VulnerabilityCategoryType getCategoryType() const { return CategoryType; }
238 
242  bool isParasitical() const { return Parasitical; }
243 
244  void setParasitical(bool B) { Parasitical = B; }
245 
247  const char *getDescription() { return VulnDescription; }
248 
249  BugDescription::BugImportance getImportance() const { return Importance; }
250 
251  BugDescription::BugClassification getClassification() const {
252  return Classification;
253  }
254 
256  const char *getName() { return VulnName; }
257 
258  virtual PSAReportDecoratorDefault *allocNewDecorator() {
259  return new PSAReportDecoratorDefault;
260  }
261 
262  virtual void destroyDecorator(PSAReportDecoratorDefault *decorator) {
263  delete decorator;
264  }
265 };
266 
270 public:
272  const char *Name, const BugDescription::BugImportance importance,
273  const BugDescription::BugClassification classification, const char *Desc)
274  : Vulnerability(VCT_SinkMustReach, Name, importance, classification,
275  Desc) {}
276 };
277 
281 public:
283  const char *Name, const BugDescription::BugImportance Importance,
284  const BugDescription::BugClassification Classification, const char *Desc)
285  : Vulnerability(VCT_SinkMustNotReach, Name, Importance, Classification,
286  Desc) {}
287 };
288 
290 public:
291  SailFishVulnerability(VulnerabilityCategoryType CTy, const char *Name,
292  const BugDescription::BugImportance Importance,
293  const BugDescription::BugClassification Classification,
294  const char *Desc)
295  : Vulnerability(CTy, Name, Importance, Classification, Desc) {}
296 
297  virtual void setSources(const SymbolicExprGraph *SEG,
298  std::vector<ValueSitePairType> &Sources) {
299  for (auto It = SEG->value_node_begin(), E = SEG->value_node_end(); It != E;
300  It++) {
301  SEGOperandNode *Node = It->second;
302 
303  for (auto SiteIt = Node->use_site_begin(), SiteE = Node->use_site_end();
304  SiteIt != SiteE; SiteIt++) {
305  if (isSource(Node, *SiteIt)) {
306  Sources.emplace_back(Node, *SiteIt);
307  }
308  }
309 
310  if (!Node->use_site_size()) {
311  if (isSource(Node, nullptr)) {
312  Sources.emplace_back(Node, nullptr);
313  }
314  }
315  }
316  }
317 
319  checkSite(const SEGSiteBase *CurrSite,
320  const VulnerabilityTraceBuilder &TraceHistory) override {
321  auto *Node = TraceHistory.recentObjAs<SEGOperandNode>();
322 
323  if (isSink((SEGNodeBase *)Node, const_cast<SEGSiteBase *>(CurrSite))) {
324  return ST_Sink;
325  } else if (isa<SEGReturnSite>(CurrSite)) {
326  return ST_Return;
327  } else if (isa<SEGCallSite>(CurrSite)) {
328  return ST_Call;
329  }
330  return ST_Others;
331  }
332 
333  virtual bool isSource(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
334 
335  virtual bool isSink(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
336 
338  const SEGSiteBase *CurrSite,
339  const VulnerabilityTraceBuilder &TraceHistory,
340  SMTExprVec &Prerequisites) override {
341  // Prerequisites.push_back(
342  // Solver->getOrInsertExpr(TraceHistory.recentObjAs<SEGNodeBase>())
343  // == 0);
344  }
345 
350  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
351  std::vector<const SEGNodeBase *> &TransferDsts) {}
352 
353 public:
354  static bool classof(const Vulnerability *vuln) {
355  return vuln->getCategoryType() > VCT_Begin &&
356  vuln->getCategoryType() < VCT_End;
357  }
358 };
359 
361 public:
363  const char *Name,
364  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
365  BugDescription::BugClassification Classification =
366  BugDescription::BC_SECURITY,
367  const char *Desc = "CUSTOMIZED")
368  : SailFishVulnerability(VCT_SinkMustReach, Name, Importance,
369  Classification, Desc) {}
370 };
371 
373 public:
375  const char *Name,
376  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
377  BugDescription::BugClassification Classification =
378  BugDescription::BC_SECURITY,
379  const char *Desc = "CUSTOMIZED")
380  : SailFishVulnerability(VCT_SinkMustNotReach, Name, Importance,
381  Classification, Desc) {}
382 };
383 
387 class TaintExtras {
388 private:
389  TaintExtras() {}
390  friend class TaintStyleVulnerability;
391 
392 public:
393  virtual ~TaintExtras() {}
394  virtual bool isSinkFunction(const SymbolicExprGraph *G,
395  const SEGArgumentNode *Arg) const = 0;
400  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
401  std::vector<const SEGNodeBase *> &TransferDsts) {}
402 };
403 
407 public:
409  const char *Name, const BugDescription::BugImportance importance,
410  const BugDescription::BugClassification classification, const char *Desc)
411  : Vulnerability(VCT_Taint, Name, importance, classification, Desc) {}
412 
413  virtual PSAReportDecoratorDefault *allocNewDecorator() override {
414  return new PSATaintReportDecorator;
415  }
416 };
417 
421 protected:
423  std::vector<std::shared_ptr<Vulnerability>> Vulns;
424 
429  std::map<std::shared_ptr<Vulnerability>,
430  std::set<std::shared_ptr<Vulnerability>>>
432 
435  std::map<std::shared_ptr<Vulnerability>,
436  std::set<std::shared_ptr<Vulnerability>>>
438 
439  typedef std::pair<std::shared_ptr<Vulnerability>,
440  std::shared_ptr<Vulnerability>>
441  VulnPairTy;
442  typedef std::function<const SEGObject *(std::shared_ptr<VulnerabilityTrace>)>
443  GetTraceFunctionTy;
444  std::map<VulnPairTy, GetTraceFunctionTy> HeadDepFctorMap;
445  std::map<VulnPairTy, GetTraceFunctionTy> TailDepFctorMap;
447 
448 public:
449  virtual ~MultiVulnerability() {}
450 
453  bool add(std::shared_ptr<Vulnerability> V) {
454  Vulns.push_back(V);
455  return true;
456  }
457 
458  std::shared_ptr<Vulnerability> get(size_t Index) const {
459  return Vulns[Index];
460  }
461 
462  size_t size() const { return Vulns.size(); }
463 
464  std::vector<std::shared_ptr<Vulnerability>>::const_iterator begin() const {
465  return Vulns.begin();
466  }
467 
468  std::vector<std::shared_ptr<Vulnerability>>::const_iterator end() const {
469  return Vulns.end();
470  }
472 
474  virtual const char *getFullName() = 0;
475 
477  virtual const char *getAbbrName() = 0;
478 
488  virtual void buildDependence() = 0;
489 
492  void insertHeadDependence(std::shared_ptr<Vulnerability> V1,
493  std::shared_ptr<Vulnerability> V2,
494  GetTraceFunctionTy &Func) {
495  HeadDeps[V1].insert(V2);
496  HeadDepFctorMap[std::make_pair(V1, V2)] = Func;
497  }
498 
501  void insertTailDependence(std::shared_ptr<Vulnerability> V1,
502  std::shared_ptr<Vulnerability> V2,
503  GetTraceFunctionTy &Func) {
504  TailDeps[V1].insert(V2);
505  TailDepFctorMap[std::make_pair(V1, V2)] = Func;
506  }
507 
510  std::set<std::shared_ptr<Vulnerability>>::iterator
511  head_dep_begin(std::shared_ptr<Vulnerability> V) {
512  return HeadDeps[V].begin();
513  }
514 
515  std::set<std::shared_ptr<Vulnerability>>::iterator
516  head_dep_end(std::shared_ptr<Vulnerability> V) {
517  return HeadDeps[V].end();
518  }
519 
520  std::set<std::shared_ptr<Vulnerability>>::iterator
521  tail_dep_begin(std::shared_ptr<Vulnerability> V) {
522  return TailDeps[V].begin();
523  }
524 
525  std::set<std::shared_ptr<Vulnerability>>::iterator
526  tail_dep_end(std::shared_ptr<Vulnerability> V) {
527  return TailDeps[V].end();
528  }
531 
538  const SEGObject *getTraceHead(std::shared_ptr<Vulnerability> V1,
539  std::shared_ptr<VulnerabilityTrace> T1,
540  std::shared_ptr<Vulnerability> V2) {
541  auto It = HeadDepFctorMap.find(std::make_pair(V1, V2));
542  if (It != HeadDepFctorMap.end()) {
543  return It->second(T1);
544  }
545  return nullptr;
546  }
547 
548  const SEGObject *getTraceTail(std::shared_ptr<Vulnerability> V1,
549  std::shared_ptr<VulnerabilityTrace> T1,
550  std::shared_ptr<Vulnerability> V2) {
551  auto It = TailDepFctorMap.find(std::make_pair(V1, V2));
552  if (It != TailDepFctorMap.end()) {
553  return It->second(T1);
554  }
555  return nullptr;
556  }
557 
559 };
560 
561 #endif /* CHECKER_PSA_VULNERABILITY_H */
MultiVulnerability::TailDeps
std::map< std::shared_ptr< Vulnerability >, std::set< std::shared_ptr< Vulnerability > > > TailDeps
Definition: Vulnerability.h:437
Vulnerability::initializeAnalysis
virtual void initializeAnalysis(Pass *P)
Definition: Vulnerability.h:233
SEGOperandNode
Definition: SymbolicExprGraph.h:456
MultiVulnerability::insertHeadDependence
void insertHeadDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:492
Vulnerability::VulnerabilityCategoryType
VulnerabilityCategoryType
Definition: Vulnerability.h:78
Vulnerability::ValueSitePairType
std::pair< const SEGOperandNode *, const SEGSiteBase * > ValueSitePairType
Definition: Vulnerability.h:91
Vulnerability::checkNode
virtual bool checkNode(const SEGNodeBase *CurrNode, const VulnerabilityTraceBuilder &TraceHistory)
Definition: Vulnerability.h:171
Vulnerability::checkTrace
virtual bool checkTrace(std::shared_ptr< VulnerabilityTrace > &Trace)
Definition: Vulnerability.h:211
SinkMustReachVulnerability
Definition: Vulnerability.h:269
SymbolicExprGraph
Definition: SymbolicExprGraph.h:707
Vulnerability::isFlowInsensitive
virtual bool isFlowInsensitive()
Definition: Vulnerability.h:202
MultiVulnerability::add
bool add(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:453
SrcMustNotReachSinkVulnerability
Definition: Vulnerability.h:372
Vulnerability::SiteType
SiteType
Definition: Vulnerability.h:58
SailFishVulnerability
Definition: Vulnerability.h:289
Vulnerability::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &AU)
Definition: Vulnerability.h:221
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:538
Vulnerability::finalCheck
virtual bool finalCheck(const VulnerabilityTraceBuilder &TraceHistory)
Definition: Vulnerability.h:179
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:431
Vulnerability::ConstantCheck
virtual void ConstantCheck(const SymbolicExprGraph *SEG, std::list< shared_ptr< VulnerabilityTrace >> &AllTraces)
Definition: Vulnerability.h:190
MultiVulnerability
Definition: Vulnerability.h:420
SrcMustReachSinkVulnerability
Definition: Vulnerability.h:360
MultiVulnerability::head_dep_begin
std::set< std::shared_ptr< Vulnerability > >::iterator head_dep_begin(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:511
Vulnerability
Definition: Vulnerability.h:44
SailFishVulnerability::setSources
virtual void setSources(const SymbolicExprGraph *SEG, std::vector< ValueSitePairType > &Sources)
Definition: Vulnerability.h:297
MultiVulnerability::Vulns
std::vector< std::shared_ptr< Vulnerability > > Vulns
What the multi-vulnerability consists of.
Definition: Vulnerability.h:423
SailFishVulnerability::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:350
TaintStyleVulnerability
Definition: Vulnerability.h:406
Vulnerability::getDescription
const char * getDescription()
Return the description of the vulnerability.
Definition: Vulnerability.h:247
SailFishVulnerability::checkSite
virtual Vulnerability::SiteType checkSite(const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory) override
Definition: Vulnerability.h:319
MultiVulnerability::insertTailDependence
void insertTailDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:501
SailFishVulnerability::setPrerequisites
virtual void setPrerequisites(SymbolicExprGraphSolver *Solver, const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory, SMTExprVec &Prerequisites) override
Definition: Vulnerability.h:337
SinkMustNotReachVulnerability
Definition: Vulnerability.h:280
TaintExtras
Definition: Vulnerability.h:387
SEGSiteBase
Definition: SymbolicExprGraph.h:663
Vulnerability::isParasitical
bool isParasitical() const
Definition: Vulnerability.h:242
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:256
TaintExtras::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:400