svf-tools 1.0.985 → 1.0.987
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 +1 -1
- package/svf/include/Graphs/ICFGNode.h +1 -1
- package/svf/include/MTA/LockAnalysis.h +9 -3
- package/svf/include/MTA/MHP.h +10 -6
- package/svf/include/MTA/TCT.h +3 -3
- package/svf/include/SABER/SaberCheckerAPI.h +4 -4
- package/svf/include/Util/SVFUtil.h +12 -49
- package/svf/include/Util/ThreadAPI.h +10 -33
- package/svf/lib/AE/Svfexe/AEDetector.cpp +11 -14
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +254 -167
- package/svf/lib/CFL/CFLAlias.cpp +1 -1
- package/svf/lib/Graphs/CallGraph.cpp +2 -2
- package/svf/lib/MTA/LockAnalysis.cpp +2 -2
- package/svf/lib/MTA/MHP.cpp +9 -7
- package/svf/lib/MemoryModel/PointerAnalysis.cpp +2 -2
- package/svf/lib/SABER/DoubleFreeChecker.cpp +1 -1
- package/svf/lib/SABER/LeakChecker.cpp +1 -1
- package/svf/lib/Util/CallGraphBuilder.cpp +4 -4
- package/svf/lib/Util/SVFBugReport.cpp +2 -1
- package/svf/lib/Util/SVFUtil.cpp +25 -10
- package/svf/lib/Util/ThreadAPI.cpp +32 -12
- package/svf/lib/WPA/Andersen.cpp +1 -1
- package/svf/lib/WPA/Steensgaard.cpp +1 -1
- package/svf-llvm/lib/ICFGBuilder.cpp +1 -1
- package/svf-llvm/lib/SymbolTableBuilder.cpp +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.987",
|
|
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": {
|
|
@@ -462,7 +462,7 @@ public:
|
|
|
462
462
|
/// Return true if this is an indirect call
|
|
463
463
|
inline bool isIndirectCall() const
|
|
464
464
|
{
|
|
465
|
-
return nullptr == SVFUtil::
|
|
465
|
+
return nullptr == SVFUtil::cast<SVFCallInst>(cs)->getCalledFunction();
|
|
466
466
|
}
|
|
467
467
|
|
|
468
468
|
/// Return the set of actual parameters
|
|
@@ -437,17 +437,23 @@ private:
|
|
|
437
437
|
/// Whether it is a lock site
|
|
438
438
|
inline bool isTDFork(const ICFGNode* call)
|
|
439
439
|
{
|
|
440
|
-
|
|
440
|
+
if(SVFUtil::isa<CallICFGNode>(call) == false)
|
|
441
|
+
return false;
|
|
442
|
+
return getTCG()->getThreadAPI()->isTDFork(SVFUtil::cast<CallICFGNode>(call));
|
|
441
443
|
}
|
|
442
444
|
/// Whether it is a lock site
|
|
443
445
|
inline bool isTDAcquire(const ICFGNode* call)
|
|
444
446
|
{
|
|
445
|
-
|
|
447
|
+
if(SVFUtil::isa<CallICFGNode>(call) == false)
|
|
448
|
+
return false;
|
|
449
|
+
return getTCG()->getThreadAPI()->isTDAcquire(SVFUtil::cast<CallICFGNode>(call));
|
|
446
450
|
}
|
|
447
451
|
/// Whether it is a unlock site
|
|
448
452
|
inline bool isTDRelease(const ICFGNode* call)
|
|
449
453
|
{
|
|
450
|
-
|
|
454
|
+
if(SVFUtil::isa<CallICFGNode>(call) == false)
|
|
455
|
+
return false;
|
|
456
|
+
return getTCG()->getThreadAPI()->isTDRelease(SVFUtil::cast<CallICFGNode>(call));
|
|
451
457
|
}
|
|
452
458
|
/// Whether it is a callsite
|
|
453
459
|
inline bool isCallSite(const ICFGNode* inst)
|
package/svf/include/MTA/MHP.h
CHANGED
|
@@ -227,12 +227,14 @@ private:
|
|
|
227
227
|
/// Whether it is a fork site
|
|
228
228
|
inline bool isTDFork(const ICFGNode* call)
|
|
229
229
|
{
|
|
230
|
-
|
|
230
|
+
const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
|
|
231
|
+
return fork && tcg->getThreadAPI()->isTDFork(fork);
|
|
231
232
|
}
|
|
232
233
|
/// Whether it is a join site
|
|
233
234
|
inline bool isTDJoin(const ICFGNode* call)
|
|
234
235
|
{
|
|
235
|
-
|
|
236
|
+
const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
|
|
237
|
+
return join && tcg->getThreadAPI()->isTDJoin(join);
|
|
236
238
|
}
|
|
237
239
|
|
|
238
240
|
/// Return thread id(s) which are directly or indirectly joined at this join site
|
|
@@ -345,11 +347,11 @@ public:
|
|
|
345
347
|
}
|
|
346
348
|
|
|
347
349
|
/// Get loop for join site
|
|
348
|
-
inline LoopBBs& getJoinLoop(const
|
|
350
|
+
inline LoopBBs& getJoinLoop(const CallICFGNode* inst)
|
|
349
351
|
{
|
|
350
352
|
return tct->getJoinLoop(inst);
|
|
351
353
|
}
|
|
352
|
-
inline bool hasJoinLoop(const
|
|
354
|
+
inline bool hasJoinLoop(const CallICFGNode* inst)
|
|
353
355
|
{
|
|
354
356
|
return tct->hasJoinLoop(inst);
|
|
355
357
|
}
|
|
@@ -461,12 +463,14 @@ private:
|
|
|
461
463
|
/// Whether it is a fork site
|
|
462
464
|
inline bool isTDFork(const ICFGNode* call)
|
|
463
465
|
{
|
|
464
|
-
|
|
466
|
+
const CallICFGNode* fork = SVFUtil::dyn_cast<CallICFGNode>(call);
|
|
467
|
+
return fork && getTCG()->getThreadAPI()->isTDFork(fork);
|
|
465
468
|
}
|
|
466
469
|
/// Whether it is a join site
|
|
467
470
|
inline bool isTDJoin(const ICFGNode* call)
|
|
468
471
|
{
|
|
469
|
-
|
|
472
|
+
const CallICFGNode* join = SVFUtil::dyn_cast<CallICFGNode>(call);
|
|
473
|
+
return join && getTCG()->getThreadAPI()->isTDJoin(join);
|
|
470
474
|
}
|
|
471
475
|
/// Get forked thread
|
|
472
476
|
inline const SVFValue* getForkedThread(const CallICFGNode* call)
|
package/svf/include/MTA/TCT.h
CHANGED
|
@@ -364,7 +364,7 @@ public:
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
/// Get loop for join site
|
|
367
|
-
inline LoopBBs& getJoinLoop(const
|
|
367
|
+
inline LoopBBs& getJoinLoop(const CallICFGNode* join)
|
|
368
368
|
{
|
|
369
369
|
assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site");
|
|
370
370
|
InstToLoopMap::iterator it = joinSiteToLoopMap.find(join);
|
|
@@ -372,7 +372,7 @@ public:
|
|
|
372
372
|
return it->second;
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
inline bool hasJoinLoop(const
|
|
375
|
+
inline bool hasJoinLoop(const CallICFGNode* join) const
|
|
376
376
|
{
|
|
377
377
|
assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site");
|
|
378
378
|
InstToLoopMap::const_iterator it = joinSiteToLoopMap.find(join);
|
|
@@ -407,7 +407,7 @@ public:
|
|
|
407
407
|
MaxCxtSize = cxt.size();
|
|
408
408
|
}
|
|
409
409
|
/// Whether a join site is in recursion
|
|
410
|
-
inline bool isJoinSiteInRecursion(const
|
|
410
|
+
inline bool isJoinSiteInRecursion(const CallICFGNode* join) const
|
|
411
411
|
{
|
|
412
412
|
assert(tcg->getThreadAPI()->isTDJoin(join) && "not a join site");
|
|
413
413
|
return inRecurJoinSites.find(join)!=inRecurJoinSites.end();
|
|
@@ -103,7 +103,7 @@ public:
|
|
|
103
103
|
}
|
|
104
104
|
inline bool isMemAlloc(const CallICFGNode* cs) const
|
|
105
105
|
{
|
|
106
|
-
return isMemAlloc(
|
|
106
|
+
return isMemAlloc(cs->getCalledFunction());
|
|
107
107
|
}
|
|
108
108
|
//@}
|
|
109
109
|
|
|
@@ -115,7 +115,7 @@ public:
|
|
|
115
115
|
}
|
|
116
116
|
inline bool isMemDealloc(const CallICFGNode* cs) const
|
|
117
117
|
{
|
|
118
|
-
return isMemDealloc(
|
|
118
|
+
return isMemDealloc(cs->getCalledFunction());
|
|
119
119
|
}
|
|
120
120
|
//@}
|
|
121
121
|
|
|
@@ -127,7 +127,7 @@ public:
|
|
|
127
127
|
}
|
|
128
128
|
inline bool isFOpen(const CallICFGNode* cs) const
|
|
129
129
|
{
|
|
130
|
-
return isFOpen(
|
|
130
|
+
return isFOpen(cs->getCalledFunction());
|
|
131
131
|
}
|
|
132
132
|
//@}
|
|
133
133
|
|
|
@@ -139,7 +139,7 @@ public:
|
|
|
139
139
|
}
|
|
140
140
|
inline bool isFClose(const CallICFGNode* cs) const
|
|
141
141
|
{
|
|
142
|
-
return isFClose(
|
|
142
|
+
return isFClose(cs->getCalledFunction());
|
|
143
143
|
}
|
|
144
144
|
//@}
|
|
145
145
|
|
|
@@ -228,25 +228,6 @@ inline std::vector<std::string> split(const std::string& s, char separator)
|
|
|
228
228
|
return output;
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
/// Return callee of a callsite. Return null if this is an indirect call
|
|
232
|
-
//@{
|
|
233
|
-
inline const SVFFunction* getCallee(const SVFCallInst* cs)
|
|
234
|
-
{
|
|
235
|
-
return cs->getCalledFunction();
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
inline const SVFFunction* getCallee(const SVFInstruction *inst)
|
|
239
|
-
{
|
|
240
|
-
if (!isCallSite(inst))
|
|
241
|
-
return nullptr;
|
|
242
|
-
return getCallee(cast<SVFCallInst>(inst));
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const SVFFunction* getCallee(const CallICFGNode *inst);
|
|
246
|
-
|
|
247
|
-
const SVFFunction* getCallee(const ICFGNode *inst);
|
|
248
|
-
//@}
|
|
249
|
-
|
|
250
231
|
/// Given a map mapping points-to sets to a count, adds from into to.
|
|
251
232
|
template <typename Data>
|
|
252
233
|
void mergePtsOccMaps(Map<Data, unsigned> &to, const Map<Data, unsigned> from)
|
|
@@ -332,7 +313,7 @@ inline bool isHeapAllocExtFunViaArg(const SVFFunction* fun)
|
|
|
332
313
|
|
|
333
314
|
/// Get the position of argument that holds an allocated heap object.
|
|
334
315
|
//@{
|
|
335
|
-
inline
|
|
316
|
+
inline u32_t getHeapAllocHoldingArgPosition(const SVFFunction* fun)
|
|
336
317
|
{
|
|
337
318
|
return ExtAPI::getExtAPI()->get_alloc_arg_pos(fun);
|
|
338
319
|
}
|
|
@@ -404,25 +385,13 @@ inline const SVFValue* getForkedFun(const CallICFGNode *inst)
|
|
|
404
385
|
//@}
|
|
405
386
|
|
|
406
387
|
|
|
407
|
-
|
|
408
|
-
{
|
|
409
|
-
return isExtCall(getCallee(cs));
|
|
410
|
-
}
|
|
388
|
+
bool isExtCall(const CallICFGNode* cs);
|
|
411
389
|
|
|
412
390
|
bool isExtCall(const ICFGNode* node);
|
|
413
391
|
|
|
414
|
-
|
|
415
|
-
{
|
|
416
|
-
return isHeapAllocExtFunViaArg(getCallee(cs));
|
|
417
|
-
}
|
|
392
|
+
bool isHeapAllocExtCallViaArg(const CallICFGNode* cs);
|
|
418
393
|
|
|
419
|
-
|
|
420
|
-
{
|
|
421
|
-
if(const SVFCallInst* call = SVFUtil::dyn_cast<SVFCallInst>(inst))
|
|
422
|
-
return isHeapAllocExtFunViaArg(call->getCalledFunction());
|
|
423
|
-
else
|
|
424
|
-
return false;
|
|
425
|
-
}
|
|
394
|
+
bool isHeapAllocExtCallViaArg(const SVFInstruction *inst);
|
|
426
395
|
|
|
427
396
|
bool isHeapAllocExtCallViaRet(const SVFInstruction *inst);
|
|
428
397
|
|
|
@@ -438,10 +407,7 @@ inline bool isHeapAllocExtCall(const SVFInstruction *inst)
|
|
|
438
407
|
|
|
439
408
|
//@}
|
|
440
409
|
|
|
441
|
-
|
|
442
|
-
{
|
|
443
|
-
return getHeapAllocHoldingArgPosition(getCallee(cs));
|
|
444
|
-
}
|
|
410
|
+
u32_t getHeapAllocHoldingArgPosition(const CallICFGNode* cs);
|
|
445
411
|
//@}
|
|
446
412
|
|
|
447
413
|
bool isReallocExtCall(const CallICFGNode* cs);
|
|
@@ -449,7 +415,7 @@ bool isReallocExtCall(const CallICFGNode* cs);
|
|
|
449
415
|
|
|
450
416
|
/// Return true if this is a thread creation call
|
|
451
417
|
///@{
|
|
452
|
-
inline bool isThreadForkCall(const
|
|
418
|
+
inline bool isThreadForkCall(const CallICFGNode *inst)
|
|
453
419
|
{
|
|
454
420
|
return ThreadAPI::getThreadAPI()->isTDFork(inst);
|
|
455
421
|
}
|
|
@@ -457,7 +423,7 @@ inline bool isThreadForkCall(const ICFGNode *inst)
|
|
|
457
423
|
|
|
458
424
|
/// Return true if this is a thread join call
|
|
459
425
|
///@{
|
|
460
|
-
inline bool isThreadJoinCall(const
|
|
426
|
+
inline bool isThreadJoinCall(const CallICFGNode* cs)
|
|
461
427
|
{
|
|
462
428
|
return ThreadAPI::getThreadAPI()->isTDJoin(cs);
|
|
463
429
|
}
|
|
@@ -465,7 +431,7 @@ inline bool isThreadJoinCall(const ICFGNode* cs)
|
|
|
465
431
|
|
|
466
432
|
/// Return true if this is a thread exit call
|
|
467
433
|
///@{
|
|
468
|
-
inline bool isThreadExitCall(const
|
|
434
|
+
inline bool isThreadExitCall(const CallICFGNode* cs)
|
|
469
435
|
{
|
|
470
436
|
return ThreadAPI::getThreadAPI()->isTDExit(cs);
|
|
471
437
|
}
|
|
@@ -473,7 +439,7 @@ inline bool isThreadExitCall(const ICFGNode* cs)
|
|
|
473
439
|
|
|
474
440
|
/// Return true if this is a lock acquire call
|
|
475
441
|
///@{
|
|
476
|
-
inline bool isLockAquireCall(const
|
|
442
|
+
inline bool isLockAquireCall(const CallICFGNode* cs)
|
|
477
443
|
{
|
|
478
444
|
return ThreadAPI::getThreadAPI()->isTDAcquire(cs);
|
|
479
445
|
}
|
|
@@ -481,7 +447,7 @@ inline bool isLockAquireCall(const ICFGNode* cs)
|
|
|
481
447
|
|
|
482
448
|
/// Return true if this is a lock acquire call
|
|
483
449
|
///@{
|
|
484
|
-
inline bool isLockReleaseCall(const
|
|
450
|
+
inline bool isLockReleaseCall(const CallICFGNode* cs)
|
|
485
451
|
{
|
|
486
452
|
return ThreadAPI::getThreadAPI()->isTDRelease(cs);
|
|
487
453
|
}
|
|
@@ -489,7 +455,7 @@ inline bool isLockReleaseCall(const ICFGNode* cs)
|
|
|
489
455
|
|
|
490
456
|
/// Return true if this is a barrier wait call
|
|
491
457
|
//@{
|
|
492
|
-
inline bool isBarrierWaitCall(const
|
|
458
|
+
inline bool isBarrierWaitCall(const CallICFGNode* cs)
|
|
493
459
|
{
|
|
494
460
|
return ThreadAPI::getThreadAPI()->isTDBarWait(cs);
|
|
495
461
|
}
|
|
@@ -504,10 +470,7 @@ inline const SVFValue* getActualParmAtForkSite(const CallICFGNode* cs)
|
|
|
504
470
|
//@}
|
|
505
471
|
|
|
506
472
|
|
|
507
|
-
|
|
508
|
-
{
|
|
509
|
-
return isProgExitFunction(getCallee(cs));
|
|
510
|
-
}
|
|
473
|
+
bool isProgExitCall(const CallICFGNode* cs);
|
|
511
474
|
|
|
512
475
|
|
|
513
476
|
template<typename T>
|
|
@@ -119,19 +119,6 @@ public:
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
/// Return the callee/callsite/func
|
|
123
|
-
//@{
|
|
124
|
-
const SVFFunction* getCallee(const ICFGNode *inst) const;
|
|
125
|
-
//@}
|
|
126
|
-
|
|
127
|
-
/// Return true if this call create a new thread
|
|
128
|
-
//@{
|
|
129
|
-
inline bool isTDFork(const ICFGNode *inst) const
|
|
130
|
-
{
|
|
131
|
-
return getType(getCallee(inst)) == TD_FORK;
|
|
132
|
-
}
|
|
133
|
-
//@}
|
|
134
|
-
|
|
135
122
|
/// Return arguments/attributes of pthread_create / hare_parallel_for
|
|
136
123
|
//@{
|
|
137
124
|
/// Return the first argument of the call,
|
|
@@ -146,12 +133,14 @@ public:
|
|
|
146
133
|
const SVFValue* getActualParmAtForkSite(const CallICFGNode *inst) const;
|
|
147
134
|
//@}
|
|
148
135
|
|
|
136
|
+
/// Return true if this call create a new thread
|
|
137
|
+
//@{
|
|
138
|
+
bool isTDFork(const CallICFGNode *inst) const;
|
|
139
|
+
//@}
|
|
140
|
+
|
|
149
141
|
/// Return true if this call wait for a worker thread
|
|
150
142
|
//@{
|
|
151
|
-
|
|
152
|
-
{
|
|
153
|
-
return getType(getCallee(inst)) == TD_JOIN;
|
|
154
|
-
}
|
|
143
|
+
bool isTDJoin(const CallICFGNode *inst) const;
|
|
155
144
|
//@}
|
|
156
145
|
|
|
157
146
|
/// Return arguments/attributes of pthread_join
|
|
@@ -167,26 +156,17 @@ public:
|
|
|
167
156
|
|
|
168
157
|
/// Return true if this call exits/terminate a thread
|
|
169
158
|
//@{
|
|
170
|
-
|
|
171
|
-
{
|
|
172
|
-
return getType(getCallee(inst)) == TD_EXIT;
|
|
173
|
-
}
|
|
159
|
+
bool isTDExit(const CallICFGNode *inst) const;
|
|
174
160
|
//@}
|
|
175
161
|
|
|
176
162
|
/// Return true if this call acquire a lock
|
|
177
163
|
//@{
|
|
178
|
-
|
|
179
|
-
{
|
|
180
|
-
return getType(getCallee(inst)) == TD_ACQUIRE;
|
|
181
|
-
}
|
|
164
|
+
bool isTDAcquire(const CallICFGNode* inst) const;
|
|
182
165
|
//@}
|
|
183
166
|
|
|
184
167
|
/// Return true if this call release a lock
|
|
185
168
|
//@{
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
return getType(getCallee(inst)) == TD_RELEASE;
|
|
189
|
-
}
|
|
169
|
+
bool isTDRelease(const CallICFGNode *inst) const;
|
|
190
170
|
//@}
|
|
191
171
|
|
|
192
172
|
/// Return lock value
|
|
@@ -197,10 +177,7 @@ public:
|
|
|
197
177
|
|
|
198
178
|
/// Return true if this call waits for a barrier
|
|
199
179
|
//@{
|
|
200
|
-
|
|
201
|
-
{
|
|
202
|
-
return getType(getCallee(inst)) == TD_BAR_WAIT;
|
|
203
|
-
}
|
|
180
|
+
bool isTDBarWait(const CallICFGNode *inst) const;
|
|
204
181
|
//@}
|
|
205
182
|
|
|
206
183
|
void performAPIStat(SVFModule* m);
|
|
@@ -94,8 +94,7 @@ void BufOverflowDetector::detect(AbstractState& as, const ICFGNode* node)
|
|
|
94
94
|
{
|
|
95
95
|
// Handle call nodes by checking for external API calls
|
|
96
96
|
const CallICFGNode* callNode = SVFUtil::cast<CallICFGNode>(node);
|
|
97
|
-
|
|
98
|
-
if (SVFUtil::isExtCall(callfun))
|
|
97
|
+
if (SVFUtil::isExtCall(callNode->getCalledFunction()))
|
|
99
98
|
{
|
|
100
99
|
detectExtAPI(as, callNode);
|
|
101
100
|
}
|
|
@@ -146,13 +145,12 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
|
|
|
146
145
|
const CallICFGNode* call)
|
|
147
146
|
{
|
|
148
147
|
SVFIR* svfir = PAG::getPAG();
|
|
149
|
-
|
|
150
|
-
assert(fun && "SVFFunction* is nullptr");
|
|
148
|
+
assert(call->getCalledFunction() && "SVFFunction* is nullptr");
|
|
151
149
|
|
|
152
150
|
AbstractInterpretation::ExtAPIType extType = AbstractInterpretation::UNCLASSIFIED;
|
|
153
151
|
|
|
154
152
|
// Determine the type of external memory API
|
|
155
|
-
for (const std::string &annotation :
|
|
153
|
+
for (const std::string &annotation : call->getCalledFunction()->getAnnotations())
|
|
156
154
|
{
|
|
157
155
|
if (annotation.find("MEMCPY") != std::string::npos)
|
|
158
156
|
extType = AbstractInterpretation::MEMCPY;
|
|
@@ -167,13 +165,13 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
|
|
|
167
165
|
// Apply buffer overflow checks based on the determined API type
|
|
168
166
|
if (extType == AbstractInterpretation::MEMCPY)
|
|
169
167
|
{
|
|
170
|
-
if (extAPIBufOverflowCheckRules.count(
|
|
168
|
+
if (extAPIBufOverflowCheckRules.count(call->getCalledFunction()->getName()) == 0)
|
|
171
169
|
{
|
|
172
|
-
SVFUtil::errs() << "Warning: " <<
|
|
170
|
+
SVFUtil::errs() << "Warning: " << call->getCalledFunction()->getName() << " is not in the rules, please implement it\n";
|
|
173
171
|
return;
|
|
174
172
|
}
|
|
175
173
|
std::vector<std::pair<u32_t, u32_t>> args =
|
|
176
|
-
extAPIBufOverflowCheckRules.at(
|
|
174
|
+
extAPIBufOverflowCheckRules.at(call->getCalledFunction()->getName());
|
|
177
175
|
for (auto arg : args)
|
|
178
176
|
{
|
|
179
177
|
IntervalValue offset = as[svfir->getValueNode(call->getArgument(arg.second))].getInterval() - IntervalValue(1);
|
|
@@ -186,13 +184,13 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
|
|
|
186
184
|
}
|
|
187
185
|
else if (extType == AbstractInterpretation::MEMSET)
|
|
188
186
|
{
|
|
189
|
-
if (extAPIBufOverflowCheckRules.count(
|
|
187
|
+
if (extAPIBufOverflowCheckRules.count(call->getCalledFunction()->getName()) == 0)
|
|
190
188
|
{
|
|
191
|
-
SVFUtil::errs() << "Warning: " <<
|
|
189
|
+
SVFUtil::errs() << "Warning: " << call->getCalledFunction()->getName() << " is not in the rules, please implement it\n";
|
|
192
190
|
return;
|
|
193
191
|
}
|
|
194
192
|
std::vector<std::pair<u32_t, u32_t>> args =
|
|
195
|
-
extAPIBufOverflowCheckRules.at(
|
|
193
|
+
extAPIBufOverflowCheckRules.at(call->getCalledFunction()->getName());
|
|
196
194
|
for (auto arg : args)
|
|
197
195
|
{
|
|
198
196
|
IntervalValue offset = as[svfir->getValueNode(call->getArgument(arg.second))].getInterval() - IntervalValue(1);
|
|
@@ -340,12 +338,11 @@ bool BufOverflowDetector::detectStrcpy(AbstractState& as, const CallICFGNode *ca
|
|
|
340
338
|
bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *call)
|
|
341
339
|
{
|
|
342
340
|
SVFIR* svfir = PAG::getPAG();
|
|
343
|
-
const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite());
|
|
344
341
|
|
|
345
342
|
const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
|
|
346
343
|
const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
|
|
347
344
|
|
|
348
|
-
if (std::find(strcatGroup.begin(), strcatGroup.end(),
|
|
345
|
+
if (std::find(strcatGroup.begin(), strcatGroup.end(), call->getCalledFunction()->getName()) != strcatGroup.end())
|
|
349
346
|
{
|
|
350
347
|
const SVFValue* arg0Val = call->getArgument(0);
|
|
351
348
|
const SVFValue* arg1Val = call->getArgument(1);
|
|
@@ -354,7 +351,7 @@ bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *ca
|
|
|
354
351
|
IntervalValue totalLen = strLen0 + strLen1;
|
|
355
352
|
return canSafelyAccessMemory(as, arg0Val, totalLen);
|
|
356
353
|
}
|
|
357
|
-
else if (std::find(strncatGroup.begin(), strncatGroup.end(),
|
|
354
|
+
else if (std::find(strncatGroup.begin(), strncatGroup.end(), call->getCalledFunction()->getName()) != strncatGroup.end())
|
|
358
355
|
{
|
|
359
356
|
const SVFValue* arg0Val = call->getArgument(0);
|
|
360
357
|
const SVFValue* arg2Val = call->getArgument(2);
|