svf-tools 1.0.987 → 1.0.989

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.987",
3
+ "version": "1.0.989",
4
4
  "description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -75,6 +75,12 @@ public:
75
75
  */
76
76
  virtual void detect(AbstractState& as, const ICFGNode* node) = 0;
77
77
 
78
+ /**
79
+ * @brief Pure virtual function for handling stub external API calls. (e.g. UNSAFE_BUFACCESS)
80
+ * @param call Pointer to the ext call ICFG node.
81
+ */
82
+ virtual void handleStubFunctions(const CallICFGNode* call) = 0;
83
+
78
84
  /**
79
85
  * @brief Pure virtual function to report detected bugs.
80
86
  */
@@ -169,6 +175,13 @@ public:
169
175
  */
170
176
  void detect(AbstractState& as, const ICFGNode*);
171
177
 
178
+
179
+ /**
180
+ * @brief Handles external API calls related to buffer overflow detection.
181
+ * @param call Pointer to the call ICFG node.
182
+ */
183
+ void handleStubFunctions(const CallICFGNode*);
184
+
172
185
  /**
173
186
  * @brief Adds an offset to a GEP object.
174
187
  * @param obj Pointer to the GEP object.
@@ -277,11 +290,11 @@ public:
277
290
  /**
278
291
  * @brief Checks if memory can be safely accessed.
279
292
  * @param as Reference to the abstract state.
280
- * @param value Pointer to the SVF value.
293
+ * @param value Pointer to the SVF var.
281
294
  * @param len The interval value representing the length of the memory access.
282
295
  * @return True if the memory access is safe, false otherwise.
283
296
  */
284
- bool canSafelyAccessMemory(AbstractState& as, const SVFValue *value, const IntervalValue &len);
297
+ bool canSafelyAccessMemory(AbstractState& as, const SVFVar *value, const IntervalValue &len);
285
298
 
286
299
  private:
287
300
  /**
@@ -0,0 +1,147 @@
1
+ //===- AbsExtAPI.h -- Abstract Interpretation External API handler-----//
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/9/9.
26
+ //
27
+ #pragma once
28
+ #include "AE/Core/AbstractState.h"
29
+ #include "AE/Core/ICFGWTO.h"
30
+ #include "AE/Svfexe/AEDetector.h"
31
+ #include "AE/Svfexe/AbsExtAPI.h"
32
+ #include "Util/SVFBugReport.h"
33
+ #include "WPA/Andersen.h"
34
+
35
+ namespace SVF
36
+ {
37
+
38
+ // Forward declaration of AbstractInterpretation class
39
+ class AbstractInterpretation;
40
+
41
+ /**
42
+ * @class AbsExtAPI
43
+ * @brief Handles external API calls and manages abstract states.
44
+ */
45
+ class AbsExtAPI
46
+ {
47
+ public:
48
+ /**
49
+ * @enum ExtAPIType
50
+ * @brief Enumeration of external API types.
51
+ */
52
+ enum ExtAPIType { UNCLASSIFIED, MEMCPY, MEMSET, STRCPY, STRCAT };
53
+
54
+ /**
55
+ * @brief Constructor for AbsExtAPI.
56
+ * @param abstractTrace Reference to a map of ICFG nodes to abstract states.
57
+ */
58
+ AbsExtAPI(Map<const ICFGNode*, AbstractState>& abstractTrace);
59
+
60
+ /**
61
+ * @brief Initializes the external function map.
62
+ */
63
+ void initExtFunMap();
64
+
65
+ /**
66
+ * @brief Reads a string from the abstract state.
67
+ * @param as Reference to the abstract state.
68
+ * @param rhs Pointer to the SVF variable representing the string.
69
+ * @return The string value.
70
+ */
71
+ std::string strRead(AbstractState& as, const SVFVar* rhs);
72
+
73
+ /**
74
+ * @brief Handles an external API call.
75
+ * @param call Pointer to the call ICFG node.
76
+ */
77
+ void handleExtAPI(const CallICFGNode *call);
78
+
79
+ /**
80
+ * @brief Handles the strcpy API call.
81
+ * @param call Pointer to the call ICFG node.
82
+ */
83
+ void handleStrcpy(const CallICFGNode *call);
84
+
85
+ /**
86
+ * @brief Calculates the length of a string.
87
+ * @param as Reference to the abstract state.
88
+ * @param strValue Pointer to the SVF variable representing the string.
89
+ * @return The interval value representing the string length.
90
+ */
91
+ IntervalValue getStrlen(AbstractState& as, const SVF::SVFVar *strValue);
92
+
93
+ /**
94
+ * @brief Handles the strcat API call.
95
+ * @param call Pointer to the call ICFG node.
96
+ */
97
+ void handleStrcat(const SVF::CallICFGNode *call);
98
+
99
+ /**
100
+ * @brief Handles the memcpy API call.
101
+ * @param as Reference to the abstract state.
102
+ * @param dst Pointer to the destination SVF variable.
103
+ * @param src Pointer to the source SVF variable.
104
+ * @param len The interval value representing the length to copy.
105
+ * @param start_idx The starting index for copying.
106
+ */
107
+ void handleMemcpy(AbstractState& as, const SVF::SVFVar *dst, const SVF::SVFVar *src, IntervalValue len, u32_t start_idx);
108
+
109
+ /**
110
+ * @brief Handles the memset API call.
111
+ * @param as Reference to the abstract state.
112
+ * @param dst Pointer to the destination SVF variable.
113
+ * @param elem The interval value representing the element to set.
114
+ * @param len The interval value representing the length to set.
115
+ */
116
+ void handleMemset(AbstractState& as, const SVFVar* dst, IntervalValue elem, IntervalValue len);
117
+
118
+ /**
119
+ * @brief Gets the range limit from a type.
120
+ * @param type Pointer to the SVF type.
121
+ * @return The interval value representing the range limit.
122
+ */
123
+ IntervalValue getRangeLimitFromType(const SVFType* type);
124
+
125
+ /**
126
+ * @brief Retrieves the abstract state from the trace for a given ICFG node.
127
+ * @param node Pointer to the ICFG node.
128
+ * @return Reference to the abstract state.
129
+ * @throws Assertion if no trace exists for the node.
130
+ */
131
+ AbstractState& getAbsStateFromTrace(const ICFGNode* node);
132
+
133
+ /**
134
+ * @brief Retrieves the SVF variable from a given SVF value.
135
+ * @param val Pointer to the SVF value.
136
+ * @return Pointer to the corresponding SVF variable.
137
+ */
138
+ const SVFVar* getSVFVar(const SVFValue* val);
139
+
140
+ protected:
141
+ SVFIR* svfir; ///< Pointer to the SVF intermediate representation.
142
+ ICFG* icfg; ///< Pointer to the interprocedural control flow graph.
143
+ Map<const ICFGNode*, AbstractState>& abstractTrace; ///< Map of ICFG nodes to abstract states.
144
+ Map<std::string, std::function<void(const CallICFGNode*)>> func_map; ///< Map of function names to handlers.
145
+ };
146
+
147
+ } // namespace SVF
@@ -31,12 +31,14 @@
31
31
  #include "AE/Core/AbstractState.h"
32
32
  #include "AE/Core/ICFGWTO.h"
33
33
  #include "AE/Svfexe/AEDetector.h"
34
+ #include "AE/Svfexe/AbsExtAPI.h"
34
35
  #include "Util/SVFBugReport.h"
35
36
  #include "WPA/Andersen.h"
36
37
 
37
38
  namespace SVF
38
39
  {
39
40
  class AbstractInterpretation;
41
+ class AbsExtAPI;
40
42
  class AEStat;
41
43
  class AEAPI;
42
44
 
@@ -104,7 +106,6 @@ class AbstractInterpretation
104
106
  friend class BufOverflowDetector;
105
107
 
106
108
  public:
107
- enum ExtAPIType { UNCLASSIFIED, MEMCPY, MEMSET, STRCPY, STRCAT };
108
109
  typedef SCCDetection<CallGraph*> CallGraphSCC;
109
110
  /// Constructor
110
111
  AbstractInterpretation();
@@ -128,7 +129,9 @@ public:
128
129
  detectors.push_back(std::move(detector));
129
130
  }
130
131
 
131
- protected:
132
+ Set<const CallICFGNode*> checkpoints; // for CI check
133
+
134
+ private:
132
135
  /// Global ICFGNode is handled at the entry of the program,
133
136
  virtual void handleGlobalNode();
134
137
 
@@ -213,77 +216,6 @@ protected:
213
216
  AbstractState& as);
214
217
 
215
218
 
216
- /**
217
- * handle external function call
218
- *
219
- * @param call call node whose callee is external function
220
- */
221
- virtual void handleExtAPI(const CallICFGNode *call);
222
-
223
- /**
224
- * the map of external function to its API type
225
- *
226
- * In AEAPI, this function is mainly used for abstract explanation.
227
- * In subclasses, this function is mainly used to check specific bugs
228
- */
229
- virtual void initExtFunMap();
230
-
231
-
232
- /**
233
- * get byte size of alloca inst
234
- * e.g. source code str = "abc", there are str value, return "abc"
235
- *
236
- * @param rhs SVFValue of string
237
- * @return the string
238
- */
239
- std::string strRead(AbstractState& as,const SVFValue* rhs);
240
-
241
- /**
242
- * get length of string
243
- * e.g. source code str = "abc", return 3
244
- *
245
- * @param strValue SVFValue of string
246
- * @return IntervalValue of string length
247
- */
248
- IntervalValue getStrlen(AbstractState& as, const SVF::SVFValue *strValue);
249
-
250
- /**
251
- * execute strcpy in abstract execution
252
- * e.g arr = new char[10]
253
- * str = "abc"
254
- * strcpy(arr, str)
255
- * we can set arr[0]='a', arr[1]='b', arr[2]='c', arr[3]='\0'
256
- * @param call callnode of strcpy like api
257
- */
258
- virtual void handleStrcpy(const CallICFGNode *call);
259
- /**
260
- * execute strcpy in abstract execution
261
- * e.g arr[10] = "abc"
262
- * str = "de"
263
- * strcat(arr, str)
264
- * we can set arr[3]='d', arr[4]='e', arr[5]='\0'
265
- * @param call callnode of strcat like api
266
- */
267
- virtual void handleStrcat(const CallICFGNode *call);
268
- /**
269
- * execute memcpy in abstract execution
270
- * e.g arr = new char[10]
271
- * str = "abcd"
272
- * memcpy(arr, str, 5)
273
- * we can set arr[3]='d', arr[4]='e', arr[5]='\0'
274
- * @param call callnode of memcpy like api
275
- */
276
- virtual void handleMemcpy(AbstractState& as, const SVFValue* dst, const SVFValue* src, IntervalValue len, u32_t start_idx);
277
- /**
278
- * execute memset in abstract execution
279
- * e.g arr = new char[10]
280
- * memset(arr, 'c', 2)
281
- * we can set arr[0]='c', arr[1]='c', arr[2]='\0'
282
- * @param call callnode of memset like api
283
- */
284
- virtual void handleMemset(AbstractState& as, const SVFValue* dst, IntervalValue elem, IntervalValue len);
285
-
286
-
287
219
  void collectCheckPoint();
288
220
  void checkPointAllSet();
289
221
 
@@ -309,8 +241,6 @@ protected:
309
241
 
310
242
  void updateStateOnPhi(const PhiStmt *phi);
311
243
 
312
- IntervalValue getRangeLimitFromType(const SVFType* type);
313
-
314
244
 
315
245
  /// protected data members, also used in subclasses
316
246
  SVFIR* svfir;
@@ -324,18 +254,6 @@ protected:
324
254
  Map<const SVFFunction*, ICFGWTO*> funcToWTO;
325
255
  Set<const SVFFunction*> recursiveFuns;
326
256
 
327
- private:
328
- // helper functions in handleCallSite
329
- virtual bool isExtCall(const CallICFGNode* callNode);
330
- virtual void extCallPass(const CallICFGNode* callNode);
331
- virtual bool isRecursiveCall(const CallICFGNode* callNode);
332
- virtual void recursiveCallPass(const CallICFGNode* callNode);
333
- virtual bool isDirectCall(const CallICFGNode* callNode);
334
- virtual void directCallFunPass(const CallICFGNode* callNode);
335
- virtual bool isIndirectCall(const CallICFGNode* callNode);
336
- virtual void indirectCallFunPass(const CallICFGNode* callNode);
337
-
338
- protected:
339
257
 
340
258
  AbstractState& getAbsStateFromTrace(const ICFGNode* node)
341
259
  {
@@ -356,16 +274,31 @@ protected:
356
274
  return abstractTrace.count(repNode) != 0;
357
275
  }
358
276
 
359
- protected:
277
+ AbsExtAPI* getUtils()
278
+ {
279
+ return utils;
280
+ }
281
+
282
+ // helper functions in handleCallSite
283
+ virtual bool isExtCall(const CallICFGNode* callNode);
284
+ virtual void extCallPass(const CallICFGNode* callNode);
285
+ virtual bool isRecursiveCall(const CallICFGNode* callNode);
286
+ virtual void recursiveCallPass(const CallICFGNode* callNode);
287
+ virtual bool isDirectCall(const CallICFGNode* callNode);
288
+ virtual void directCallFunPass(const CallICFGNode* callNode);
289
+ virtual bool isIndirectCall(const CallICFGNode* callNode);
290
+ virtual void indirectCallFunPass(const CallICFGNode* callNode);
291
+
360
292
  // there data should be shared with subclasses
361
293
  Map<std::string, std::function<void(const CallICFGNode*)>> 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
294
+
295
+ Map<const ICFGNode*, AbstractState> abstractTrace; // abstract states immediately after nodes
366
296
  std::string moduleName;
367
297
 
368
298
  std::vector<std::unique_ptr<AEDetector>> detectors;
299
+ AbsExtAPI* utils;
300
+
301
+
369
302
 
370
303
  };
371
304
  }
@@ -319,7 +319,6 @@ private:
319
319
  const SVFFunction* realDefFun; /// the definition of a function across multiple modules
320
320
  std::vector<const SVFBasicBlock*> allBBs; /// all BasicBlocks of this function
321
321
  std::vector<const SVFArgument*> allArgs; /// all formal arguments of this function
322
- std::vector<std::string> annotations; /// annotations of this function
323
322
  SVFBasicBlock *exitBlock; /// a 'single' basic block having no successors and containing return instruction in a function
324
323
 
325
324
  protected:
@@ -463,16 +462,6 @@ public:
463
462
  return !isNotRet;
464
463
  }
465
464
 
466
- inline const std::vector<std::string>& getAnnotations() const
467
- {
468
- return annotations;
469
- }
470
-
471
- inline void setAnnotations(std::vector<std::string>& annotations)
472
- {
473
- this->annotations = annotations;
474
- }
475
-
476
465
  inline void getExitBlocksOfLoop(const SVFBasicBlock* bb, BBList& exitbbs) const
477
466
  {
478
467
  return loopAndDom->getExitBlocksOfLoop(bb,exitbbs);
@@ -43,10 +43,14 @@ namespace SVF
43
43
 
44
44
  class ExtAPI
45
45
  {
46
+ friend class LLVMModuleSet;
46
47
  private:
47
48
 
48
49
  static ExtAPI *extOp;
49
50
 
51
+ // Map SVFFunction to its annotations
52
+ Map<const SVFFunction*, std::vector<std::string>> func2Annotations;
53
+
50
54
  // extapi.bc file path
51
55
  static std::string extBcPath;
52
56
 
@@ -67,6 +71,8 @@ public:
67
71
  // Get the annotation of (F)
68
72
  std::string getExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation);
69
73
 
74
+ const std::vector<std::string>& getExtFuncAnnotations(const SVFFunction* fun);
75
+
70
76
  // Does (F) have some annotation?
71
77
  bool hasExtFuncAnnotation(const SVFFunction* fun, const std::string& funcAnnotation);
72
78
 
@@ -94,6 +100,10 @@ public:
94
100
  // Should (F) be considered "external" (either not defined in the program
95
101
  // or a user-defined version of a known alloc or no-op)?
96
102
  bool is_ext(const SVFFunction *F);
103
+
104
+ private:
105
+ // Set the annotation of (F)
106
+ void setExtFuncAnnotations(const SVFFunction* fun, const std::vector<std::string>& funcAnnotations);
97
107
  };
98
108
  } // End namespace SVF
99
109
 
@@ -391,19 +391,13 @@ bool isExtCall(const ICFGNode* node);
391
391
 
392
392
  bool isHeapAllocExtCallViaArg(const CallICFGNode* cs);
393
393
 
394
- bool isHeapAllocExtCallViaArg(const SVFInstruction *inst);
395
-
396
- bool isHeapAllocExtCallViaRet(const SVFInstruction *inst);
397
394
 
398
395
  /// interfaces to be used externally
399
396
  bool isHeapAllocExtCallViaRet(const CallICFGNode* cs);
400
397
 
401
398
  bool isHeapAllocExtCall(const ICFGNode* cs);
402
399
 
403
- inline bool isHeapAllocExtCall(const SVFInstruction *inst)
404
- {
405
- return isHeapAllocExtCallViaRet(inst) || isHeapAllocExtCallViaArg(inst);
406
- }
400
+
407
401
 
408
402
  //@}
409
403