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 
146  virtual void setSinks(const SymbolicExprGraph *SEG,
147  std::vector<ValueSitePairType> &Sinks) {
148  return;
149  }
150 
161  virtual void setPrerequisites(SymbolicExprGraphSolver *Solver,
162  const SEGSiteBase *CurrSite,
163  const VulnerabilityTraceBuilder &TraceHistory,
164  SMTExprVec &Prerequisites) = 0;
165 
176  virtual bool checkNode(const SEGNodeBase *CurrNode,
177  const VulnerabilityTraceBuilder &TraceHistory) {
178  return false;
179  }
180 
184  virtual bool finalCheck(const VulnerabilityTraceBuilder &TraceHistory) {
185  return true;
186  }
187 
194  virtual void
196  std::list<shared_ptr<VulnerabilityTrace>> &AllTraces) {
197  return;
198  }
199 
207  virtual bool isFlowInsensitive() { return false; }
208 
211  virtual SiteType checkSite(const SEGSiteBase *CurrSite,
212  const VulnerabilityTraceBuilder &TraceHistory) = 0;
213 
216  virtual bool checkTrace(std::shared_ptr<VulnerabilityTrace> &Trace) {
217  return true;
218  }
219 
226  virtual void getAnalysisUsage(AnalysisUsage &AU) {}
227 
238  virtual void initializeAnalysis(Pass *P) {}
240 
241 public:
242  VulnerabilityCategoryType getCategoryType() const { return CategoryType; }
243 
247  bool isParasitical() const { return Parasitical; }
248 
249  void setParasitical(bool B) { Parasitical = B; }
250 
252  const char *getDescription() { return VulnDescription; }
253 
254  BugDescription::BugImportance getImportance() const { return Importance; }
255 
256  BugDescription::BugClassification getClassification() const {
257  return Classification;
258  }
259 
261  const char *getName() { return VulnName; }
262 
263  virtual PSAReportDecoratorDefault *allocNewDecorator() {
264  return new PSAReportDecoratorDefault;
265  }
266 
267  virtual void destroyDecorator(PSAReportDecoratorDefault *decorator) {
268  delete decorator;
269  }
270 };
271 
275 public:
277  const char *Name, const BugDescription::BugImportance importance,
278  const BugDescription::BugClassification classification, const char *Desc)
279  : Vulnerability(VCT_SinkMustReach, Name, importance, classification,
280  Desc) {}
281 };
282 
286 public:
288  const char *Name, const BugDescription::BugImportance Importance,
289  const BugDescription::BugClassification Classification, const char *Desc)
290  : Vulnerability(VCT_SinkMustNotReach, Name, Importance, Classification,
291  Desc) {}
292 };
293 
295 public:
296  SailFishVulnerability(VulnerabilityCategoryType CTy, const char *Name,
297  const BugDescription::BugImportance Importance,
298  const BugDescription::BugClassification Classification,
299  const char *Desc)
300  : Vulnerability(CTy, Name, Importance, Classification, Desc) {}
301 
302  virtual void setSources(const SymbolicExprGraph *SEG,
303  std::vector<ValueSitePairType> &Sources) {
304  for (auto It = SEG->value_node_begin(), E = SEG->value_node_end(); It != E;
305  It++) {
306  SEGOperandNode *Node = It->second;
307 
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);
312  }
313  }
314 
315  if (!Node->use_site_size()) {
316  if (isSource(Node, nullptr)) {
317  Sources.emplace_back(Node, nullptr);
318  }
319  }
320  }
321  }
322 
324  checkSite(const SEGSiteBase *CurrSite,
325  const VulnerabilityTraceBuilder &TraceHistory) override {
326  auto *Node = TraceHistory.recentObjAs<SEGOperandNode>();
327 
328  if (isSink((SEGNodeBase *)Node, const_cast<SEGSiteBase *>(CurrSite))) {
329  return ST_Sink;
330  } else if (isa<SEGReturnSite>(CurrSite)) {
331  return ST_Return;
332  } else if (isa<SEGCallSite>(CurrSite)) {
333  return ST_Call;
334  }
335  return ST_Others;
336  }
337 
338  virtual bool isSource(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
339 
340  virtual bool isSink(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
341 
343  const SEGSiteBase *CurrSite,
344  const VulnerabilityTraceBuilder &TraceHistory,
345  SMTExprVec &Prerequisites) override {
346  // Prerequisites.push_back(
347  // Solver->getOrInsertExpr(TraceHistory.recentObjAs<SEGNodeBase>())
348  // == 0);
349  }
350 
355  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
356  std::vector<const SEGNodeBase *> &TransferDsts) {}
357 
358 public:
359  static bool classof(const Vulnerability *vuln) {
360  return vuln->getCategoryType() > VCT_Begin &&
361  vuln->getCategoryType() < VCT_End;
362  }
363 };
364 
366 public:
368  const char *Name,
369  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
370  BugDescription::BugClassification Classification =
371  BugDescription::BC_SECURITY,
372  const char *Desc = "CUSTOMIZED")
373  : SailFishVulnerability(VCT_SinkMustReach, Name, Importance,
374  Classification, Desc) {}
375 };
376 
378 public:
380  const char *Name,
381  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
382  BugDescription::BugClassification Classification =
383  BugDescription::BC_SECURITY,
384  const char *Desc = "CUSTOMIZED")
385  : SailFishVulnerability(VCT_SinkMustNotReach, Name, Importance,
386  Classification, Desc) {}
387 };
388 
392 class TaintExtras {
393 private:
394  TaintExtras() {}
395  friend class TaintStyleVulnerability;
396 
397 public:
398  virtual ~TaintExtras() {}
399  virtual bool isSinkFunction(const SymbolicExprGraph *G,
400  const SEGArgumentNode *Arg) const = 0;
405  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
406  std::vector<const SEGNodeBase *> &TransferDsts) {}
407 };
408 
412 public:
414  const char *Name, const BugDescription::BugImportance importance,
415  const BugDescription::BugClassification classification, const char *Desc)
416  : Vulnerability(VCT_Taint, Name, importance, classification, Desc) {}
417 
418  virtual PSAReportDecoratorDefault *allocNewDecorator() override {
419  return new PSATaintReportDecorator;
420  }
421 };
422 
426 protected:
428  std::vector<std::shared_ptr<Vulnerability>> Vulns;
429 
434  std::map<std::shared_ptr<Vulnerability>,
435  std::set<std::shared_ptr<Vulnerability>>>
437 
440  std::map<std::shared_ptr<Vulnerability>,
441  std::set<std::shared_ptr<Vulnerability>>>
443 
444  typedef std::pair<std::shared_ptr<Vulnerability>,
445  std::shared_ptr<Vulnerability>>
446  VulnPairTy;
447  typedef std::function<const SEGObject *(std::shared_ptr<VulnerabilityTrace>)>
448  GetTraceFunctionTy;
449  std::map<VulnPairTy, GetTraceFunctionTy> HeadDepFctorMap;
450  std::map<VulnPairTy, GetTraceFunctionTy> TailDepFctorMap;
452 
453 public:
454  virtual ~MultiVulnerability() {}
455 
458  bool add(std::shared_ptr<Vulnerability> V) {
459  Vulns.push_back(V);
460  return true;
461  }
462 
463  std::shared_ptr<Vulnerability> get(size_t Index) const {
464  return Vulns[Index];
465  }
466 
467  size_t size() const { return Vulns.size(); }
468 
469  std::vector<std::shared_ptr<Vulnerability>>::const_iterator begin() const {
470  return Vulns.begin();
471  }
472 
473  std::vector<std::shared_ptr<Vulnerability>>::const_iterator end() const {
474  return Vulns.end();
475  }
477 
479  virtual const char *getFullName() = 0;
480 
482  virtual const char *getAbbrName() = 0;
483 
493  virtual void buildDependence() = 0;
494 
497  void insertHeadDependence(std::shared_ptr<Vulnerability> V1,
498  std::shared_ptr<Vulnerability> V2,
499  GetTraceFunctionTy &Func) {
500  HeadDeps[V1].insert(V2);
501  HeadDepFctorMap[std::make_pair(V1, V2)] = Func;
502  }
503 
506  void insertTailDependence(std::shared_ptr<Vulnerability> V1,
507  std::shared_ptr<Vulnerability> V2,
508  GetTraceFunctionTy &Func) {
509  TailDeps[V1].insert(V2);
510  TailDepFctorMap[std::make_pair(V1, V2)] = Func;
511  }
512 
515  std::set<std::shared_ptr<Vulnerability>>::iterator
516  head_dep_begin(std::shared_ptr<Vulnerability> V) {
517  return HeadDeps[V].begin();
518  }
519 
520  std::set<std::shared_ptr<Vulnerability>>::iterator
521  head_dep_end(std::shared_ptr<Vulnerability> V) {
522  return HeadDeps[V].end();
523  }
524 
525  std::set<std::shared_ptr<Vulnerability>>::iterator
526  tail_dep_begin(std::shared_ptr<Vulnerability> V) {
527  return TailDeps[V].begin();
528  }
529 
530  std::set<std::shared_ptr<Vulnerability>>::iterator
531  tail_dep_end(std::shared_ptr<Vulnerability> V) {
532  return TailDeps[V].end();
533  }
536 
543  const SEGObject *getTraceHead(std::shared_ptr<Vulnerability> V1,
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);
549  }
550  return nullptr;
551  }
552 
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);
559  }
560  return nullptr;
561  }
562 
564 };
565 
566 #endif /* CHECKER_PSA_VULNERABILITY_H */
MultiVulnerability::TailDeps
std::map< std::shared_ptr< Vulnerability >, std::set< std::shared_ptr< Vulnerability > > > TailDeps
Definition: Vulnerability.h:442
Vulnerability::initializeAnalysis
virtual void initializeAnalysis(Pass *P)
Definition: Vulnerability.h:238
SEGOperandNode
Definition: SymbolicExprGraph.h:456
MultiVulnerability::insertHeadDependence
void insertHeadDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:497
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:176
Vulnerability::checkTrace
virtual bool checkTrace(std::shared_ptr< VulnerabilityTrace > &Trace)
Definition: Vulnerability.h:216
SinkMustReachVulnerability
Definition: Vulnerability.h:274
SymbolicExprGraph
Definition: SymbolicExprGraph.h:707
Vulnerability::isFlowInsensitive
virtual bool isFlowInsensitive()
Definition: Vulnerability.h:207
MultiVulnerability::add
bool add(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:458
SrcMustNotReachSinkVulnerability
Definition: Vulnerability.h:377
Vulnerability::SiteType
SiteType
Definition: Vulnerability.h:58
SailFishVulnerability
Definition: Vulnerability.h:294
Vulnerability::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &AU)
Definition: Vulnerability.h:226
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:543
Vulnerability::finalCheck
virtual bool finalCheck(const VulnerabilityTraceBuilder &TraceHistory)
Definition: Vulnerability.h:184
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:436
Vulnerability::ConstantCheck
virtual void ConstantCheck(const SymbolicExprGraph *SEG, std::list< shared_ptr< VulnerabilityTrace >> &AllTraces)
Definition: Vulnerability.h:195
MultiVulnerability
Definition: Vulnerability.h:425
SrcMustReachSinkVulnerability
Definition: Vulnerability.h:365
MultiVulnerability::head_dep_begin
std::set< std::shared_ptr< Vulnerability > >::iterator head_dep_begin(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:516
Vulnerability
Definition: Vulnerability.h:44
SailFishVulnerability::setSources
virtual void setSources(const SymbolicExprGraph *SEG, std::vector< ValueSitePairType > &Sources)
Definition: Vulnerability.h:302
MultiVulnerability::Vulns
std::vector< std::shared_ptr< Vulnerability > > Vulns
What the multi-vulnerability consists of.
Definition: Vulnerability.h:428
SailFishVulnerability::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:355
TaintStyleVulnerability
Definition: Vulnerability.h:411
Vulnerability::getDescription
const char * getDescription()
Return the description of the vulnerability.
Definition: Vulnerability.h:252
SailFishVulnerability::checkSite
virtual Vulnerability::SiteType checkSite(const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory) override
Definition: Vulnerability.h:324
MultiVulnerability::insertTailDependence
void insertTailDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:506
SailFishVulnerability::setPrerequisites
virtual void setPrerequisites(SymbolicExprGraphSolver *Solver, const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory, SMTExprVec &Prerequisites) override
Definition: Vulnerability.h:342
SinkMustNotReachVulnerability
Definition: Vulnerability.h:285
TaintExtras
Definition: Vulnerability.h:392
SEGSiteBase
Definition: SymbolicExprGraph.h:663
Vulnerability::isParasitical
bool isParasitical() const
Definition: Vulnerability.h:247
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:261
TaintExtras::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:405