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 
176  virtual SiteType checkSite(const SEGSiteBase *CurrSite,
177  const VulnerabilityTraceBuilder &TraceHistory) = 0;
178 
181  virtual bool checkTrace(std::shared_ptr<VulnerabilityTrace> &Trace) {
182  return true;
183  }
184 
191  virtual void getAnalysisUsage(AnalysisUsage &AU) {}
192 
203  virtual void initializeAnalysis(Pass *P) {}
205 
206 public:
207  VulnerabilityCategoryType getCategoryType() const { return CategoryType; }
208 
212  bool isParasitical() const { return Parasitical; }
213 
214  void setParasitical(bool B) { Parasitical = B; }
215 
217  const char *getDescription() { return VulnDescription; }
218 
219  BugDescription::BugImportance getImportance() const { return Importance; }
220 
221  BugDescription::BugClassification getClassification() const {
222  return Classification;
223  }
224 
226  const char *getName() { return VulnName; }
227 
228  virtual PSAReportDecoratorDefault *allocNewDecorator() {
229  return new PSAReportDecoratorDefault;
230  }
231 
232  virtual void destroyDecorator(PSAReportDecoratorDefault *decorator) {
233  delete decorator;
234  }
235 };
236 
240 public:
242  const char *Name, const BugDescription::BugImportance importance,
243  const BugDescription::BugClassification classification, const char *Desc)
244  : Vulnerability(VCT_SinkMustReach, Name, importance, classification,
245  Desc) {}
246 };
247 
251 public:
253  const char *Name, const BugDescription::BugImportance Importance,
254  const BugDescription::BugClassification Classification, const char *Desc)
255  : Vulnerability(VCT_SinkMustNotReach, Name, Importance, Classification,
256  Desc) {}
257 };
258 
260 public:
261  SailFishVulnerability(VulnerabilityCategoryType CTy, const char *Name,
262  const BugDescription::BugImportance Importance,
263  const BugDescription::BugClassification Classification,
264  const char *Desc)
265  : Vulnerability(CTy, Name, Importance, Classification, Desc) {}
266 
267  virtual void setSources(const SymbolicExprGraph *SEG,
268  std::vector<ValueSitePairType> &Sources) {
269  for (auto It = SEG->value_node_begin(), E = SEG->value_node_end(); It != E;
270  It++) {
271  SEGOperandNode *Node = It->second;
272 
273  for (auto SiteIt = Node->use_site_begin(), SiteE = Node->use_site_end();
274  SiteIt != SiteE; SiteIt++) {
275  if (isSource(Node, *SiteIt)) {
276  Sources.emplace_back(Node, *SiteIt);
277  }
278  }
279 
280  if (!Node->use_site_size()) {
281  if (isSource(Node, nullptr)) {
282  Sources.emplace_back(Node, nullptr);
283  }
284  }
285  }
286  }
287 
289  checkSite(const SEGSiteBase *CurrSite,
290  const VulnerabilityTraceBuilder &TraceHistory) override {
291  auto *Node = TraceHistory.recentObjAs<SEGOperandNode>();
292 
293  if (isSink((SEGNodeBase *)Node, const_cast<SEGSiteBase *>(CurrSite))) {
294  return ST_Sink;
295  } else if (isa<SEGReturnSite>(CurrSite)) {
296  return ST_Return;
297  } else if (isa<SEGCallSite>(CurrSite)) {
298  return ST_Call;
299  }
300  return ST_Others;
301  }
302 
303  virtual bool isSource(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
304 
305  virtual bool isSink(SEGNodeBase *Node, SEGSiteBase *Site) { return false; };
306 
308  const SEGSiteBase *CurrSite,
309  const VulnerabilityTraceBuilder &TraceHistory,
310  SMTExprVec &Prerequisites) override {
311  // Prerequisites.push_back(
312  // Solver->getOrInsertExpr(TraceHistory.recentObjAs<SEGNodeBase>())
313  // == 0);
314  }
315 
320  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
321  std::vector<const SEGNodeBase *> &TransferDsts) {}
322 
323 public:
324  static bool classof(const Vulnerability *vuln) {
325  return vuln->getCategoryType() > VCT_Begin &&
326  vuln->getCategoryType() < VCT_End;
327  }
328 };
329 
331 public:
333  const char *Name,
334  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
335  BugDescription::BugClassification Classification =
336  BugDescription::BC_SECURITY,
337  const char *Desc = "CUSTOMIZED")
338  : SailFishVulnerability(VCT_SinkMustReach, Name, Importance,
339  Classification, Desc) {}
340 };
341 
343 public:
345  const char *Name,
346  BugDescription::BugImportance Importance = BugDescription::BI_MEDIUM,
347  BugDescription::BugClassification Classification =
348  BugDescription::BC_SECURITY,
349  const char *Desc = "CUSTOMIZED")
350  : SailFishVulnerability(VCT_SinkMustNotReach, Name, Importance,
351  Classification, Desc) {}
352 };
353 
357 class TaintExtras {
358 private:
359  TaintExtras() {}
360  friend class TaintStyleVulnerability;
361 
362 public:
363  virtual ~TaintExtras() {}
364  virtual bool isSinkFunction(const SymbolicExprGraph *G,
365  const SEGArgumentNode *Arg) const = 0;
370  virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg,
371  std::vector<const SEGNodeBase *> &TransferDsts) {}
372 };
373 
377 public:
379  const char *Name, const BugDescription::BugImportance importance,
380  const BugDescription::BugClassification classification, const char *Desc)
381  : Vulnerability(VCT_Taint, Name, importance, classification, Desc) {}
382 
383  virtual PSAReportDecoratorDefault *allocNewDecorator() override {
384  return new PSATaintReportDecorator;
385  }
386 };
387 
391 protected:
393  std::vector<std::shared_ptr<Vulnerability>> Vulns;
394 
399  std::map<std::shared_ptr<Vulnerability>,
400  std::set<std::shared_ptr<Vulnerability>>>
402 
405  std::map<std::shared_ptr<Vulnerability>,
406  std::set<std::shared_ptr<Vulnerability>>>
408 
409  typedef std::pair<std::shared_ptr<Vulnerability>,
410  std::shared_ptr<Vulnerability>>
411  VulnPairTy;
412  typedef std::function<const SEGObject *(std::shared_ptr<VulnerabilityTrace>)>
413  GetTraceFunctionTy;
414  std::map<VulnPairTy, GetTraceFunctionTy> HeadDepFctorMap;
415  std::map<VulnPairTy, GetTraceFunctionTy> TailDepFctorMap;
417 
418 public:
419  virtual ~MultiVulnerability() {}
420 
423  bool add(std::shared_ptr<Vulnerability> V) {
424  Vulns.push_back(V);
425  return true;
426  }
427 
428  std::shared_ptr<Vulnerability> get(size_t Index) const {
429  return Vulns[Index];
430  }
431 
432  size_t size() const { return Vulns.size(); }
433 
434  std::vector<std::shared_ptr<Vulnerability>>::const_iterator begin() const {
435  return Vulns.begin();
436  }
437 
438  std::vector<std::shared_ptr<Vulnerability>>::const_iterator end() const {
439  return Vulns.end();
440  }
442 
444  virtual const char *getFullName() = 0;
445 
447  virtual const char *getAbbrName() = 0;
448 
458  virtual void buildDependence() = 0;
459 
462  void insertHeadDependence(std::shared_ptr<Vulnerability> V1,
463  std::shared_ptr<Vulnerability> V2,
464  GetTraceFunctionTy &Func) {
465  HeadDeps[V1].insert(V2);
466  HeadDepFctorMap[std::make_pair(V1, V2)] = Func;
467  }
468 
471  void insertTailDependence(std::shared_ptr<Vulnerability> V1,
472  std::shared_ptr<Vulnerability> V2,
473  GetTraceFunctionTy &Func) {
474  TailDeps[V1].insert(V2);
475  TailDepFctorMap[std::make_pair(V1, V2)] = Func;
476  }
477 
480  std::set<std::shared_ptr<Vulnerability>>::iterator
481  head_dep_begin(std::shared_ptr<Vulnerability> V) {
482  return HeadDeps[V].begin();
483  }
484 
485  std::set<std::shared_ptr<Vulnerability>>::iterator
486  head_dep_end(std::shared_ptr<Vulnerability> V) {
487  return HeadDeps[V].end();
488  }
489 
490  std::set<std::shared_ptr<Vulnerability>>::iterator
491  tail_dep_begin(std::shared_ptr<Vulnerability> V) {
492  return TailDeps[V].begin();
493  }
494 
495  std::set<std::shared_ptr<Vulnerability>>::iterator
496  tail_dep_end(std::shared_ptr<Vulnerability> V) {
497  return TailDeps[V].end();
498  }
501 
508  const SEGObject *getTraceHead(std::shared_ptr<Vulnerability> V1,
509  std::shared_ptr<VulnerabilityTrace> T1,
510  std::shared_ptr<Vulnerability> V2) {
511  auto It = HeadDepFctorMap.find(std::make_pair(V1, V2));
512  if (It != HeadDepFctorMap.end()) {
513  return It->second(T1);
514  }
515  return nullptr;
516  }
517 
518  const SEGObject *getTraceTail(std::shared_ptr<Vulnerability> V1,
519  std::shared_ptr<VulnerabilityTrace> T1,
520  std::shared_ptr<Vulnerability> V2) {
521  auto It = TailDepFctorMap.find(std::make_pair(V1, V2));
522  if (It != TailDepFctorMap.end()) {
523  return It->second(T1);
524  }
525  return nullptr;
526  }
527 
529 };
530 
531 #endif /* CHECKER_PSA_VULNERABILITY_H */
MultiVulnerability::TailDeps
std::map< std::shared_ptr< Vulnerability >, std::set< std::shared_ptr< Vulnerability > > > TailDeps
Definition: Vulnerability.h:407
Vulnerability::initializeAnalysis
virtual void initializeAnalysis(Pass *P)
Definition: Vulnerability.h:203
SEGOperandNode
Definition: SymbolicExprGraph.h:539
MultiVulnerability::insertHeadDependence
void insertHeadDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:462
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:181
SinkMustReachVulnerability
Definition: Vulnerability.h:239
SymbolicExprGraph
Definition: SymbolicExprGraph.h:855
MultiVulnerability::add
bool add(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:423
SrcMustNotReachSinkVulnerability
Definition: Vulnerability.h:342
Vulnerability::SiteType
SiteType
Definition: Vulnerability.h:58
SailFishVulnerability
Definition: Vulnerability.h:259
Vulnerability::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &AU)
Definition: Vulnerability.h:191
SEGArgumentNode
Definition: SEGArgumentNode.h:19
MultiVulnerability::getTraceHead
const SEGObject * getTraceHead(std::shared_ptr< Vulnerability > V1, std::shared_ptr< VulnerabilityTrace > T1, std::shared_ptr< Vulnerability > V2)
Definition: Vulnerability.h:508
SymbolicExprGraphSolver
Definition: SymbolicExprGraphSolver.h:48
SEGObject
Definition: SymbolicExprGraph.h:87
MultiVulnerability::HeadDeps
std::map< std::shared_ptr< Vulnerability >, std::set< std::shared_ptr< Vulnerability > > > HeadDeps
Definition: Vulnerability.h:401
MultiVulnerability
Definition: Vulnerability.h:390
SrcMustReachSinkVulnerability
Definition: Vulnerability.h:330
MultiVulnerability::head_dep_begin
std::set< std::shared_ptr< Vulnerability > >::iterator head_dep_begin(std::shared_ptr< Vulnerability > V)
Definition: Vulnerability.h:481
Vulnerability
Definition: Vulnerability.h:44
SailFishVulnerability::setSources
virtual void setSources(const SymbolicExprGraph *SEG, std::vector< ValueSitePairType > &Sources)
Definition: Vulnerability.h:267
MultiVulnerability::Vulns
std::vector< std::shared_ptr< Vulnerability > > Vulns
What the multi-vulnerability consists of.
Definition: Vulnerability.h:393
SailFishVulnerability::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:320
TaintStyleVulnerability
Definition: Vulnerability.h:376
Vulnerability::getDescription
const char * getDescription()
Return the description of the vulnerability.
Definition: Vulnerability.h:217
SailFishVulnerability::checkSite
virtual Vulnerability::SiteType checkSite(const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory) override
Definition: Vulnerability.h:289
MultiVulnerability::insertTailDependence
void insertTailDependence(std::shared_ptr< Vulnerability > V1, std::shared_ptr< Vulnerability > V2, GetTraceFunctionTy &Func)
Definition: Vulnerability.h:471
SailFishVulnerability::setPrerequisites
virtual void setPrerequisites(SymbolicExprGraphSolver *Solver, const SEGSiteBase *CurrSite, const VulnerabilityTraceBuilder &TraceHistory, SMTExprVec &Prerequisites) override
Definition: Vulnerability.h:307
SinkMustNotReachVulnerability
Definition: Vulnerability.h:250
TaintExtras
Definition: Vulnerability.h:357
SEGSiteBase
Definition: SymbolicExprGraph.h:776
Vulnerability::isParasitical
bool isParasitical() const
Definition: Vulnerability.h:212
SEGNodeBase
The node base of symbolic expression graph.
Definition: SymbolicExprGraph.h:288
Vulnerability::getName
const char * getName()
Return the name of the vulnerability.
Definition: Vulnerability.h:226
TaintExtras::transfer
virtual void transfer(const SEGSiteBase *Site, const SEGNodeBase *Arg, std::vector< const SEGNodeBase * > &TransferDsts)
Definition: Vulnerability.h:370