svf-lib 1.0.1501 → 1.0.1503
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/SVF-linux/Release-build/svf/libSvfCore.a +0 -0
- package/SVF-linux/Release-build/svf-llvm/libSvfLLVM.a +0 -0
- package/SVF-linux/svf/include/SABER/FileChecker.h +0 -2
- package/SVF-linux/svf/include/SABER/LeakChecker.h +0 -2
- package/SVF-linux/svf/include/SABER/ProgSlice.h +3 -0
- package/SVF-linux/svf/include/SABER/SrcSnkDDA.h +3 -2
- package/SVF-linux/svf/include/Util/SVFBugReport.h +424 -0
- package/SVF-osx/Release-build/svf/libSvfCore.a +0 -0
- package/SVF-osx/Release-build/svf-llvm/libSvfLLVM.a +0 -0
- package/SVF-osx/svf/include/Util/SVFBugReport.h +24 -86
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
#include "Util/WorkList.h"
|
|
42
42
|
#include "Graphs/SVFG.h"
|
|
43
43
|
#include "Util/DPItem.h"
|
|
44
|
+
#include "Util/SVFBugReport.h"
|
|
44
45
|
|
|
45
46
|
namespace SVF
|
|
46
47
|
{
|
|
@@ -201,6 +202,8 @@ public:
|
|
|
201
202
|
}
|
|
202
203
|
/// Evaluate final condition
|
|
203
204
|
std::string evalFinalCond() const;
|
|
205
|
+
/// Add final condition to eventStack
|
|
206
|
+
void evalFinalCond2Event(GenericBug::EventStack &eventStack) const;
|
|
204
207
|
//@}
|
|
205
208
|
|
|
206
209
|
protected:
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
#ifndef SRCSNKANALYSIS_H_
|
|
38
38
|
#define SRCSNKANALYSIS_H_
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
#include "Util/GraphReachSolver.h"
|
|
42
40
|
#include "Graphs/SVFGOPT.h"
|
|
43
41
|
#include "SABER/ProgSlice.h"
|
|
44
42
|
#include "SABER/SaberSVFGBuilder.h"
|
|
43
|
+
#include "Util/GraphReachSolver.h"
|
|
44
|
+
#include "Util/SVFBugReport.h"
|
|
45
45
|
|
|
46
46
|
namespace SVF
|
|
47
47
|
{
|
|
@@ -77,6 +77,7 @@ protected:
|
|
|
77
77
|
SaberSVFGBuilder memSSA;
|
|
78
78
|
SVFG* svfg;
|
|
79
79
|
PTACallGraph* ptaCallGraph;
|
|
80
|
+
SVFBugReport report; /// Bug Reporter
|
|
80
81
|
|
|
81
82
|
public:
|
|
82
83
|
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
//===- SVFBugReport.h -- Base class for statistics---------------------------------//
|
|
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
|
+
// Created by JoelYang on 2023/4/19.
|
|
25
|
+
//
|
|
26
|
+
|
|
27
|
+
#ifndef SVF_BUGRECODER_H
|
|
28
|
+
#define SVF_BUGRECODER_H
|
|
29
|
+
|
|
30
|
+
#include <vector>
|
|
31
|
+
#include "SVFIR/SVFValue.h"
|
|
32
|
+
#include "SVFIR/SVFVariables.h"
|
|
33
|
+
#include "SVFIR/SVFStatements.h"
|
|
34
|
+
#include "Graphs/ICFGNode.h"
|
|
35
|
+
#include <string>
|
|
36
|
+
#include <map>
|
|
37
|
+
#include "Util/cJSON.h"
|
|
38
|
+
#include <set>
|
|
39
|
+
|
|
40
|
+
namespace SVF
|
|
41
|
+
{
|
|
42
|
+
|
|
43
|
+
/*!
|
|
44
|
+
* Bug Detector Recoder
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class GenericEvent
|
|
49
|
+
{
|
|
50
|
+
public:
|
|
51
|
+
enum EventType {Branch, Caller, CallSite, Loop, SourceInst};
|
|
52
|
+
|
|
53
|
+
protected:
|
|
54
|
+
EventType eventType;
|
|
55
|
+
|
|
56
|
+
public:
|
|
57
|
+
GenericEvent(EventType eventType): eventType(eventType) { };
|
|
58
|
+
virtual ~GenericEvent() = default;
|
|
59
|
+
|
|
60
|
+
inline EventType getEventType() const
|
|
61
|
+
{
|
|
62
|
+
return eventType;
|
|
63
|
+
}
|
|
64
|
+
virtual const std::string getEventDescription() const = 0;
|
|
65
|
+
virtual const std::string getFuncName() const = 0;
|
|
66
|
+
virtual const std::string getEventLoc() const = 0;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
class BranchEvent: public GenericEvent
|
|
70
|
+
{
|
|
71
|
+
/// branch statement and branch condition true or false
|
|
72
|
+
protected:
|
|
73
|
+
const SVFInstruction *branchInst;
|
|
74
|
+
bool branchSuccessFlg;
|
|
75
|
+
|
|
76
|
+
public:
|
|
77
|
+
BranchEvent(const SVFInstruction *branchInst, bool branchSuccessFlg):
|
|
78
|
+
GenericEvent(GenericEvent::Branch), branchInst(branchInst), branchSuccessFlg(branchSuccessFlg) { }
|
|
79
|
+
|
|
80
|
+
const std::string getEventDescription() const;
|
|
81
|
+
const std::string getFuncName() const;
|
|
82
|
+
const std::string getEventLoc() const;
|
|
83
|
+
|
|
84
|
+
/// ClassOf
|
|
85
|
+
static inline bool classof(const GenericEvent* event)
|
|
86
|
+
{
|
|
87
|
+
return event->getEventType() == GenericEvent::Branch;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
class CallSiteEvent: public GenericEvent
|
|
92
|
+
{
|
|
93
|
+
protected:
|
|
94
|
+
const CallICFGNode *callSite;
|
|
95
|
+
|
|
96
|
+
public:
|
|
97
|
+
CallSiteEvent(const CallICFGNode *callSite): GenericEvent(GenericEvent::CallSite), callSite(callSite) { }
|
|
98
|
+
const std::string getEventDescription() const;
|
|
99
|
+
const std::string getFuncName() const;
|
|
100
|
+
const std::string getEventLoc() const;
|
|
101
|
+
|
|
102
|
+
/// ClassOf
|
|
103
|
+
static inline bool classof(const GenericEvent* event)
|
|
104
|
+
{
|
|
105
|
+
return event->getEventType() == GenericEvent::CallSite;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
class SourceInstEvent : public GenericEvent
|
|
110
|
+
{
|
|
111
|
+
protected:
|
|
112
|
+
const SVFInstruction *sourceSVFInst;
|
|
113
|
+
|
|
114
|
+
public:
|
|
115
|
+
SourceInstEvent(const SVFInstruction *sourceSVFInst):
|
|
116
|
+
GenericEvent(GenericEvent::SourceInst), sourceSVFInst(sourceSVFInst) { }
|
|
117
|
+
|
|
118
|
+
const std::string getEventDescription() const;
|
|
119
|
+
const std::string getFuncName() const;
|
|
120
|
+
const std::string getEventLoc() const;
|
|
121
|
+
|
|
122
|
+
/// ClassOf
|
|
123
|
+
static inline bool classof(const GenericEvent* event)
|
|
124
|
+
{
|
|
125
|
+
return event->getEventType() == GenericEvent::SourceInst;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
class GenericBug
|
|
130
|
+
{
|
|
131
|
+
public:
|
|
132
|
+
typedef std::vector<const GenericEvent *> EventStack;
|
|
133
|
+
|
|
134
|
+
public:
|
|
135
|
+
enum BugType {FULLBUFOVERFLOW, PARTIALBUFOVERFLOW, NEVERFREE, PARTIALLEAK, DOUBLEFREE, FILENEVERCLOSE, FILEPARTIALCLOSE};
|
|
136
|
+
|
|
137
|
+
protected:
|
|
138
|
+
BugType bugType;
|
|
139
|
+
EventStack bugEventStack;
|
|
140
|
+
|
|
141
|
+
public:
|
|
142
|
+
/// note: should be initialized with a bugEventStack
|
|
143
|
+
GenericBug(BugType bugType, EventStack bugEventStack):
|
|
144
|
+
bugType(bugType), bugEventStack(bugEventStack)
|
|
145
|
+
{
|
|
146
|
+
assert(bugEventStack.size() != 0 && "bugEventStack should NOT be empty!");
|
|
147
|
+
}
|
|
148
|
+
virtual ~GenericBug() = default;
|
|
149
|
+
//GenericBug(const GenericBug &) = delete;
|
|
150
|
+
/// returns bug type
|
|
151
|
+
inline BugType getBugType() const
|
|
152
|
+
{
|
|
153
|
+
return bugType;
|
|
154
|
+
}
|
|
155
|
+
/// returns bug location as json format string
|
|
156
|
+
const std::string getLoc() const;
|
|
157
|
+
/// return bug source function name
|
|
158
|
+
const std::string getFuncName() const;
|
|
159
|
+
|
|
160
|
+
inline const EventStack& getEventStack() const
|
|
161
|
+
{
|
|
162
|
+
return bugEventStack;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
virtual cJSON *getBugDescription() const = 0;
|
|
166
|
+
virtual void printBugToTerminal() const = 0;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
class BufferOverflowBug: public GenericBug
|
|
170
|
+
{
|
|
171
|
+
protected:
|
|
172
|
+
s64_t allocLowerBound, allocUpperBound, accessLowerBound, accessUpperBound;
|
|
173
|
+
|
|
174
|
+
public:
|
|
175
|
+
BufferOverflowBug(GenericBug::BugType bugType, const EventStack &eventStack,
|
|
176
|
+
s64_t allocLowerBound, s64_t allocUpperBound,
|
|
177
|
+
s64_t accessLowerBound, s64_t accessUpperBound):
|
|
178
|
+
GenericBug(bugType, eventStack), allocLowerBound(allocLowerBound),
|
|
179
|
+
allocUpperBound(allocUpperBound), accessLowerBound(accessLowerBound),
|
|
180
|
+
accessUpperBound(accessUpperBound) { }
|
|
181
|
+
|
|
182
|
+
cJSON *getBugDescription() const;
|
|
183
|
+
void printBugToTerminal() const;
|
|
184
|
+
|
|
185
|
+
/// ClassOf
|
|
186
|
+
static inline bool classof(const GenericBug *bug)
|
|
187
|
+
{
|
|
188
|
+
return bug->getBugType() == GenericBug::PARTIALBUFOVERFLOW || bug->getBugType() == GenericBug::FULLBUFOVERFLOW;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
class FullBufferOverflowBug: public BufferOverflowBug
|
|
193
|
+
{
|
|
194
|
+
public:
|
|
195
|
+
FullBufferOverflowBug(const EventStack &eventStack,
|
|
196
|
+
s64_t allocLowerBound, s64_t allocUpperBound,
|
|
197
|
+
s64_t accessLowerBound, s64_t accessUpperBound):
|
|
198
|
+
BufferOverflowBug(GenericBug::FULLBUFOVERFLOW, eventStack, allocLowerBound,
|
|
199
|
+
allocUpperBound, accessLowerBound, accessUpperBound) { }
|
|
200
|
+
|
|
201
|
+
/// ClassOf
|
|
202
|
+
static inline bool classof(const GenericBug *bug)
|
|
203
|
+
{
|
|
204
|
+
return bug->getBugType() == GenericBug::FULLBUFOVERFLOW;
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
class PartialBufferOverflowBug: public BufferOverflowBug
|
|
209
|
+
{
|
|
210
|
+
public:
|
|
211
|
+
PartialBufferOverflowBug( const EventStack &eventStack,
|
|
212
|
+
s64_t allocLowerBound, s64_t allocUpperBound,
|
|
213
|
+
s64_t accessLowerBound, s64_t accessUpperBound):
|
|
214
|
+
BufferOverflowBug(GenericBug::PARTIALBUFOVERFLOW, eventStack, allocLowerBound,
|
|
215
|
+
allocUpperBound, accessLowerBound, accessUpperBound) { }
|
|
216
|
+
|
|
217
|
+
/// ClassOf
|
|
218
|
+
static inline bool classof(const GenericBug *bug)
|
|
219
|
+
{
|
|
220
|
+
return bug->getBugType() == GenericBug::PARTIALBUFOVERFLOW;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
class NeverFreeBug : public GenericBug
|
|
225
|
+
{
|
|
226
|
+
public:
|
|
227
|
+
NeverFreeBug(const EventStack &bugEventStack):
|
|
228
|
+
GenericBug(GenericBug::NEVERFREE, bugEventStack) { };
|
|
229
|
+
|
|
230
|
+
cJSON *getBugDescription() const;
|
|
231
|
+
void printBugToTerminal() const;
|
|
232
|
+
|
|
233
|
+
/// ClassOf
|
|
234
|
+
static inline bool classof(const GenericBug *bug)
|
|
235
|
+
{
|
|
236
|
+
return bug->getBugType() == GenericBug::NEVERFREE;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
class PartialLeakBug : public GenericBug
|
|
241
|
+
{
|
|
242
|
+
public:
|
|
243
|
+
PartialLeakBug(const EventStack &bugEventStack):
|
|
244
|
+
GenericBug(GenericBug::PARTIALLEAK, bugEventStack) { }
|
|
245
|
+
|
|
246
|
+
cJSON *getBugDescription() const;
|
|
247
|
+
void printBugToTerminal() const;
|
|
248
|
+
|
|
249
|
+
/// ClassOf
|
|
250
|
+
static inline bool classof(const GenericBug *bug)
|
|
251
|
+
{
|
|
252
|
+
return bug->getBugType() == GenericBug::PARTIALLEAK;
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
class DoubleFreeBug : public GenericBug
|
|
257
|
+
{
|
|
258
|
+
public:
|
|
259
|
+
DoubleFreeBug(const EventStack &bugEventStack):
|
|
260
|
+
GenericBug(GenericBug::PARTIALLEAK, bugEventStack) { }
|
|
261
|
+
|
|
262
|
+
cJSON *getBugDescription() const;
|
|
263
|
+
void printBugToTerminal() const;
|
|
264
|
+
|
|
265
|
+
/// ClassOf
|
|
266
|
+
static inline bool classof(const GenericBug *bug)
|
|
267
|
+
{
|
|
268
|
+
return bug->getBugType() == GenericBug::DOUBLEFREE;
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
class FileNeverCloseBug : public GenericBug
|
|
273
|
+
{
|
|
274
|
+
public:
|
|
275
|
+
FileNeverCloseBug(const EventStack &bugEventStack):
|
|
276
|
+
GenericBug(GenericBug::NEVERFREE, bugEventStack) { };
|
|
277
|
+
|
|
278
|
+
cJSON *getBugDescription() const;
|
|
279
|
+
void printBugToTerminal() const;
|
|
280
|
+
|
|
281
|
+
/// ClassOf
|
|
282
|
+
static inline bool classof(const GenericBug *bug)
|
|
283
|
+
{
|
|
284
|
+
return bug->getBugType() == GenericBug::FILENEVERCLOSE;
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
class FilePartialCloseBug : public GenericBug
|
|
289
|
+
{
|
|
290
|
+
public:
|
|
291
|
+
FilePartialCloseBug(const EventStack &bugEventStack):
|
|
292
|
+
GenericBug(GenericBug::PARTIALLEAK, bugEventStack) { }
|
|
293
|
+
|
|
294
|
+
cJSON *getBugDescription() const;
|
|
295
|
+
void printBugToTerminal() const;
|
|
296
|
+
|
|
297
|
+
/// ClassOf
|
|
298
|
+
static inline bool classof(const GenericBug *bug)
|
|
299
|
+
{
|
|
300
|
+
return bug->getBugType() == GenericBug::FILEPARTIALCLOSE;
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
class SVFBugReport
|
|
305
|
+
{
|
|
306
|
+
public:
|
|
307
|
+
SVFBugReport() = default;
|
|
308
|
+
~SVFBugReport();
|
|
309
|
+
typedef SVF::Set<const GenericBug *> BugSet;
|
|
310
|
+
typedef SVF::Set<const GenericEvent *> EventSet;
|
|
311
|
+
|
|
312
|
+
protected:
|
|
313
|
+
BugSet bugSet; // maintain bugs
|
|
314
|
+
EventSet eventSet;// maintain added events
|
|
315
|
+
|
|
316
|
+
public:
|
|
317
|
+
/*
|
|
318
|
+
* function: pass bug type (i.e., GenericBug::NEVERFREE) and eventStack as parameter,
|
|
319
|
+
* it will add the bug into bugQueue.
|
|
320
|
+
* usage: addSaberBug(GenericBug::NEVERFREE, eventStack)
|
|
321
|
+
*/
|
|
322
|
+
void addSaberBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack)
|
|
323
|
+
{
|
|
324
|
+
/// resign added events
|
|
325
|
+
for(auto eventPtr : eventStack)
|
|
326
|
+
{
|
|
327
|
+
eventSet.insert(eventPtr);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/// create and add the bug
|
|
331
|
+
GenericBug *newBug = nullptr;
|
|
332
|
+
switch(bugType)
|
|
333
|
+
{
|
|
334
|
+
case GenericBug::NEVERFREE:
|
|
335
|
+
{
|
|
336
|
+
newBug = new NeverFreeBug(eventStack);
|
|
337
|
+
bugSet.insert(newBug);
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
case GenericBug::PARTIALLEAK:
|
|
341
|
+
{
|
|
342
|
+
newBug = new PartialLeakBug(eventStack);
|
|
343
|
+
bugSet.insert(newBug);
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
case GenericBug::DOUBLEFREE:
|
|
347
|
+
{
|
|
348
|
+
newBug = new DoubleFreeBug(eventStack);
|
|
349
|
+
bugSet.insert(newBug);
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
case GenericBug::FILENEVERCLOSE:
|
|
353
|
+
{
|
|
354
|
+
newBug = new FileNeverCloseBug(eventStack);
|
|
355
|
+
bugSet.insert(newBug);
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
case GenericBug::FILEPARTIALCLOSE:
|
|
359
|
+
{
|
|
360
|
+
newBug = new FilePartialCloseBug(eventStack);
|
|
361
|
+
bugSet.insert(newBug);
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
default:
|
|
365
|
+
{
|
|
366
|
+
assert(false && "saber does NOT have this bug type!");
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// when add a bug, also print it to terminal
|
|
372
|
+
newBug->printBugToTerminal();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/*
|
|
376
|
+
* function: pass bug type (i.e., GenericBug::FULLBUFOVERFLOW) and eventStack as parameter,
|
|
377
|
+
* it will add the bug into bugQueue.
|
|
378
|
+
* usage: addAbsExecBug(GenericBug::FULLBUFOVERFLOW, eventStack, 0, 10, 11, 11)
|
|
379
|
+
*/
|
|
380
|
+
void addAbsExecBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack,
|
|
381
|
+
s64_t allocLowerBound, s64_t allocUpperBound, s64_t accessLowerBound, s64_t accessUpperBound)
|
|
382
|
+
{
|
|
383
|
+
/// resign added events
|
|
384
|
+
for(auto eventPtr : eventStack)
|
|
385
|
+
{
|
|
386
|
+
eventSet.insert(eventPtr);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/// add bugs
|
|
390
|
+
GenericBug *newBug = nullptr;
|
|
391
|
+
switch(bugType)
|
|
392
|
+
{
|
|
393
|
+
case GenericBug::FULLBUFOVERFLOW:
|
|
394
|
+
{
|
|
395
|
+
newBug = new FullBufferOverflowBug(eventStack, allocLowerBound, allocUpperBound, accessLowerBound, accessUpperBound);
|
|
396
|
+
bugSet.insert(newBug);
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
case GenericBug::PARTIALBUFOVERFLOW:
|
|
400
|
+
{
|
|
401
|
+
newBug = new PartialBufferOverflowBug(eventStack, allocLowerBound, allocUpperBound, accessLowerBound, accessUpperBound);
|
|
402
|
+
bugSet.insert(newBug);
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
default:
|
|
406
|
+
{
|
|
407
|
+
assert(false && "Abstract Execution does NOT hava his bug type!");
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// when add a bug, also print it to terminal
|
|
413
|
+
newBug->printBugToTerminal();
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/*
|
|
417
|
+
* function: pass file path, open the file and dump bug report as JSON format
|
|
418
|
+
* usage: dumpToFile("/path/to/file")
|
|
419
|
+
*/
|
|
420
|
+
void dumpToJsonFile(const std::string& filePath);
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
#endif
|
|
Binary file
|
|
Binary file
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
#include "Util/cJSON.h"
|
|
38
38
|
#include <set>
|
|
39
39
|
|
|
40
|
+
#define BRANCHFLAGMASK 0x00000010
|
|
41
|
+
#define EVENTTYPEMASK 0x0000000f
|
|
42
|
+
|
|
40
43
|
namespace SVF
|
|
41
44
|
{
|
|
42
45
|
|
|
@@ -45,102 +48,50 @@ namespace SVF
|
|
|
45
48
|
*/
|
|
46
49
|
|
|
47
50
|
|
|
48
|
-
class
|
|
49
|
-
{
|
|
50
|
-
public:
|
|
51
|
-
enum EventType {Branch, Caller, CallSite, Loop, SourceInst};
|
|
52
|
-
|
|
53
|
-
protected:
|
|
54
|
-
EventType eventType;
|
|
55
|
-
|
|
56
|
-
public:
|
|
57
|
-
GenericEvent(EventType eventType): eventType(eventType) { };
|
|
58
|
-
virtual ~GenericEvent() = default;
|
|
59
|
-
|
|
60
|
-
inline EventType getEventType() const
|
|
61
|
-
{
|
|
62
|
-
return eventType;
|
|
63
|
-
}
|
|
64
|
-
virtual const std::string getEventDescription() const = 0;
|
|
65
|
-
virtual const std::string getFuncName() const = 0;
|
|
66
|
-
virtual const std::string getEventLoc() const = 0;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
class BranchEvent: public GenericEvent
|
|
70
|
-
{
|
|
71
|
-
/// branch statement and branch condition true or false
|
|
72
|
-
protected:
|
|
73
|
-
const SVFInstruction *branchInst;
|
|
74
|
-
bool branchSuccessFlg;
|
|
75
|
-
|
|
76
|
-
public:
|
|
77
|
-
BranchEvent(const SVFInstruction *branchInst, bool branchSuccessFlg):
|
|
78
|
-
GenericEvent(GenericEvent::Branch), branchInst(branchInst), branchSuccessFlg(branchSuccessFlg) { }
|
|
79
|
-
|
|
80
|
-
const std::string getEventDescription() const;
|
|
81
|
-
const std::string getFuncName() const;
|
|
82
|
-
const std::string getEventLoc() const;
|
|
83
|
-
|
|
84
|
-
/// ClassOf
|
|
85
|
-
static inline bool classof(const GenericEvent* event)
|
|
86
|
-
{
|
|
87
|
-
return event->getEventType() == GenericEvent::Branch;
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
class CallSiteEvent: public GenericEvent
|
|
51
|
+
class BugEvent
|
|
92
52
|
{
|
|
93
|
-
protected:
|
|
94
|
-
const CallICFGNode *callSite;
|
|
95
|
-
|
|
96
53
|
public:
|
|
97
|
-
|
|
98
|
-
const std::string getEventDescription() const;
|
|
99
|
-
const std::string getFuncName() const;
|
|
100
|
-
const std::string getEventLoc() const;
|
|
101
|
-
|
|
102
|
-
/// ClassOf
|
|
103
|
-
static inline bool classof(const GenericEvent* event)
|
|
54
|
+
enum EventType
|
|
104
55
|
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
56
|
+
Branch = 0x1,
|
|
57
|
+
Caller = 0x2,
|
|
58
|
+
CallSite = 0x3,
|
|
59
|
+
Loop = 0x4,
|
|
60
|
+
SourceInst = 0x5
|
|
61
|
+
};
|
|
108
62
|
|
|
109
|
-
class SourceInstEvent : public GenericEvent
|
|
110
|
-
{
|
|
111
63
|
protected:
|
|
112
|
-
|
|
64
|
+
u32_t typeAndInfoFlag;
|
|
65
|
+
const SVFInstruction *eventInst;
|
|
113
66
|
|
|
114
67
|
public:
|
|
115
|
-
|
|
116
|
-
|
|
68
|
+
BugEvent(u32_t typeAndInfoFlag, const SVFInstruction *eventInst): typeAndInfoFlag(typeAndInfoFlag), eventInst(eventInst) { };
|
|
69
|
+
virtual ~BugEvent() = default;
|
|
117
70
|
|
|
118
|
-
|
|
119
|
-
const std::string getFuncName() const;
|
|
120
|
-
const std::string getEventLoc() const;
|
|
121
|
-
|
|
122
|
-
/// ClassOf
|
|
123
|
-
static inline bool classof(const GenericEvent* event)
|
|
71
|
+
inline u32_t getEventType() const
|
|
124
72
|
{
|
|
125
|
-
return
|
|
73
|
+
return typeAndInfoFlag & EVENTTYPEMASK;
|
|
126
74
|
}
|
|
75
|
+
virtual const std::string getEventDescription() const;
|
|
76
|
+
virtual const std::string getFuncName() const;
|
|
77
|
+
virtual const std::string getEventLoc() const;
|
|
127
78
|
};
|
|
128
79
|
|
|
129
80
|
class GenericBug
|
|
130
81
|
{
|
|
131
82
|
public:
|
|
132
|
-
typedef std::vector<
|
|
83
|
+
typedef std::vector<BugEvent> EventStack;
|
|
133
84
|
|
|
134
85
|
public:
|
|
135
86
|
enum BugType {FULLBUFOVERFLOW, PARTIALBUFOVERFLOW, NEVERFREE, PARTIALLEAK, DOUBLEFREE, FILENEVERCLOSE, FILEPARTIALCLOSE};
|
|
136
87
|
|
|
137
88
|
protected:
|
|
138
89
|
BugType bugType;
|
|
139
|
-
EventStack bugEventStack;
|
|
90
|
+
const EventStack bugEventStack;
|
|
140
91
|
|
|
141
92
|
public:
|
|
142
93
|
/// note: should be initialized with a bugEventStack
|
|
143
|
-
GenericBug(BugType bugType, EventStack bugEventStack):
|
|
94
|
+
GenericBug(BugType bugType, const EventStack &bugEventStack):
|
|
144
95
|
bugType(bugType), bugEventStack(bugEventStack)
|
|
145
96
|
{
|
|
146
97
|
assert(bugEventStack.size() != 0 && "bugEventStack should NOT be empty!");
|
|
@@ -307,13 +258,12 @@ public:
|
|
|
307
258
|
SVFBugReport() = default;
|
|
308
259
|
~SVFBugReport();
|
|
309
260
|
typedef SVF::Set<const GenericBug *> BugSet;
|
|
310
|
-
typedef SVF::Set<const GenericEvent *> EventSet;
|
|
311
261
|
|
|
312
262
|
protected:
|
|
313
263
|
BugSet bugSet; // maintain bugs
|
|
314
|
-
EventSet eventSet;// maintain added events
|
|
315
264
|
|
|
316
265
|
public:
|
|
266
|
+
|
|
317
267
|
/*
|
|
318
268
|
* function: pass bug type (i.e., GenericBug::NEVERFREE) and eventStack as parameter,
|
|
319
269
|
* it will add the bug into bugQueue.
|
|
@@ -321,12 +271,6 @@ public:
|
|
|
321
271
|
*/
|
|
322
272
|
void addSaberBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack)
|
|
323
273
|
{
|
|
324
|
-
/// resign added events
|
|
325
|
-
for(auto eventPtr : eventStack)
|
|
326
|
-
{
|
|
327
|
-
eventSet.insert(eventPtr);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
274
|
/// create and add the bug
|
|
331
275
|
GenericBug *newBug = nullptr;
|
|
332
276
|
switch(bugType)
|
|
@@ -380,12 +324,6 @@ public:
|
|
|
380
324
|
void addAbsExecBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack,
|
|
381
325
|
s64_t allocLowerBound, s64_t allocUpperBound, s64_t accessLowerBound, s64_t accessUpperBound)
|
|
382
326
|
{
|
|
383
|
-
/// resign added events
|
|
384
|
-
for(auto eventPtr : eventStack)
|
|
385
|
-
{
|
|
386
|
-
eventSet.insert(eventPtr);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
327
|
/// add bugs
|
|
390
328
|
GenericBug *newBug = nullptr;
|
|
391
329
|
switch(bugType)
|