Static Value-Flow Analysis
SrcSnkDDA.h
Go to the documentation of this file.
1 //===- SrcSnkDDA.h -- Source-sink analyzer-----------------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * SrcSnkDDA.h
25  *
26  * Created on: Apr 1, 2014
27  * Author: Yulei Sui
28  *
29  * The implementation is based on
30  * (1) Yulei Sui, Ding Ye, and Jingling Xue. "Static Memory Leak Detection Using Full-Sparse Value-Flow Analysis".
31  * 2012 International Symposium on Software Testing and Analysis (ISSTA'12)
32  *
33  * (2) Yulei Sui, Ding Ye, and Jingling Xue. "Detecting Memory Leaks Statically with Full-Sparse Value-Flow Analysis".
34  * IEEE Transactions on Software Engineering (TSE'14)
35  */
36 
37 #ifndef SRCSNKANALYSIS_H_
38 #define SRCSNKANALYSIS_H_
39 
40 #include "Graphs/SVFGOPT.h"
41 #include "SABER/ProgSlice.h"
42 #include "SABER/SaberSVFGBuilder.h"
43 #include "Util/GraphReachSolver.h"
44 #include "Util/SVFBugReport.h"
45 
46 namespace SVF
47 {
48 
50 
54 class SrcSnkDDA : public CFLSrcSnkSolver
55 {
56 
57 public:
60  typedef SVFGNodeSet::const_iterator SVFGNodeSetIter;
61  typedef CxtDPItem DPIm;
62  typedef Set<DPIm> DPImSet;
65  typedef NodeBS SVFGNodeBS;
67 
68 private:
72  std::unique_ptr<SaberCondAllocator> saberCondAllocator;
75 
76 protected:
81 
82 public:
83 
85  SrcSnkDDA() : _curSlice(nullptr), svfg(nullptr), callgraph(nullptr)
86  {
87  saberCondAllocator = std::make_unique<SaberCondAllocator>();
88  }
90  ~SrcSnkDDA() override
91  {
92  svfg = nullptr;
93 
94  delete _curSlice;
95  _curSlice = nullptr;
96 
98  //if (callgraph != nullptr)
99  // delete callgraph;
100  //callgraph = nullptr;
101 
102  //if(pathCondAllocator)
103  // delete pathCondAllocator;
104  //pathCondAllocator = nullptr;
105  }
106 
108  virtual void analyze(SVFModule* module);
109 
111  virtual void initialize(SVFModule* module);
112 
114  virtual void finalize()
115  {
116  dumpSlices();
117  }
118 
120  SVFIR* getPAG() const
121  {
122  return SVFIR::getPAG();
123  }
124 
126  inline const SVFG* getSVFG() const
127  {
128  return graph();
129  }
130 
132  inline PTACallGraph* getCallgraph() const
133  {
134  return callgraph;
135  }
136 
138  inline bool isGlobalSVFGNode(const SVFGNode* node) const
139  {
140  return memSSA.isGlobalSVFGNode(node);
141  }
143 
144  virtual void setCurSlice(const SVFGNode* src);
145 
146  inline ProgSlice* getCurSlice() const
147  {
148  return _curSlice;
149  }
150  inline void addSinkToCurSlice(const SVFGNode* node)
151  {
152  _curSlice->addToSinks(node);
153  addToCurForwardSlice(node);
154  }
155  inline bool isInCurForwardSlice(const SVFGNode* node)
156  {
157  return _curSlice->inForwardSlice(node);
158  }
159  inline bool isInCurBackwardSlice(const SVFGNode* node)
160  {
161  return _curSlice->inBackwardSlice(node);
162  }
163  inline void addToCurForwardSlice(const SVFGNode* node)
164  {
166  }
167  inline void addToCurBackwardSlice(const SVFGNode* node)
168  {
170  }
172 
175  virtual void initSrcs() = 0;
176  virtual void initSnks() = 0;
177  virtual bool isSourceLikeFun(const SVFFunction* fun)
178  {
179  return false;
180  }
181 
182  virtual bool isSinkLikeFun(const SVFFunction* fun)
183  {
184  return false;
185  }
186 
187  bool isSource(const SVFGNode* node) const
188  {
189  return getSources().find(node)!=getSources().end();
190  }
191 
192  bool isSink(const SVFGNode* node) const
193  {
194  return getSinks().find(node)!=getSinks().end();
195  }
197 
199  bool isInAWrapper(const SVFGNode* src, CallSiteSet& csIdSet);
200 
202  virtual void reportBug(ProgSlice* slice) = 0;
203 
205 
206  inline const SVFGNodeSet& getSources() const
207  {
208  return sources;
209  }
211  {
212  return sources.begin();
213  }
215  {
216  return sources.end();
217  }
218  inline void addToSources(const SVFGNode* node)
219  {
220  sources.insert(node);
221  }
222  inline const SVFGNodeSet& getSinks() const
223  {
224  return sinks;
225  }
227  {
228  return sinks.begin();
229  }
230  inline SVFGNodeSetIter sinksEnd() const
231  {
232  return sinks.end();
233  }
234  inline void addToSinks(const SVFGNode* node)
235  {
236  sinks.insert(node);
237  }
239 
242  {
243  return saberCondAllocator.get();
244  }
245 
246  inline const SVFBugReport& getBugReport() const
247  {
248  return report;
249  }
250 
251 protected:
253  inline void FWProcessCurNode(const DPIm& item) override
254  {
255  const SVFGNode* node = getNode(item.getCurNodeID());
256  if(isSink(node))
257  {
258  addSinkToCurSlice(node);
260  }
261  else
262  addToCurForwardSlice(node);
263  }
265  inline void BWProcessCurNode(const DPIm& item) override
266  {
267  const SVFGNode* node = getNode(item.getCurNodeID());
268  if(isInCurForwardSlice(node))
269  {
270  addToCurBackwardSlice(node);
271  }
272  }
274  void FWProcessOutgoingEdge(const DPIm& item, SVFGEdge* edge) override;
276  void BWProcessIncomingEdge(const DPIm& item, SVFGEdge* edge) override;
278 
279  inline bool forwardVisited(const SVFGNode* node, const DPIm& item)
280  {
281  SVFGNodeToDPItemsMap::const_iterator it = nodeToDPItemsMap.find(node);
282  if(it!=nodeToDPItemsMap.end())
283  return it->second.find(item)!=it->second.end();
284  else
285  return false;
286  }
287  inline void addForwardVisited(const SVFGNode* node, const DPIm& item)
288  {
289  nodeToDPItemsMap[node].insert(item);
290  }
291  inline bool backwardVisited(const SVFGNode* node)
292  {
293  return visitedSet.find(node)!=visitedSet.end();
294  }
295  inline void addBackwardVisited(const SVFGNode* node)
296  {
297  visitedSet.insert(node);
298  }
299  inline void clearVisitedMap()
300  {
301  nodeToDPItemsMap.clear();
302  visitedSet.clear();
303  }
305 
307  virtual bool isAllPathReachable()
308  {
309  return _curSlice->isAllReachable();
310  }
312  virtual bool isSomePathReachable()
313  {
314  return _curSlice->isPartialReachable();
315  }
317 
318  void dumpSlices();
319  void annotateSlice(ProgSlice* slice);
320  void printZ3Stat();
322 
323 };
324 
325 } // End namespace SVF
326 
327 #endif /* SRCSNKANALYSIS_H_ */
cJSON * item
Definition: cJSON.h:222
GNODE * getNode(NodeID id) const
const GraphType graph() const
Get/Set graph methods.
void addToForwardSlice(const SVFGNode *node)
Forward and backward slice operations.
Definition: ProgSlice.h:87
bool inBackwardSlice(const SVFGNode *node)
Definition: ProgSlice.h:99
bool isAllReachable() const
Definition: ProgSlice.h:159
bool isPartialReachable() const
Definition: ProgSlice.h:155
Set< const SVFGNode * > SVFGNodeSet
Definition: ProgSlice.h:53
bool inForwardSlice(const SVFGNode *node)
Definition: ProgSlice.h:95
void addToBackwardSlice(const SVFGNode *node)
Definition: ProgSlice.h:91
void addToSinks(const SVFGNode *node)
Definition: ProgSlice.h:127
void setPartialReachable()
Definition: ProgSlice.h:143
Definition: SVFG.h:66
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
bool isGlobalSVFGNode(const SVFGNode *node) const
SVFGNodeSetIter sourcesBegin() const
Definition: SrcSnkDDA.h:210
const SVFGNodeSet & getSources() const
Get sources/sinks.
Definition: SrcSnkDDA.h:206
virtual void initSnks()=0
const SVFGNodeSet & getSinks() const
Definition: SrcSnkDDA.h:222
const SVFBugReport & getBugReport() const
Definition: SrcSnkDDA.h:246
std::unique_ptr< SaberCondAllocator > saberCondAllocator
source nodes
Definition: SrcSnkDDA.h:72
virtual bool isSomePathReachable()
Whether it is some path reachable from a source.
Definition: SrcSnkDDA.h:312
ProgSlice::SVFGNodeSet SVFGNodeSet
Definition: SrcSnkDDA.h:58
virtual void initSrcs()=0
SVFGNodeSet visitedSet
record backward visited nodes
Definition: SrcSnkDDA.h:74
bool backwardVisited(const SVFGNode *node)
Definition: SrcSnkDDA.h:291
bool isGlobalSVFGNode(const SVFGNode *node) const
Whether this svfg node may access global variable.
Definition: SrcSnkDDA.h:138
void BWProcessIncomingEdge(const DPIm &item, SVFGEdge *edge) override
Propagate information backward without matching context, as forward analysis already did it.
Definition: SrcSnkDDA.cpp:257
ProgSlice::VFWorkList WorkList
Definition: SrcSnkDDA.h:66
Set< const CallICFGNode * > CallSiteSet
Definition: SrcSnkDDA.h:64
bool isInCurForwardSlice(const SVFGNode *node)
Definition: SrcSnkDDA.h:155
bool isInCurBackwardSlice(const SVFGNode *node)
Definition: SrcSnkDDA.h:159
SVFIR * getPAG() const
Get SVFIR.
Definition: SrcSnkDDA.h:120
Map< const SVFGNode *, DPImSet > SVFGNodeToDPItemsMap
map a SVFGNode to its visited dpitems
Definition: SrcSnkDDA.h:63
void addForwardVisited(const SVFGNode *node, const DPIm &item)
Definition: SrcSnkDDA.h:287
const SVFG * getSVFG() const
Get SVFG.
Definition: SrcSnkDDA.h:126
PTACallGraph * callgraph
Definition: SrcSnkDDA.h:79
void addToCurForwardSlice(const SVFGNode *node)
Definition: SrcSnkDDA.h:163
~SrcSnkDDA() override
Destructor.
Definition: SrcSnkDDA.h:90
SVFGNodeToDPItemsMap nodeToDPItemsMap
record forward visited dpitems
Definition: SrcSnkDDA.h:73
ProgSlice * _curSlice
Definition: SrcSnkDDA.h:69
virtual bool isAllPathReachable()
Whether it is all path reachable from a source.
Definition: SrcSnkDDA.h:307
void addSinkToCurSlice(const SVFGNode *node)
Definition: SrcSnkDDA.h:150
bool isSink(const SVFGNode *node) const
Definition: SrcSnkDDA.h:192
NodeBS SVFGNodeBS
Definition: SrcSnkDDA.h:65
SrcSnkDDA()
Bug Reporter.
Definition: SrcSnkDDA.h:85
SVFGNodeSetIter sinksBegin() const
Definition: SrcSnkDDA.h:226
bool isSource(const SVFGNode *node) const
Definition: SrcSnkDDA.h:187
CxtDPItem DPIm
Definition: SrcSnkDDA.h:61
void annotateSlice(ProgSlice *slice)
Definition: SrcSnkDDA.cpp:284
virtual void initialize(SVFModule *module)
Initialize analysis.
Definition: SrcSnkDDA.cpp:41
void printZ3Stat()
Definition: SrcSnkDDA.cpp:302
bool forwardVisited(const SVFGNode *node, const DPIm &item)
Whether has been visited or not, in order to avoid recursion on SVFG.
Definition: SrcSnkDDA.h:279
SVFGNodeSet sources
current program slice
Definition: SrcSnkDDA.h:70
void addToSinks(const SVFGNode *node)
Definition: SrcSnkDDA.h:234
void addBackwardVisited(const SVFGNode *node)
Definition: SrcSnkDDA.h:295
SVFBugReport report
Definition: SrcSnkDDA.h:80
virtual void reportBug(ProgSlice *slice)=0
report bug on the current analyzed slice
SVFGNodeSetIter sinksEnd() const
Definition: SrcSnkDDA.h:230
SVFGNodeSet sinks
source nodes
Definition: SrcSnkDDA.h:71
virtual void setCurSlice(const SVFGNode *src)
Slice operations.
Definition: SrcSnkDDA.cpp:272
virtual bool isSinkLikeFun(const SVFFunction *fun)
Definition: SrcSnkDDA.h:182
Set< DPIm > DPImSet
dpitem set
Definition: SrcSnkDDA.h:62
SaberSVFGBuilder memSSA
Definition: SrcSnkDDA.h:77
virtual void analyze(SVFModule *module)
Start analysis here.
Definition: SrcSnkDDA.cpp:61
Map< const SVFGNode *, ProgSlice * > SVFGNodeToSliceMap
Definition: SrcSnkDDA.h:59
void dumpSlices()
Dump SVFG with annotated slice information.
Definition: SrcSnkDDA.cpp:295
void FWProcessOutgoingEdge(const DPIm &item, SVFGEdge *edge) override
Propagate information forward by matching context.
Definition: SrcSnkDDA.cpp:192
void addToSources(const SVFGNode *node)
Definition: SrcSnkDDA.h:218
SVFGNodeSetIter sourcesEnd() const
Definition: SrcSnkDDA.h:214
void addToCurBackwardSlice(const SVFGNode *node)
Definition: SrcSnkDDA.h:167
PTACallGraph * getCallgraph() const
Get Callgraph.
Definition: SrcSnkDDA.h:132
void FWProcessCurNode(const DPIm &item) override
Forward traverse.
Definition: SrcSnkDDA.h:253
ProgSlice * getCurSlice() const
Definition: SrcSnkDDA.h:146
SVFGNodeSet::const_iterator SVFGNodeSetIter
Definition: SrcSnkDDA.h:60
void BWProcessCurNode(const DPIm &item) override
Backward traverse.
Definition: SrcSnkDDA.h:265
SVFG * svfg
Definition: SrcSnkDDA.h:78
void clearVisitedMap()
Definition: SrcSnkDDA.h:299
SaberCondAllocator * getSaberCondAllocator() const
Get saber condition allocator.
Definition: SrcSnkDDA.h:241
virtual bool isSourceLikeFun(const SVFFunction *fun)
Definition: SrcSnkDDA.h:177
virtual void finalize()
Finalize analysis.
Definition: SrcSnkDDA.h:114
bool isInAWrapper(const SVFGNode *src, CallSiteSet &csIdSet)
Identify allocation wrappers.
Definition: SrcSnkDDA.cpp:118
for isBitcode
Definition: BasicTypes.h:68
GraphReachSolver< SVFG *, CxtDPItem > CFLSrcSnkSolver
Definition: SrcSnkDDA.h:49
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96