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.
@@ -26,6 +26,7 @@
26
26
  //
27
27
 
28
28
  #include <AE/Svfexe/AEDetector.h>
29
+ #include <AE/Svfexe/AbsExtAPI.h>
29
30
  #include <AE/Svfexe/AbstractInterpretation.h>
30
31
 
31
32
  using namespace SVF;
@@ -101,6 +102,85 @@ void BufOverflowDetector::detect(AbstractState& as, const ICFGNode* node)
101
102
  }
102
103
  }
103
104
 
105
+
106
+ /**
107
+ * @brief Handles stub functions within the ICFG node.
108
+ *
109
+ * This function is a placeholder for handling stub functions within the ICFG node.
110
+ *
111
+ * @param node Pointer to the ICFG node.
112
+ */
113
+ void BufOverflowDetector::handleStubFunctions(const SVF::CallICFGNode* callNode)
114
+ {
115
+ // get function name
116
+ SVFIR* svfir = PAG::getPAG();
117
+ std::string funcName = callNode->getCalledFunction()->getName();
118
+ if (funcName == "SAFE_BUFACCESS")
119
+ {
120
+ // void SAFE_BUFACCESS(void* data, int size);
121
+ AbstractInterpretation::getAEInstance().checkpoints.erase(callNode);
122
+ if (callNode->arg_size() < 2)
123
+ return;
124
+ AbstractState& as =
125
+ AbstractInterpretation::getAEInstance().getAbsStateFromTrace(
126
+ callNode);
127
+ u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
128
+ IntervalValue val = as[size_id].getInterval();
129
+ if (val.isBottom())
130
+ {
131
+ val = IntervalValue(0);
132
+ assert(false && "SAFE_BUFACCESS size is bottom");
133
+ }
134
+ const SVFVar* arg0Val =
135
+ AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(
136
+ callNode->getArgument(0));
137
+ bool isSafe = canSafelyAccessMemory(as, arg0Val, val);
138
+ if (isSafe)
139
+ {
140
+ std::cout << "safe buffer access success: " << callNode->toString()
141
+ << std::endl;
142
+ return;
143
+ }
144
+ else
145
+ {
146
+ std::string err_msg = "this SAFE_BUFACCESS should be a safe access but detected buffer overflow. Pos: ";
147
+ err_msg += callNode->getSourceLoc();
148
+ std::cerr << err_msg << std::endl;
149
+ assert(false);
150
+ }
151
+ }
152
+ else if (funcName == "UNSAFE_BUFACCESS")
153
+ {
154
+ // handle other stub functions
155
+ //void UNSAFE_BUFACCESS(void* data, int size);
156
+ AbstractInterpretation::getAEInstance().checkpoints.erase(callNode);
157
+ if (callNode->arg_size() < 2) return;
158
+ AbstractState&as = AbstractInterpretation::getAEInstance().getAbsStateFromTrace(callNode);
159
+ u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
160
+ IntervalValue val = as[size_id].getInterval();
161
+ if (val.isBottom())
162
+ {
163
+ assert(false && "UNSAFE_BUFACCESS size is bottom");
164
+ }
165
+ const SVFVar* arg0Val =
166
+ AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(
167
+ callNode->getArgument(0));
168
+ bool isSafe = canSafelyAccessMemory(as, arg0Val, val);
169
+ if (!isSafe)
170
+ {
171
+ std::cout << "detect buffer overflow success: " << callNode->toString() << std::endl;
172
+ return;
173
+ }
174
+ else
175
+ {
176
+ std::string err_msg = "this UNSAFE_BUFACCESS should be a buffer overflow but not detected. Pos: ";
177
+ err_msg += callNode->getSourceLoc();
178
+ std::cerr << err_msg << std::endl;
179
+ assert(false);
180
+ }
181
+ }
182
+ }
183
+
104
184
  /**
105
185
  * @brief Initializes external API buffer overflow check rules.
106
186
  *
@@ -147,23 +227,23 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
147
227
  SVFIR* svfir = PAG::getPAG();
148
228
  assert(call->getCalledFunction() && "SVFFunction* is nullptr");
149
229
 
150
- AbstractInterpretation::ExtAPIType extType = AbstractInterpretation::UNCLASSIFIED;
230
+ AbsExtAPI::ExtAPIType extType = AbsExtAPI::UNCLASSIFIED;
151
231
 
152
232
  // Determine the type of external memory API
153
- for (const std::string &annotation : call->getCalledFunction()->getAnnotations())
233
+ for (const std::string &annotation : ExtAPI::getExtAPI()->getExtFuncAnnotations(call->getCalledFunction()))
154
234
  {
155
235
  if (annotation.find("MEMCPY") != std::string::npos)
156
- extType = AbstractInterpretation::MEMCPY;
236
+ extType = AbsExtAPI::MEMCPY;
157
237
  if (annotation.find("MEMSET") != std::string::npos)
158
- extType = AbstractInterpretation::MEMSET;
238
+ extType = AbsExtAPI::MEMSET;
159
239
  if (annotation.find("STRCPY") != std::string::npos)
160
- extType = AbstractInterpretation::STRCPY;
240
+ extType = AbsExtAPI::STRCPY;
161
241
  if (annotation.find("STRCAT") != std::string::npos)
162
- extType = AbstractInterpretation::STRCAT;
242
+ extType = AbsExtAPI::STRCAT;
163
243
  }
164
244
 
165
245
  // Apply buffer overflow checks based on the determined API type
166
- if (extType == AbstractInterpretation::MEMCPY)
246
+ if (extType == AbsExtAPI::MEMCPY)
167
247
  {
168
248
  if (extAPIBufOverflowCheckRules.count(call->getCalledFunction()->getName()) == 0)
169
249
  {
@@ -175,14 +255,15 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
175
255
  for (auto arg : args)
176
256
  {
177
257
  IntervalValue offset = as[svfir->getValueNode(call->getArgument(arg.second))].getInterval() - IntervalValue(1);
178
- if (!canSafelyAccessMemory(as, call->getArgument(arg.first), offset))
258
+ const SVFVar* argVar = AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(call->getArgument(arg.first));
259
+ if (!canSafelyAccessMemory(as, argVar, offset))
179
260
  {
180
261
  AEException bug(call->toString());
181
262
  addBugToReporter(bug, call);
182
263
  }
183
264
  }
184
265
  }
185
- else if (extType == AbstractInterpretation::MEMSET)
266
+ else if (extType == AbsExtAPI::MEMSET)
186
267
  {
187
268
  if (extAPIBufOverflowCheckRules.count(call->getCalledFunction()->getName()) == 0)
188
269
  {
@@ -194,14 +275,15 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
194
275
  for (auto arg : args)
195
276
  {
196
277
  IntervalValue offset = as[svfir->getValueNode(call->getArgument(arg.second))].getInterval() - IntervalValue(1);
197
- if (!canSafelyAccessMemory(as, call->getArgument(arg.first), offset))
278
+ const SVFVar* argVar = AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(call->getArgument(arg.first));
279
+ if (!canSafelyAccessMemory(as, argVar, offset))
198
280
  {
199
281
  AEException bug(call->toString());
200
282
  addBugToReporter(bug, call);
201
283
  }
202
284
  }
203
285
  }
204
- else if (extType == AbstractInterpretation::STRCPY)
286
+ else if (extType == AbsExtAPI::STRCPY)
205
287
  {
206
288
  if (!detectStrcpy(as, call))
207
289
  {
@@ -209,7 +291,7 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
209
291
  addBugToReporter(bug, call);
210
292
  }
211
293
  }
212
- else if (extType == AbstractInterpretation::STRCAT)
294
+ else if (extType == AbsExtAPI::STRCAT)
213
295
  {
214
296
  if (!detectStrcat(as, call))
215
297
  {
@@ -319,9 +401,9 @@ void BufOverflowDetector::updateGepObjOffsetFromBase(SVF::AddressValue gepAddrs,
319
401
  */
320
402
  bool BufOverflowDetector::detectStrcpy(AbstractState& as, const CallICFGNode *call)
321
403
  {
322
- const SVFValue* arg0Val = call->getArgument(0);
323
- const SVFValue* arg1Val = call->getArgument(1);
324
- IntervalValue strLen = AbstractInterpretation::getAEInstance().getStrlen(as, arg1Val);
404
+ const SVFVar* arg0Val = AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(call->getArgument(0));
405
+ const SVFVar* arg1Val = AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(call->getArgument(1));
406
+ IntervalValue strLen = AbstractInterpretation::getAEInstance().getUtils()->getStrlen(as, arg1Val);
325
407
  return canSafelyAccessMemory(as, arg0Val, strLen);
326
408
  }
327
409
 
@@ -337,26 +419,24 @@ bool BufOverflowDetector::detectStrcpy(AbstractState& as, const CallICFGNode *ca
337
419
  */
338
420
  bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *call)
339
421
  {
340
- SVFIR* svfir = PAG::getPAG();
341
-
342
422
  const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
343
423
  const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
344
424
 
345
425
  if (std::find(strcatGroup.begin(), strcatGroup.end(), call->getCalledFunction()->getName()) != strcatGroup.end())
346
426
  {
347
- const SVFValue* arg0Val = call->getArgument(0);
348
- const SVFValue* arg1Val = call->getArgument(1);
349
- IntervalValue strLen0 = AbstractInterpretation::getAEInstance().getStrlen(as, arg0Val);
350
- IntervalValue strLen1 = AbstractInterpretation::getAEInstance().getStrlen(as, arg1Val);
427
+ const SVFVar* arg0Val = AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(call->getArgument(0));
428
+ const SVFVar* arg1Val = AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(call->getArgument(1));
429
+ IntervalValue strLen0 = AbstractInterpretation::getAEInstance().getUtils()->getStrlen(as, arg0Val);
430
+ IntervalValue strLen1 = AbstractInterpretation::getAEInstance().getUtils()->getStrlen(as, arg1Val);
351
431
  IntervalValue totalLen = strLen0 + strLen1;
352
432
  return canSafelyAccessMemory(as, arg0Val, totalLen);
353
433
  }
354
434
  else if (std::find(strncatGroup.begin(), strncatGroup.end(), call->getCalledFunction()->getName()) != strncatGroup.end())
355
435
  {
356
- const SVFValue* arg0Val = call->getArgument(0);
357
- const SVFValue* arg2Val = call->getArgument(2);
358
- IntervalValue arg2Num = as[svfir->getValueNode(arg2Val)].getInterval();
359
- IntervalValue strLen0 = AbstractInterpretation::getAEInstance().getStrlen(as, arg0Val);
436
+ const SVFVar* arg0Val = AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(call->getArgument(0));
437
+ const SVFVar* arg2Val = AbstractInterpretation::getAEInstance().getUtils()->getSVFVar(call->getArgument(2));
438
+ IntervalValue arg2Num = as[arg2Val->getId()].getInterval();
439
+ IntervalValue strLen0 = AbstractInterpretation::getAEInstance().getUtils()->getStrlen(as, arg0Val);
360
440
  IntervalValue totalLen = strLen0 + arg2Num;
361
441
  return canSafelyAccessMemory(as, arg0Val, totalLen);
362
442
  }
@@ -374,14 +454,14 @@ bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *ca
374
454
  * does not exceed the allocated size of the buffer.
375
455
  *
376
456
  * @param as Reference to the abstract state.
377
- * @param value Pointer to the SVF value.
457
+ * @param value Pointer to the SVF var.
378
458
  * @param len The interval value representing the length of the memory access.
379
459
  * @return True if the memory access is safe, false otherwise.
380
460
  */
381
- bool BufOverflowDetector::canSafelyAccessMemory(AbstractState& as, const SVF::SVFValue* value, const SVF::IntervalValue& len)
461
+ bool BufOverflowDetector::canSafelyAccessMemory(AbstractState& as, const SVF::SVFVar* value, const SVF::IntervalValue& len)
382
462
  {
383
463
  SVFIR* svfir = PAG::getPAG();
384
- NodeID value_id = svfir->getValueNode(value);
464
+ NodeID value_id = value->getId();
385
465
 
386
466
  assert(as[value_id].isAddr());
387
467
  for (const auto& addr : as[value_id].getAddrs())