svf-tools 1.0.1088 → 1.0.1090

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.1088",
3
+ "version": "1.0.1090",
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": {
@@ -161,6 +161,7 @@ public:
161
161
 
162
162
  /**
163
163
  * @brief Updates the offset of a GEP object from its base.
164
+ * @param as Reference to the abstract state.
164
165
  * @param gepAddrs Address value for GEP.
165
166
  * @param objAddrs Address value for the object.
166
167
  * @param offset The interval value of the offset.
@@ -358,6 +359,7 @@ public:
358
359
  */
359
360
  bool isUninit(AbstractValue v)
360
361
  {
362
+ // uninitialized value has neither interval value nor address value
361
363
  bool is = v.getAddrs().isBottom() && v.getInterval().isBottom();
362
364
  return is;
363
365
  }
@@ -63,12 +63,14 @@ void BufOverflowDetector::detect(AbstractState& as, const ICFGNode* node)
63
63
  {
64
64
  NodeID objId = as.getIDFromAddr(addr);
65
65
  u32_t size = 0;
66
+ // like `int arr[10]` which has constant size before runtime
66
67
  if (svfir->getBaseObject(objId)->isConstantByteSize())
67
68
  {
68
69
  size = svfir->getBaseObject(objId)->getByteSizeOfObj();
69
70
  }
70
71
  else
71
72
  {
73
+ // like `int len = ***; int arr[len]`, whose size can only be known in runtime
72
74
  const ICFGNode* addrNode = svfir->getBaseObject(objId)->getICFGNode();
73
75
  for (const SVFStmt* stmt2 : addrNode->getSVFStmts())
74
76
  {
@@ -146,8 +148,7 @@ void BufOverflowDetector::handleStubFunctions(const SVF::CallICFGNode* callNode)
146
148
  }
147
149
  else if (funcName == "UNSAFE_BUFACCESS")
148
150
  {
149
- // handle other stub functions
150
- //void UNSAFE_BUFACCESS(void* data, int size);
151
+ // void UNSAFE_BUFACCESS(void* data, int size);
151
152
  AbstractInterpretation::getAEInstance().checkpoints.erase(callNode);
152
153
  if (callNode->arg_size() < 2) return;
153
154
  AbstractState&as = AbstractInterpretation::getAEInstance().getAbsStateFromTrace(callNode);
@@ -313,14 +314,16 @@ IntervalValue BufOverflowDetector::getAccessOffset(SVF::AbstractState& as, SVF::
313
314
  SVFIR* svfir = PAG::getPAG();
314
315
  auto obj = svfir->getGNode(objId);
315
316
 
316
- // if the object is a BaseObjVar, return the byte offset directly
317
317
  if (SVFUtil::isa<BaseObjVar>(obj))
318
318
  {
319
+ // if the object is a BaseObjVar, return the byte offset directly
320
+ // like `int arr[10]; arr[5] = 1;` arr is the baseObjVar
319
321
  return as.getByteOffset(gep);
320
322
  }
321
323
  else if (SVFUtil::isa<GepObjVar>(obj))
322
324
  {
323
325
  // if the object is a GepObjVar, return the offset from the base object
326
+ // like `int arr[10]; int* p=arr+5; p[3] = 1`, p is the GepObjVar from arr.
324
327
  return getGepObjOffsetFromBase(SVFUtil::cast<GepObjVar>(obj)) + as.getByteOffset(gep);
325
328
  }
326
329
  else
@@ -348,9 +351,12 @@ void BufOverflowDetector::updateGepObjOffsetFromBase(AbstractState& as, SVF::Add
348
351
  {
349
352
  NodeID objId = as.getIDFromAddr(objAddr);
350
353
  auto obj = svfir->getGNode(objId);
351
- // if the object is a BaseObjVar, add the offset directly
354
+
352
355
  if (SVFUtil::isa<BaseObjVar>(obj))
353
356
  {
357
+ // if the object is a BaseObjVar, add the offset directly
358
+ // like llvm bc `arr = alloc i8 12; p = gep arr, 4`
359
+ // we write key value pair {gep, 4}
354
360
  for (const auto& gepAddr : gepAddrs)
355
361
  {
356
362
  NodeID gepObj = as.getIDFromAddr(gepAddr);
@@ -367,6 +373,8 @@ void BufOverflowDetector::updateGepObjOffsetFromBase(AbstractState& as, SVF::Add
367
373
  else if (SVFUtil::isa<GepObjVar>(obj))
368
374
  {
369
375
  // if the object is a GepObjVar, add the offset from the base object
376
+ // like llvm bc `arr = alloc i8 12; p = gep arr, 4; q = gep p, 6`
377
+ // we retreive {p, 4} and write {q, 4+6}
370
378
  const GepObjVar* objVar = SVFUtil::cast<GepObjVar>(obj);
371
379
  for (const auto& gepAddr : gepAddrs)
372
380
  {
@@ -518,6 +526,8 @@ void NullptrDerefDetector::detect(AbstractState& as, const ICFGNode* node)
518
526
  {
519
527
  if (SVFUtil::isa<CallICFGNode>(node))
520
528
  {
529
+ // external API like memset(*dst, elem, sz)
530
+ // we check if it's external api and check the corrisponding index
521
531
  const CallICFGNode* callNode = SVFUtil::cast<CallICFGNode>(node);
522
532
  if (SVFUtil::isExtCall(callNode->getCalledFunction()))
523
533
  {
@@ -530,6 +540,8 @@ void NullptrDerefDetector::detect(AbstractState& as, const ICFGNode* node)
530
540
  {
531
541
  if (const GepStmt* gep = SVFUtil::dyn_cast<GepStmt>(stmt))
532
542
  {
543
+ // like llvm bitcode `p = gep p, idx`
544
+ // we check rhs p's all address are valid mem
533
545
  SVFVar* rhs = gep->getRHSVar();
534
546
  if (!canSafelyDerefPtr(as, rhs))
535
547
  {
@@ -539,6 +551,8 @@ void NullptrDerefDetector::detect(AbstractState& as, const ICFGNode* node)
539
551
  }
540
552
  else if (const LoadStmt* load = SVFUtil::dyn_cast<LoadStmt>(stmt))
541
553
  {
554
+ // like llvm bitcode `p = load q`
555
+ // we check lhs p's all address are valid mem
542
556
  SVFVar* lhs = load->getLHSVar();
543
557
  if ( !canSafelyDerefPtr(as, lhs))
544
558
  {
@@ -665,16 +679,19 @@ bool NullptrDerefDetector::canSafelyDerefPtr(AbstractState& as, const SVFVar* va
665
679
  {
666
680
  NodeID value_id = value->getId();
667
681
  AbstractValue AbsVal = as[value_id];
682
+ // uninit value cannot be dereferenced, return unsafe
668
683
  if (isUninit(AbsVal)) return false;
684
+ // Interval Value (non-addr) is not the checkpoint of nullptr dereference, return safe
669
685
  if (!AbsVal.isAddr()) return true;
670
686
  for (const auto &addr: AbsVal.getAddrs())
671
687
  {
688
+ // if the addr itself is invalid mem, report unsafe
672
689
  if (AbstractState::isInvalidMem(addr))
673
- {
674
690
  return false;
675
- }
691
+ // if nullptr is detected, return unsafe
676
692
  else if (AbstractState::isNullMem(addr))
677
693
  return false;
694
+ // if addr is labeled freed mem, report unsafe
678
695
  else if (as.isFreedMem(addr))
679
696
  return false;
680
697
  }