Static Value-Flow Analysis
DoubleFreeChecker.cpp
Go to the documentation of this file.
1 //===- DoubleFreeChecker.cpp -- Detecting double-free errors------------------//
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  * DoubleFreeChecker.cpp
25  *
26  * Created on: Apr 24, 2014
27  * Author: Yulei Sui
28  */
29 
31 #include "Util/SVFUtil.h"
32 #include "Util/Options.h"
33 
34 using namespace SVF;
35 using namespace SVFUtil;
36 
38 {
39 
40  if(slice->isSatisfiableForPairs() == false)
41  {
42  GenericBug::EventStack eventStack;
43  slice->evalFinalCond2Event(eventStack);
44  eventStack.push_back(
45  SVFBugEvent(SVFBugEvent::SourceInst, getSrcCSID(slice->getSource())));
46  report.addSaberBug(GenericBug::DOUBLEFREE, eventStack);
47  }
49  testsValidation(slice);
50 }
51 
52 
53 
55 {
56  const SVFGNode* source = slice->getSource();
57  const CallICFGNode* cs = getSrcCSID(source);
58  const SVFFunction* fun = cs->getCalledFunction();
59  if(fun==nullptr)
60  return;
61  validateSuccessTests(slice,fun);
62  validateExpectedFailureTests(slice,fun);
63 }
64 
66 {
67  const SVFGNode* source = slice->getSource();
68  const CallICFGNode* cs = getSrcCSID(source);
69 
70  bool success = false;
71 
72  if(fun->getName() == "SAFEMALLOC")
73  {
74  if(slice->isSatisfiableForPairs() == true)
75  success = true;
76  }
77  else if(fun->getName() == "DOUBLEFREEMALLOC")
78  {
79  if(slice->isSatisfiableForPairs() == false)
80  success = true;
81  }
82  else if(fun->getName() == "DOUBLEFREEMALLOCFN" || fun->getName() == "SAFEMALLOCFP")
83  {
84  return;
85  }
86  else
87  {
88  writeWrnMsg("\t can not validate, check function not found, please put it at the right place!!");
89  return;
90  }
91 
92  std::string funName = source->getFun()->getName();
93 
94  if (success)
95  {
96  outs() << sucMsg("\t SUCCESS :") << funName << " check <src id:" << source->getId()
97  << ", cs id:" << (getSrcCSID(source))->valueOnlyToString() << "> at ("
98  << cs->getSourceLoc() << ")\n";
99  outs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
100  }
101  else
102  {
103  SVFUtil::errs() << errMsg("\t FAILURE :") << funName << " check <src id:" << source->getId()
104  << ", cs id:" << (getSrcCSID(source))->valueOnlyToString() << "> at ("
105  << cs->getSourceLoc() << ")\n";
106  SVFUtil::errs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
107  assert(false && "test case failed!");
108  }
109 }
110 
112 {
113  const SVFGNode* source = slice->getSource();
114  const CallICFGNode* cs = getSrcCSID(source);
115 
116  bool expectedFailure = false;
118  if(fun->getName() == "DOUBLEFREEMALLOCFN")
119  {
120  if(slice->isSatisfiableForPairs() == true)
121  expectedFailure = true;
122  }
123  else if(fun->getName() == "SAFEMALLOCFP")
124  {
125  if(slice->isSatisfiableForPairs() == false)
126  expectedFailure = true;
127  }
128  else if(fun->getName() == "SAFEMALLOC" || fun->getName() == "DOUBLEFREEMALLOC")
129  {
130  return;
131  }
132  else
133  {
134  writeWrnMsg("\t can not validate, check function not found, please put it at the right place!!");
135  return;
136  }
137 
138  std::string funName = source->getFun()->getName();
139 
140  if (expectedFailure)
141  {
142  outs() << sucMsg("\t EXPECTED-FAILURE :") << funName << " check <src id:" << source->getId()
143  << ", cs id:" << (getSrcCSID(source))->valueOnlyToString() << "> at ("
144  << cs->getSourceLoc() << ")\n";
145  outs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
146  }
147  else
148  {
149  SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << funName
150  << " check <src id:" << source->getId()
151  << ", cs id:" << (getSrcCSID(source))->valueOnlyToString() << "> at ("
152  << cs->getSourceLoc() << ")\n";
153  SVFUtil::errs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
154  assert(false && "test case failed!");
155  }
156 }
const char *const string
Definition: cJSON.h:172
const SVFFunction * getCalledFunction() const
Definition: ICFGNode.h:518
const std::string getSourceLoc() const override
Definition: ICFGNode.h:588
void testsValidation(ProgSlice *slice)
Validate test cases for regression test purpose.
void validateSuccessTests(ProgSlice *slice, const SVFFunction *fun)
void validateExpectedFailureTests(ProgSlice *slice, const SVFFunction *fun)
void reportBug(ProgSlice *slice) override
Report file/close bugs.
std::vector< SVFBugEvent > EventStack
Definition: SVFBugReport.h:83
static const Option< bool > ValidateTests
Definition: Options.h:169
void evalFinalCond2Event(GenericBug::EventStack &eventStack) const
Add final condition to eventStack.
Definition: ProgSlice.cpp:196
bool isSatisfiableForPairs()
Definition: ProgSlice.cpp:158
const SVFGNode * getSource() const
root and sink operations
Definition: ProgSlice.h:123
std::string evalFinalCond() const
Evaluate final condition.
Definition: ProgSlice.cpp:220
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
const std::string & getName() const
Definition: SVFValue.h:243
virtual const SVFFunction * getFun() const
Get the function of this SVFGNode.
Definition: VFGNode.h:79
std::string sucMsg(const std::string &msg)
Returns successful message by converting a string into green string output.
Definition: SVFUtil.cpp:53
std::string errMsg(const std::string &msg)
Print error message by converting a string into red string output.
Definition: SVFUtil.cpp:76
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition: SVFUtil.cpp:66
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68