svf-lib 1.0.2084 → 1.0.2086

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/SVF-linux/Release-build/bin/ae +0 -0
  2. package/SVF-linux/Release-build/include/AE/Core/AbstractState.h +10 -8
  3. package/SVF-linux/Release-build/include/AE/Svfexe/AEDetector.h +322 -0
  4. package/SVF-linux/Release-build/include/AE/Svfexe/AbstractInterpretation.h +30 -66
  5. package/SVF-linux/Release-build/lib/libSvfCore.a +0 -0
  6. package/SVF-osx/Release-build/bin/ae +0 -0
  7. package/SVF-osx/Release-build/bin/cfl +0 -0
  8. package/SVF-osx/Release-build/bin/dvf +0 -0
  9. package/SVF-osx/Release-build/bin/llvm2svf +0 -0
  10. package/SVF-osx/Release-build/bin/mta +0 -0
  11. package/SVF-osx/Release-build/bin/saber +0 -0
  12. package/SVF-osx/Release-build/bin/svf-ex +0 -0
  13. package/SVF-osx/Release-build/bin/wpa +0 -0
  14. package/SVF-osx/Release-build/include/Graphs/ICFG.h +9 -0
  15. package/SVF-osx/Release-build/include/MSSA/MemRegion.h +2 -2
  16. package/SVF-osx/Release-build/include/MTA/MHP.h +1 -2
  17. package/SVF-osx/Release-build/include/SVF-LLVM/ICFGBuilder.h +16 -6
  18. package/SVF-osx/Release-build/include/SVF-LLVM/LLVMUtil.h +11 -0
  19. package/SVF-osx/Release-build/include/SVF-LLVM/SVFIRBuilder.h +2 -2
  20. package/SVF-osx/Release-build/include/SVFIR/SVFIR.h +1 -1
  21. package/SVF-osx/Release-build/include/SVFIR/SVFStatements.h +1 -1
  22. package/SVF-osx/Release-build/include/SVFIR/SVFValue.h +21 -16
  23. package/SVF-osx/Release-build/include/Util/SVFUtil.h +19 -17
  24. package/SVF-osx/Release-build/lib/libSvfCore.a +0 -0
  25. package/SVF-osx/Release-build/lib/libSvfLLVM.a +0 -0
  26. package/package.json +1 -1
  27. package/SVF-linux/Release-build/include/AE/Svfexe/BufOverflowChecker.h +0 -216
  28. package/SVF-linux/Release-build/include/AE/Svfexe/ICFGSimplification.h +0 -44
Binary file
@@ -95,6 +95,8 @@ public:
95
95
  // storeValue
96
96
  void storeValue(NodeID varId, AbstractValue val);
97
97
 
98
+ u32_t getAllocaInstByteSize(const AddrStmt *addr);
99
+
98
100
 
99
101
  /// The physical address starts with 0x7f...... + idx
100
102
  static inline u32_t getVirtualMemAddress(u32_t idx)
@@ -281,13 +283,14 @@ public:
281
283
  /// domain meet with other, important! other widen this.
282
284
  void meetWith(const AbstractState&other);
283
285
 
284
-
285
- /// Return int value from an expression if it is a numeral, otherwise return an approximate value
286
- inline s32_t Interval2NumValue(const IntervalValue &e) const
287
- {
288
- //TODO: return concrete value;
289
- return (s32_t) e.lb().getNumeral();
290
- }
286
+ /**
287
+ * if this NodeID in SVFIR is a pointer, get the pointee type
288
+ * e.g arr = (int*) malloc(10*sizeof(int))
289
+ * getPointeeType(arr) -> return int
290
+ * we can set arr[0]='c', arr[1]='c', arr[2]='\0'
291
+ * @param call callnode of memset like api
292
+ */
293
+ const SVFType* getPointeeElement(NodeID id);
291
294
 
292
295
 
293
296
  u32_t hash() const;
@@ -395,7 +398,6 @@ public:
395
398
  _varToAbsVal.clear();
396
399
  }
397
400
 
398
-
399
401
  };
400
402
 
401
403
  }
@@ -0,0 +1,322 @@
1
+ //===- AEDetector.h -- Vulnerability Detectors---------------------------------//
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
+ //
25
+ // Created by Jiawei Wang on 2024/8/20.
26
+ //
27
+ #pragma once
28
+ #include <SVFIR/SVFIR.h>
29
+ #include <AE/Core/AbstractState.h>
30
+ #include "Util/SVFBugReport.h"
31
+
32
+ namespace SVF
33
+ {
34
+ /**
35
+ * @class AEDetector
36
+ * @brief Base class for all detectors.
37
+ */
38
+ class AEDetector
39
+ {
40
+ public:
41
+ /**
42
+ * @enum DetectorKind
43
+ * @brief Enumerates the types of detectors available.
44
+ */
45
+ enum DetectorKind
46
+ {
47
+ BUF_OVERFLOW, ///< Detector for buffer overflow issues.
48
+ UNKNOWN, ///< Default type if the kind is not specified.
49
+ };
50
+
51
+ /**
52
+ * @brief Constructor initializes the detector kind to UNKNOWN.
53
+ */
54
+ AEDetector(): kind(UNKNOWN) {}
55
+
56
+ /**
57
+ * @brief Virtual destructor for safe polymorphic use.
58
+ */
59
+ virtual ~AEDetector() = default;
60
+
61
+ /**
62
+ * @brief Check if the detector is of the UNKNOWN kind.
63
+ * @param detector Pointer to the detector.
64
+ * @return True if the detector is of type UNKNOWN, false otherwise.
65
+ */
66
+ static bool classof(const AEDetector* detector)
67
+ {
68
+ return detector->getKind() == AEDetector::UNKNOWN;
69
+ }
70
+
71
+ /**
72
+ * @brief Pure virtual function for detecting issues within a node.
73
+ * @param as Reference to the abstract state.
74
+ * @param node Pointer to the ICFG node.
75
+ */
76
+ virtual void detect(AbstractState& as, const ICFGNode* node) = 0;
77
+
78
+ /**
79
+ * @brief Pure virtual function to report detected bugs.
80
+ */
81
+ virtual void reportBug() = 0;
82
+
83
+ /**
84
+ * @brief Get the kind of the detector.
85
+ * @return The kind of the detector.
86
+ */
87
+ DetectorKind getKind() const
88
+ {
89
+ return kind;
90
+ }
91
+
92
+ protected:
93
+ DetectorKind kind; ///< The kind of the detector.
94
+ };
95
+
96
+ /**
97
+ * @class AEException
98
+ * @brief Exception class for handling errors in Abstract Execution.
99
+ */
100
+ class AEException : public std::exception
101
+ {
102
+ public:
103
+ /**
104
+ * @brief Constructor initializes the exception with a message.
105
+ * @param message The error message.
106
+ */
107
+ AEException(const std::string& message)
108
+ : msg_(message) {}
109
+
110
+ /**
111
+ * @brief Provides the error message.
112
+ * @return The error message as a C-string.
113
+ */
114
+ virtual const char* what() const throw()
115
+ {
116
+ return msg_.c_str();
117
+ }
118
+
119
+ private:
120
+ std::string msg_; ///< The error message.
121
+ };
122
+
123
+ /**
124
+ * @class BufOverflowDetector
125
+ * @brief Detector for identifying buffer overflow issues.
126
+ */
127
+ class BufOverflowDetector : public AEDetector
128
+ {
129
+ friend class AbstractInterpretation;
130
+ public:
131
+ /**
132
+ * @brief Constructor initializes the detector kind to BUF_OVERFLOW and sets up external API buffer overflow rules.
133
+ */
134
+ BufOverflowDetector()
135
+ {
136
+ kind = BUF_OVERFLOW;
137
+ initExtAPIBufOverflowCheckRules();
138
+ }
139
+
140
+ /**
141
+ * @brief Destructor.
142
+ */
143
+ ~BufOverflowDetector() = default;
144
+
145
+ /**
146
+ * @brief Check if the detector is of the BUF_OVERFLOW kind.
147
+ * @param detector Pointer to the detector.
148
+ * @return True if the detector is of type BUF_OVERFLOW, false otherwise.
149
+ */
150
+ static bool classof(const AEDetector* detector)
151
+ {
152
+ return detector->getKind() == AEDetector::BUF_OVERFLOW;
153
+ }
154
+
155
+ /**
156
+ * @brief Updates the offset of a GEP object from its base.
157
+ * @param gepAddrs Address value for GEP.
158
+ * @param objAddrs Address value for the object.
159
+ * @param offset The interval value of the offset.
160
+ */
161
+ void updateGepObjOffsetFromBase(AddressValue gepAddrs,
162
+ AddressValue objAddrs,
163
+ IntervalValue offset);
164
+
165
+ /**
166
+ * @brief Detect buffer overflow issues within a node.
167
+ * @param as Reference to the abstract state.
168
+ * @param node Pointer to the ICFG node.
169
+ */
170
+ void detect(AbstractState& as, const ICFGNode*);
171
+
172
+ /**
173
+ * @brief Adds an offset to a GEP object.
174
+ * @param obj Pointer to the GEP object.
175
+ * @param offset The interval value of the offset.
176
+ */
177
+ void addToGepObjOffsetFromBase(const GepObjVar* obj, const IntervalValue& offset)
178
+ {
179
+ gepObjOffsetFromBase[obj] = offset;
180
+ }
181
+
182
+ /**
183
+ * @brief Checks if a GEP object has an associated offset.
184
+ * @param obj Pointer to the GEP object.
185
+ * @return True if the GEP object has an offset, false otherwise.
186
+ */
187
+ bool hasGepObjOffsetFromBase(const GepObjVar* obj) const
188
+ {
189
+ return gepObjOffsetFromBase.find(obj) != gepObjOffsetFromBase.end();
190
+ }
191
+
192
+ /**
193
+ * @brief Retrieves the offset of a GEP object from its base.
194
+ * @param obj Pointer to the GEP object.
195
+ * @return The interval value of the offset.
196
+ */
197
+ IntervalValue getGepObjOffsetFromBase(const GepObjVar* obj) const
198
+ {
199
+ if (hasGepObjOffsetFromBase(obj))
200
+ return gepObjOffsetFromBase.at(obj);
201
+ else
202
+ assert(false && "GepObjVar not found in gepObjOffsetFromBase");
203
+ }
204
+
205
+ /**
206
+ * @brief Retrieves the access offset for a given object and GEP statement.
207
+ * @param as Reference to the abstract state.
208
+ * @param objId The ID of the object.
209
+ * @param gep Pointer to the GEP statement.
210
+ * @return The interval value of the access offset.
211
+ */
212
+ IntervalValue getAccessOffset(AbstractState& as, NodeID objId, const GepStmt* gep);
213
+
214
+ /**
215
+ * @brief Adds a bug to the reporter based on an exception.
216
+ * @param e The exception that was thrown.
217
+ * @param node Pointer to the ICFG node where the bug was detected.
218
+ */
219
+ void addBugToReporter(const AEException& e, const ICFGNode* node)
220
+ {
221
+ const SVFInstruction* inst = nullptr;
222
+
223
+ // Determine the instruction associated with the ICFG node
224
+ if (const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(node))
225
+ {
226
+ inst = call->getCallSite(); // If the node is a call node, get the call site instruction
227
+ }
228
+ else
229
+ {
230
+ inst = node->getSVFStmts().back()->getInst(); // Otherwise, get the last instruction of the node's
231
+ // statements
232
+ }
233
+
234
+ GenericBug::EventStack eventStack;
235
+ SVFBugEvent sourceInstEvent(SVFBugEvent::EventType::SourceInst, inst);
236
+ eventStack.push_back(sourceInstEvent); // Add the source instruction event to the event stack
237
+
238
+ if (eventStack.empty())
239
+ {
240
+ return; // If the event stack is empty, return early
241
+ }
242
+
243
+ std::string loc = eventStack.back().getEventLoc(); // Get the location of the last event in the stack
244
+
245
+ // Check if the bug at this location has already been reported
246
+ if (bugLoc.find(loc) != bugLoc.end())
247
+ {
248
+ return; // If the bug location is already reported, return early
249
+ }
250
+ else
251
+ {
252
+ bugLoc.insert(loc); // Otherwise, mark this location as reported
253
+ }
254
+
255
+ // Add the bug to the recorder with details from the event stack
256
+ recoder.addAbsExecBug(GenericBug::FULLBUFOVERFLOW, eventStack, 0, 0, 0, 0);
257
+ nodeToBugInfo[node] = e.what(); // Record the exception information for the node
258
+ }
259
+
260
+ /**
261
+ * @brief Reports all detected buffer overflow bugs.
262
+ */
263
+ void reportBug()
264
+ {
265
+ if (!nodeToBugInfo.empty())
266
+ {
267
+ std::cerr << "######################Buffer Overflow (" + std::to_string(nodeToBugInfo.size())
268
+ + " found)######################\n";
269
+ std::cerr << "---------------------------------------------\n";
270
+ for (const auto& it : nodeToBugInfo)
271
+ {
272
+ std::cerr << it.second << "\n---------------------------------------------\n";
273
+ }
274
+ }
275
+ }
276
+
277
+ /**
278
+ * @brief Initializes external API buffer overflow check rules.
279
+ */
280
+ void initExtAPIBufOverflowCheckRules();
281
+
282
+ /**
283
+ * @brief Handles external API calls related to buffer overflow detection.
284
+ * @param as Reference to the abstract state.
285
+ * @param call Pointer to the call ICFG node.
286
+ */
287
+ void detectExtAPI(AbstractState& as, const CallICFGNode *call);
288
+
289
+ /**
290
+ * @brief Checks if memory can be safely accessed.
291
+ * @param as Reference to the abstract state.
292
+ * @param value Pointer to the SVF value.
293
+ * @param len The interval value representing the length of the memory access.
294
+ * @return True if the memory access is safe, false otherwise.
295
+ */
296
+ bool canSafelyAccessMemory(AbstractState& as, const SVFValue *value, const IntervalValue &len);
297
+
298
+ private:
299
+ /**
300
+ * @brief Detects buffer overflow in 'strcat' function calls.
301
+ * @param as Reference to the abstract state.
302
+ * @param call Pointer to the call ICFG node.
303
+ * @return True if a buffer overflow is detected, false otherwise.
304
+ */
305
+ bool detectStrcat(AbstractState& as, const CallICFGNode *call);
306
+
307
+ /**
308
+ * @brief Detects buffer overflow in 'strcpy' function calls.
309
+ * @param as Reference to the abstract state.
310
+ * @param call Pointer to the call ICFG node.
311
+ * @return True if a buffer overflow is detected, false otherwise.
312
+ */
313
+ bool detectStrcpy(AbstractState& as, const CallICFGNode *call);
314
+
315
+ private:
316
+ Map<const GepObjVar*, IntervalValue> gepObjOffsetFromBase; ///< Maps GEP objects to their offsets from the base.
317
+ Map<std::string, std::vector<std::pair<u32_t, u32_t>>> extAPIBufOverflowCheckRules; ///< Rules for checking buffer overflows in external APIs.
318
+ Set<std::string> bugLoc; ///< Set of locations where bugs have been reported.
319
+ SVFBugReport recoder; ///< Recorder for abstract execution bugs.
320
+ Map<const ICFGNode*, std::string> nodeToBugInfo; ///< Maps ICFG nodes to bug information.
321
+ };
322
+ }
@@ -27,11 +27,12 @@
27
27
  // Xiao Cheng, Jiawei Wang and Yulei Sui. Precise Sparse Abstract Execution via Cross-Domain Interaction.
28
28
  // 46th International Conference on Software Engineering. (ICSE24)
29
29
  //
30
-
30
+ #pragma once
31
+ #include "AE/Core/AbstractState.h"
31
32
  #include "AE/Core/ICFGWTO.h"
33
+ #include "AE/Svfexe/AEDetector.h"
32
34
  #include "Util/SVFBugReport.h"
33
35
  #include "WPA/Andersen.h"
34
- #include "AE/Core/AbstractState.h"
35
36
 
36
37
  namespace SVF
37
38
  {
@@ -41,12 +42,6 @@ class AEAPI;
41
42
 
42
43
  template<typename T> class FILOWorkList;
43
44
 
44
- enum class AEKind
45
- {
46
- AbstractExecution,
47
- BufOverflowChecker,
48
- };
49
-
50
45
  /// AEStat: Statistic for AE
51
46
  class AEStat : public SVFStat
52
47
  {
@@ -67,14 +62,12 @@ public:
67
62
 
68
63
  void finializeStat();
69
64
  void performStat() override;
70
- void reportBug();
71
65
 
72
66
  public:
73
67
  AbstractInterpretation* _ae;
74
68
  s32_t count{0};
75
69
  std::string memory_usage;
76
70
  std::string memUsage;
77
- std::string bugStr;
78
71
 
79
72
 
80
73
  u32_t& getFunctionTrace()
@@ -108,6 +101,7 @@ class AbstractInterpretation
108
101
  {
109
102
  friend class AEStat;
110
103
  friend class AEAPI;
104
+ friend class BufOverflowDetector;
111
105
 
112
106
  public:
113
107
  enum ExtAPIType { UNCLASSIFIED, MEMCPY, MEMSET, STRCPY, STRCAT };
@@ -123,14 +117,15 @@ public:
123
117
  /// Program entry
124
118
  void analyse();
125
119
 
126
- static bool classof(const AbstractInterpretation* ae)
120
+ static AbstractInterpretation& getAEInstance()
127
121
  {
128
- return ae->getKind() == AEKind::AbstractExecution;
122
+ static AbstractInterpretation instance;
123
+ return instance;
129
124
  }
130
125
 
131
- AEKind getKind() const
126
+ void addDetector(std::unique_ptr<AEDetector> detector)
132
127
  {
133
- return _kind;
128
+ detectors.push_back(std::move(detector));
134
129
  }
135
130
 
136
131
  protected:
@@ -233,13 +228,6 @@ protected:
233
228
  */
234
229
  virtual void initExtFunMap();
235
230
 
236
- /**
237
- * get byte size of alloca inst
238
- *
239
- * @param addr Address Stmt like malloc/calloc/ALLOCA/StackAlloc
240
- * @return the byte size e.g. int32_t a[10] -> return 40
241
- */
242
- u32_t getAllocaInstByteSize(AbstractState& as, const AddrStmt *addr);
243
231
 
244
232
  /**
245
233
  * get byte size of alloca inst
@@ -259,16 +247,6 @@ protected:
259
247
  */
260
248
  IntervalValue getStrlen(AbstractState& as, const SVF::SVFValue *strValue);
261
249
 
262
- /**
263
- * get memory allocation size
264
- * e.g arr = new int[10]
265
- * ....
266
- * memset(arr, 1, 10* sizeof(int))
267
- * when we trace the 'arr', we can get the alloc size [40, 40]
268
- * @param value to be traced
269
- * @return IntervalValue of allocation size
270
- */
271
- IntervalValue traceMemoryAllocationSize(AbstractState& as, const SVFValue *value);
272
250
  /**
273
251
  * execute strcpy in abstract execution
274
252
  * e.g arr = new char[10]
@@ -305,23 +283,9 @@ protected:
305
283
  */
306
284
  virtual void handleMemset(AbstractState& as, const SVFValue* dst, IntervalValue elem, IntervalValue len);
307
285
 
308
- /**
309
- * if this NodeID in SVFIR is a pointer, get the pointee type
310
- * e.g arr = (int*) malloc(10*sizeof(int))
311
- * getPointeeType(arr) -> return int
312
- * we can set arr[0]='c', arr[1]='c', arr[2]='\0'
313
- * @param call callnode of memset like api
314
- */
315
- const SVFType* getPointeeElement(AbstractState& as, NodeID id);
316
286
 
317
287
  void collectCheckPoint();
318
288
  void checkPointAllSet();
319
- // helper functions for traceMemoryAllocationSize and canSafelyAccessMemory
320
- void AccessMemoryViaRetNode(const CallICFGNode *callnode, SVF::FILOWorkList<const SVFValue *>& worklist, Set<const SVFValue *>& visited);
321
- void AccessMemoryViaCopyStmt(const CopyStmt *copy, SVF::FILOWorkList<const SVFValue *>& worklist, Set<const SVFValue *>& visited);
322
- void AccessMemoryViaLoadStmt(AbstractState& as, const LoadStmt *load, SVF::FILOWorkList<const SVFValue *>& worklist, Set<const SVFValue *>& visited);
323
- void AccessMemoryViaCallArgs(const SVF::SVFArgument *arg, SVF::FILOWorkList<const SVFValue *>& worklist, Set<const SVFValue *>& visited);
324
-
325
289
 
326
290
  void updateStateOnAddr(const AddrStmt *addr);
327
291
 
@@ -349,20 +313,16 @@ protected:
349
313
 
350
314
 
351
315
  /// protected data members, also used in subclasses
352
- SVFIR* _svfir;
316
+ SVFIR* svfir;
353
317
  /// Execution State, used to store the Interval Value of every SVF variable
354
- AEAPI* _api{nullptr};
318
+ AEAPI* api{nullptr};
355
319
 
356
- ICFG* _icfg;
357
- AEStat* _stat;
358
- AEKind _kind;
320
+ ICFG* icfg;
321
+ AEStat* stat;
359
322
 
360
- Set<std::string> _bugLoc;
361
- SVFBugReport _recoder;
362
- std::vector<const CallICFGNode*> _callSiteStack;
363
- Map<const ICFGNode*, std::string> _nodeToBugInfo;
364
- Map<const SVFFunction*, ICFGWTO*> _funcToWTO;
365
- Set<const SVFFunction*> _recursiveFuns;
323
+ std::vector<const CallICFGNode*> callSiteStack;
324
+ Map<const SVFFunction*, ICFGWTO*> funcToWTO;
325
+ Set<const SVFFunction*> recursiveFuns;
366
326
 
367
327
  private:
368
328
  // helper functions in handleCallSite
@@ -379,29 +339,33 @@ protected:
379
339
 
380
340
  AbstractState& getAbsStateFromTrace(const ICFGNode* node)
381
341
  {
382
- const ICFGNode* repNode = _icfg->getRepNode(node);
383
- if (_abstractTrace.count(repNode) == 0)
342
+ const ICFGNode* repNode = icfg->getRepNode(node);
343
+ if (abstractTrace.count(repNode) == 0)
384
344
  {
385
345
  assert(0 && "No preAbsTrace for this node");
386
346
  }
387
347
  else
388
348
  {
389
- return _abstractTrace[repNode];
349
+ return abstractTrace[repNode];
390
350
  }
391
351
  }
392
352
 
393
353
  bool hasAbsStateFromTrace(const ICFGNode* node)
394
354
  {
395
- const ICFGNode* repNode = _icfg->getRepNode(node);
396
- return _abstractTrace.count(repNode) != 0;
355
+ const ICFGNode* repNode = icfg->getRepNode(node);
356
+ return abstractTrace.count(repNode) != 0;
397
357
  }
398
358
 
399
359
  protected:
400
360
  // there data should be shared with subclasses
401
- Map<std::string, std::function<void(const CallSite &)>> _func_map;
402
- Set<const CallICFGNode*> _checkpoints;
403
- Set<std::string> _checkpoint_names;
404
- Map<const ICFGNode*, AbstractState> _abstractTrace; // abstract states immediately after nodes
405
- std::string _moduleName;
361
+ Map<std::string, std::function<void(const CallSite &)>> func_map;
362
+ Set<const CallICFGNode*> checkpoints;
363
+ Set<std::string> checkpoint_names;
364
+ Map<const ICFGNode*, AbstractState>
365
+ abstractTrace; // abstract states immediately after nodes
366
+ std::string moduleName;
367
+
368
+ std::vector<std::unique_ptr<AEDetector>> detectors;
369
+
406
370
  };
407
371
  }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -198,12 +198,21 @@ public:
198
198
  //@{
199
199
  ICFGNode* getICFGNode(const SVFInstruction* inst);
200
200
 
201
+ /// Whether has the ICFGNode
202
+ bool hasICFGNode(const SVFInstruction* inst);
203
+
201
204
  CallICFGNode* getCallICFGNode(const SVFInstruction* inst);
202
205
 
206
+ CallICFGNode* addCallICFGNode(const SVFInstruction* inst);
207
+
203
208
  RetICFGNode* getRetICFGNode(const SVFInstruction* inst);
204
209
 
210
+ RetICFGNode* addRetICFGNode(const SVFInstruction* inst);
211
+
205
212
  IntraICFGNode* getIntraICFGNode(const SVFInstruction* inst);
206
213
 
214
+ IntraICFGNode* addIntraICFGNode(const SVFInstruction* inst);
215
+
207
216
  FunEntryICFGNode* getFunEntryICFGNode(const SVFFunction* fun);
208
217
 
209
218
  FunExitICFGNode* getFunExitICFGNode(const SVFFunction* fun);
@@ -470,9 +470,9 @@ public:
470
470
  }
471
471
  //@}
472
472
  /// Whether this instruction has SVFIR Edge
473
- bool hasSVFStmtList(const SVFInstruction* inst);
473
+ bool hasSVFStmtList(const ICFGNode* icfgNode);
474
474
  /// Given an instruction, get all its the PAGEdge (statement) in sequence
475
- SVFStmtList& getPAGEdgesFromInst(const SVFInstruction* inst);
475
+ SVFStmtList& getPAGEdgesFromInst(const ICFGNode* node);
476
476
 
477
477
  /// getModRefInfo APIs
478
478
  //@{
@@ -341,8 +341,7 @@ public:
341
341
  NodeID parentTid = tct->getParentThread(tid);
342
342
  const CxtThread& parentct = tct->getTCTNode(parentTid)->getCxtThread();
343
343
  const SVFFunction* parentRoutine = tct->getStartRoutineOfCxtThread(parentct);
344
- const SVFInstruction* inst = parentRoutine->getExitBB()->back();
345
- return tct->getICFGNode(inst);
344
+ return parentRoutine->getExitBB()->back();
346
345
  }
347
346
 
348
347
  /// Get loop for join site
@@ -62,23 +62,30 @@ private:
62
62
  ///@{
63
63
  void processFunEntry(const Function* fun, WorkList& worklist);
64
64
 
65
+ void processNoPrecessorBasicBlocks(const Function* fun, WorkList& worklist);
66
+
65
67
  void processFunBody(WorkList& worklist);
66
68
 
67
69
  void processFunExit(const Function* fun);
68
70
  //@}
69
71
 
72
+ void checkICFGNodesVisited(const Function* fun);
73
+
70
74
  void connectGlobalToProgEntry(SVFModule* svfModule);
71
75
 
72
76
  /// Add/Get an inter block ICFGNode
73
- InterICFGNode* getOrAddInterBlockICFGNode(const SVFInstruction* inst);
77
+ InterICFGNode* addInterBlockICFGNode(const SVFInstruction* inst);
74
78
 
75
79
  /// Add/Get a basic block ICFGNode
76
- inline ICFGNode* getOrAddBlockICFGNode(const SVFInstruction* inst)
80
+ inline ICFGNode* addBlockICFGNode(const SVFInstruction* inst)
77
81
  {
82
+ ICFGNode* node;
78
83
  if(SVFUtil::isNonInstricCallSite(inst))
79
- return getOrAddInterBlockICFGNode(inst);
84
+ node = addInterBlockICFGNode(inst);
80
85
  else
81
- return getOrAddIntraBlockICFGNode(inst);
86
+ node = addIntraBlockICFGNode(inst);
87
+ const_cast<SVFBasicBlock*>(inst->getParent())->addICFGNode(node);
88
+ return node;
82
89
  }
83
90
 
84
91
  /// Create edges between ICFG nodes across functions
@@ -96,10 +103,13 @@ private:
96
103
  }
97
104
 
98
105
  /// Add and get IntraBlock ICFGNode
99
- IntraICFGNode* getOrAddIntraBlockICFGNode(const SVFInstruction* inst)
106
+ IntraICFGNode* addIntraBlockICFGNode(const SVFInstruction* inst)
100
107
  {
101
- return icfg->getIntraICFGNode(inst);
108
+ return icfg->addIntraICFGNode(inst);
102
109
  }
110
+
111
+ private:
112
+ BBSet visited;
103
113
  };
104
114
 
105
115
  } // End namespace SVF
@@ -303,6 +303,17 @@ void getNextInsts(const Instruction* curInst,
303
303
  void getPrevInsts(const Instruction* curInst,
304
304
  std::vector<const Instruction*>& instList);
305
305
 
306
+ /// Basic block does not have predecessors
307
+ /// map-1.cpp.bc
308
+ /// try.cont: ; No predecessors!
309
+ /// call void @llvm.trap()
310
+ /// unreachable
311
+ inline bool isNoPrecessorBasicBlock(const BasicBlock* bb)
312
+ {
313
+ return bb != &bb->getParent()->getEntryBlock() &&
314
+ pred_empty(bb);
315
+ }
316
+
306
317
  /// Get num of BB's predecessors
307
318
  u32_t getBBPredecessorNum(const BasicBlock* BB);
308
319
 
@@ -450,9 +450,9 @@ protected:
450
450
  /// Add Store edge
451
451
  inline void addStoreEdge(NodeID src, NodeID dst)
452
452
  {
453
- IntraICFGNode* node;
453
+ ICFGNode* node;
454
454
  if (const SVFInstruction* inst = SVFUtil::dyn_cast<SVFInstruction>(curVal))
455
- node = pag->getICFG()->getIntraICFGNode(inst);
455
+ node = pag->getICFG()->getICFGNode(inst);
456
456
  else
457
457
  node = nullptr;
458
458
  if (StoreStmt* edge = pag->addStoreStmt(src, dst, node))
@@ -658,7 +658,7 @@ private:
658
658
  /// Add Load edge
659
659
  LoadStmt* addLoadStmt(NodeID src, NodeID dst);
660
660
  /// Add Store edge
661
- StoreStmt* addStoreStmt(NodeID src, NodeID dst, const IntraICFGNode* val);
661
+ StoreStmt* addStoreStmt(NodeID src, NodeID dst, const ICFGNode* val);
662
662
  /// Add Call edge
663
663
  CallPE* addCallPE(NodeID src, NodeID dst, const CallICFGNode* cs,
664
664
  const FunEntryICFGNode* entry);
@@ -478,7 +478,7 @@ public:
478
478
  //@}
479
479
 
480
480
  /// constructor
481
- StoreStmt(SVFVar* s, SVFVar* d, const IntraICFGNode* st);
481
+ StoreStmt(SVFVar* s, SVFVar* d, const ICFGNode* st);
482
482
 
483
483
  virtual const std::string toString() const override;
484
484
  };
@@ -524,6 +524,8 @@ public:
524
524
  }
525
525
  };
526
526
 
527
+ class ICFGNode;
528
+
527
529
  class SVFBasicBlock : public SVFValue
528
530
  {
529
531
  friend class LLVMModuleSet;
@@ -531,21 +533,26 @@ class SVFBasicBlock : public SVFValue
531
533
  friend class SVFIRReader;
532
534
  friend class SVFIRBuilder;
533
535
  friend class SVFFunction;
536
+ friend class ICFGBuilder;
537
+ friend class ICFG;
534
538
 
535
539
  public:
536
- typedef std::vector<const SVFInstruction*>::const_iterator const_iterator;
540
+ typedef std::vector<const ICFGNode*>::const_iterator const_iterator;
537
541
 
538
542
  private:
539
- std::vector<const SVFInstruction*> allInsts; ///< all Instructions in this BasicBlock
543
+ std::vector<const ICFGNode*> allICFGNodes; ///< all ICFGNodes in this BasicBlock
540
544
  std::vector<const SVFBasicBlock*> succBBs; ///< all successor BasicBlocks of this BasicBlock
541
545
  std::vector<const SVFBasicBlock*> predBBs; ///< all predecessor BasicBlocks of this BasicBlock
542
546
  const SVFFunction* fun; /// Function where this BasicBlock is
543
547
 
544
548
  protected:
545
549
  ///@{ attributes to be set only through Module builders e.g., LLVMModule
546
- inline void addInstruction(const SVFInstruction* inst)
550
+
551
+ inline void addICFGNode(const ICFGNode* icfgNode)
547
552
  {
548
- allInsts.push_back(inst);
553
+ assert(std::find(getICFGNodeList().begin(), getICFGNodeList().end(),
554
+ icfgNode) == getICFGNodeList().end() && "duplicated icfgnode");
555
+ allICFGNodes.push_back(icfgNode);
549
556
  }
550
557
 
551
558
  inline void addSuccBasicBlock(const SVFBasicBlock* succ)
@@ -570,19 +577,19 @@ public:
570
577
  return node->getKind() == SVFBB;
571
578
  }
572
579
 
573
- inline const std::vector<const SVFInstruction*>& getInstructionList() const
580
+ inline const std::vector<const ICFGNode*>& getICFGNodeList() const
574
581
  {
575
- return allInsts;
582
+ return allICFGNodes;
576
583
  }
577
584
 
578
585
  inline const_iterator begin() const
579
586
  {
580
- return allInsts.begin();
587
+ return allICFGNodes.begin();
581
588
  }
582
589
 
583
590
  inline const_iterator end() const
584
591
  {
585
- return allInsts.end();
592
+ return allICFGNodes.end();
586
593
  }
587
594
 
588
595
  inline const SVFFunction* getParent() const
@@ -595,20 +602,18 @@ public:
595
602
  return fun;
596
603
  }
597
604
 
598
- inline const SVFInstruction* front() const
605
+ inline const ICFGNode* front() const
599
606
  {
600
- return allInsts.front();
607
+ assert(!allICFGNodes.empty() && "bb empty?");
608
+ return allICFGNodes.front();
601
609
  }
602
610
 
603
- inline const SVFInstruction* back() const
611
+ inline const ICFGNode* back() const
604
612
  {
605
- return allInsts.back();
613
+ assert(!allICFGNodes.empty() && "bb empty?");
614
+ return allICFGNodes.back();
606
615
  }
607
616
 
608
- /// Returns the terminator instruction if the block is well formed or null
609
- /// if the block is not well formed.
610
- const SVFInstruction* getTerminator() const;
611
-
612
617
  inline const std::vector<const SVFBasicBlock*>& getSuccessors() const
613
618
  {
614
619
  return succBBs;
@@ -168,6 +168,8 @@ void dumpPointsToList(const PointsToList& ptl);
168
168
 
169
169
  /// Return true if it is an llvm intrinsic instruction
170
170
  bool isIntrinsicInst(const SVFInstruction* inst);
171
+ bool isIntrinsicInst(const ICFGNode* inst);
172
+
171
173
  //@}
172
174
 
173
175
  /// Whether an instruction is a call or invoke instruction
@@ -184,6 +186,10 @@ inline bool isCallSite(const SVFValue* val)
184
186
  return false;
185
187
  }
186
188
 
189
+ bool isCallSite(const ICFGNode* inst);
190
+
191
+ bool isRetInstNode(const ICFGNode* node);
192
+
187
193
  /// Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls
188
194
  inline bool isNonInstricCallSite(const SVFInstruction* inst)
189
195
  {
@@ -192,6 +198,14 @@ inline bool isNonInstricCallSite(const SVFInstruction* inst)
192
198
  return isCallSite(inst);
193
199
  }
194
200
 
201
+ /// Whether an instruction is a callsite in the application code, excluding llvm intrinsic calls
202
+ inline bool isNonInstricCallSite(const ICFGNode* inst)
203
+ {
204
+ if(isIntrinsicInst(inst))
205
+ return false;
206
+ return isCallSite(inst);
207
+ }
208
+
195
209
  /// Return LLVM callsite given an instruction
196
210
  inline CallSite getSVFCallSite(const SVFInstruction* inst)
197
211
  {
@@ -250,6 +264,8 @@ inline const SVFFunction* getCallee(const SVFInstruction *inst)
250
264
  CallSite cs(inst);
251
265
  return getCallee(cs);
252
266
  }
267
+
268
+ const SVFFunction* getCallee(const ICFGNode *inst);
253
269
  //@}
254
270
 
255
271
  /// Given a map mapping points-to sets to a count, adds from into to.
@@ -402,27 +418,20 @@ inline bool isArgOfUncalledFunction(const SVFValue* svfval)
402
418
 
403
419
  /// Return thread fork function
404
420
  //@{
405
- inline const SVFValue* getForkedFun(const CallSite cs)
406
- {
407
- return ThreadAPI::getThreadAPI()->getForkedFun(cs.getInstruction());
408
- }
409
421
  inline const SVFValue* getForkedFun(const SVFInstruction *inst)
410
422
  {
411
423
  return ThreadAPI::getThreadAPI()->getForkedFun(inst);
412
424
  }
413
425
  //@}
414
426
 
415
- /// This function servers a allocation wrapper detector
416
- inline bool isAnAllocationWraper(const SVFInstruction*)
417
- {
418
- return false;
419
- }
420
427
 
421
428
  inline bool isExtCall(const CallSite cs)
422
429
  {
423
430
  return isExtCall(getCallee(cs));
424
431
  }
425
432
 
433
+ bool isExtCall(const ICFGNode* node);
434
+
426
435
  inline bool isExtCall(const SVFInstruction *inst)
427
436
  {
428
437
  return isExtCall(getCallee(inst));
@@ -451,10 +460,7 @@ inline bool isHeapAllocExtCallViaRet(const SVFInstruction *inst)
451
460
  return isPtrTy && isHeapAllocExtFunViaRet(getCallee(inst));
452
461
  }
453
462
 
454
- inline bool isHeapAllocExtCall(const CallSite cs)
455
- {
456
- return isHeapAllocExtCallViaRet(cs) || isHeapAllocExtCallViaArg(cs);
457
- }
463
+ bool isHeapAllocExtCall(const ICFGNode* cs);
458
464
 
459
465
  inline bool isHeapAllocExtCall(const SVFInstruction *inst)
460
466
  {
@@ -477,10 +483,6 @@ inline bool isReallocExtCall(const CallSite cs)
477
483
 
478
484
  /// Return true if this is a thread creation call
479
485
  ///@{
480
- inline bool isThreadForkCall(const CallSite cs)
481
- {
482
- return ThreadAPI::getThreadAPI()->isTDFork(cs.getInstruction());
483
- }
484
486
  inline bool isThreadForkCall(const SVFInstruction *inst)
485
487
  {
486
488
  return ThreadAPI::getThreadAPI()->isTDFork(inst);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-lib",
3
- "version": "1.0.2084",
3
+ "version": "1.0.2086",
4
4
  "description": "SVF's npm support",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,216 +0,0 @@
1
- //===- BufOverflowChecker.cpp -- BufOVerflowChecker Client for Abstract Execution---//
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
- //
25
- // Created by Jiawei Wang on 2024/1/12.
26
- // The implementation is based on
27
- // Xiao Cheng, Jiawei Wang and Yulei Sui. Precise Sparse Abstract Execution via Cross-Domain Interaction.
28
- // 46th International Conference on Software Engineering. (ICSE24)
29
- //
30
-
31
- #include "AE/Svfexe/AbstractInterpretation.h"
32
-
33
- namespace SVF
34
- {
35
-
36
- struct BufOverflowException: public std::exception
37
- {
38
- public:
39
- BufOverflowException(std::string msg, u32_t allocLb,
40
- u32_t allocUb, u32_t accessLb, u32_t accessUb, const SVFValue* allocVal) :
41
- _msg(msg), _allocLb(allocLb), _allocUb(allocUb),
42
- _accessLb(accessLb), _accessUb(accessUb), _allocVar(allocVal)
43
- {
44
- }
45
-
46
- u32_t getAllocLb() const
47
- {
48
- return _allocLb;
49
- }
50
-
51
- void setAllocLb(u32_t allocLb)
52
- {
53
- _allocLb = allocLb;
54
- }
55
-
56
- u32_t getAllocUb() const
57
- {
58
- return _allocUb;
59
- }
60
-
61
- void setAllocUb(u32_t allocUb)
62
- {
63
- _allocUb = allocUb;
64
- }
65
-
66
- u32_t getAccessLb() const
67
- {
68
- return _accessLb;
69
- }
70
-
71
- void setAccessLb(u32_t accessLb)
72
- {
73
- _accessLb = accessLb;
74
- }
75
-
76
- u32_t getAccessUb() const
77
- {
78
- return _accessUb;
79
- }
80
-
81
- void setAccessUb(u32_t accessUb)
82
- {
83
- _accessUb = accessUb;
84
- }
85
-
86
- const SVFValue* getAllocVar() const
87
- {
88
- return _allocVar;
89
- }
90
-
91
- const char* what() const noexcept override
92
- {
93
- return _msg.c_str();
94
- }
95
-
96
-
97
- protected:
98
- std::string _msg;
99
- u32_t _allocLb, _allocUb, _accessLb, _accessUb;
100
- const SVFValue* _allocVar;
101
- };
102
-
103
- class BufOverflowChecker: public AbstractInterpretation
104
- {
105
- public:
106
- BufOverflowChecker() : AbstractInterpretation()
107
- {
108
- initExtFunMap();
109
- _kind = AEKind::BufOverflowChecker;
110
- initExtAPIBufOverflowCheckRules();
111
- }
112
-
113
- static bool classof(const AbstractInterpretation* ae)
114
- {
115
- return ae->getKind() == AEKind::BufOverflowChecker;
116
- }
117
-
118
- protected:
119
- /**
120
- * the map of external function to its API type
121
- *
122
- * it initialize the ext apis about buffer overflow checking
123
- */
124
- virtual void initExtFunMap() override;
125
-
126
- /**
127
- * the map of ext apis of buffer overflow checking rules
128
- *
129
- * it initialize the rules of extapis about buffer overflow checking
130
- * e.g. memcpy(dst, src, sz) -> we check allocSize(dst)>=sz and allocSize(src)>=sz
131
- */
132
- void initExtAPIBufOverflowCheckRules();
133
-
134
- /**
135
- * handle external function call regarding buffer overflow checking
136
- * e.g. memcpy(dst, src, sz) -> we check allocSize(dst)>=sz and allocSize(src)>=sz
137
- *
138
- * @param call call node whose callee is external function
139
- */
140
- void handleExtAPI(const CallICFGNode *call) override;
141
- /**
142
- * detect buffer overflow from strcpy like apis
143
- * e.g. strcpy(dst, src), if dst is shorter than src, we will throw buffer overflow
144
- *
145
- * @param call call node whose callee is strcpy-like external function
146
- * @return true if the buffer overflow is detected
147
- */
148
- bool detectStrcpy(const CallICFGNode *call);
149
- /**
150
- * detect buffer overflow from strcat like apis
151
- * e.g. strcat(dst, src), if dst is shorter than src, we will throw buffer overflow
152
- *
153
- * @param call call node whose callee is strcpy-like external function
154
- * @return true if the buffer overflow is detected
155
- */
156
- bool detectStrcat(const CallICFGNode *call);
157
-
158
- /**
159
- * detect buffer overflow by giving a var and a length
160
- * e.g. int x[10]; x[10] = 1;
161
- * we call canSafelyAccessMemory(x, 11 * sizeof(int));
162
- *
163
- * @param value the value of the buffer overflow checkpoint
164
- * @param len the length of the buffer overflow checkpoint
165
- * @return true if the buffer overflow is detected
166
- */
167
- bool canSafelyAccessMemory(const SVFValue *value, const IntervalValue &len, const ICFGNode *curNode);
168
-
169
- private:
170
- /**
171
- * handle SVF statement regarding buffer overflow checking
172
- *
173
- * @param stmt SVF statement
174
- */
175
- virtual void handleSVFStatement(const SVFStmt *stmt) override;
176
-
177
- // TODO: will delete later
178
- virtual void handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto) override
179
- {
180
- AbstractInterpretation::handleSingletonWTO(icfgSingletonWto);
181
- const ICFGNode* repNode = _icfg->getRepNode(icfgSingletonWto->getICFGNode());
182
- if (_abstractTrace.count(repNode) == 0)
183
- {
184
- return;
185
- }
186
- const std::vector<const ICFGNode*>& worklist_vec = _icfg->getSubNodes(icfgSingletonWto->getICFGNode());
187
-
188
- for (auto it = worklist_vec.begin(); it != worklist_vec.end(); ++it)
189
- {
190
- const ICFGNode* curNode = *it;
191
- detectBufOverflow(curNode);
192
- }
193
- }
194
-
195
- /**
196
- * check buffer overflow at ICFGNode which is a checkpoint
197
- *
198
- * @param node ICFGNode
199
- * @return true if the buffer overflow is detected
200
- */
201
- bool detectBufOverflow(const ICFGNode *node);
202
-
203
- /**
204
- * add buffer overflow bug to recoder
205
- *
206
- * @param e the exception that is thrown by BufOverflowChecker
207
- * @param node ICFGNode that causes the exception
208
- */
209
- void addBugToRecoder(const BufOverflowException& e, const ICFGNode* node);
210
-
211
- private:
212
- Map<NodeID, const GepStmt*> _addrToGep;
213
- Map<std::string, std::vector<std::pair<u32_t, u32_t>>> _extAPIBufOverflowCheckRules;
214
-
215
- };
216
- }
@@ -1,44 +0,0 @@
1
- //===- ICFGSimplification.h -- Simplify ICFG----------------------------------//
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
- //
25
- // Created by Jiawei Wang on 2024/2/25.
26
- //
27
- // The implementation is based on
28
- // Xiao Cheng, Jiawei Wang and Yulei Sui. Precise Sparse Abstract Execution via Cross-Domain Interaction.
29
- // 46th International Conference on Software Engineering. (ICSE24)
30
- #include "Graphs/ICFG.h"
31
-
32
- namespace SVF
33
- {
34
-
35
- class ICFGSimplification
36
- {
37
- public:
38
- ICFGSimplification() = default;
39
-
40
- virtual ~ICFGSimplification() = default;
41
-
42
- static void mergeAdjacentNodes(ICFG* icfg);
43
- };
44
- }