-
Notifications
You must be signed in to change notification settings - Fork 436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add SVFBugRecoder and modify source loc format #1067
Changes from 2 commits
66dae8e
5332504
a66aca2
5a715b4
236c6ce
a4cb99f
c2d62b9
c138efb
4d1cfd7
a39e7ad
21e8041
1c9a83b
5eb7db8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,12 +64,12 @@ class GenericEvent{ | |
class BranchEvent: public GenericEvent{ | ||
/// branch statement and branch condition true or false | ||
protected: | ||
const BranchStmt *branchStmt; | ||
bool branchCondition; | ||
const SVFStmt *branchStmt; | ||
bool branchSuccessFlg; | ||
|
||
public: | ||
BranchEvent(const BranchStmt *branchStmt, bool branchCondition): | ||
GenericEvent(GenericEvent::Branch), branchStmt(branchStmt), branchCondition(branchCondition){ } | ||
BranchEvent(const SVFStmt *branchStmt, bool branchSuccessFlg): | ||
GenericEvent(GenericEvent::Branch), branchStmt(branchStmt), branchSuccessFlg(branchSuccessFlg){ } | ||
|
||
const std::string getEventDescription() const; | ||
const std::string getFuncName() const; | ||
|
@@ -120,7 +120,7 @@ class SourceInstructionEvent: public GenericEvent{ | |
|
||
class GenericBug{ | ||
public: | ||
typedef std::vector<GenericEvent *> EventStack; | ||
typedef std::vector<const GenericEvent *> EventStack; | ||
|
||
public: | ||
enum BugType{FULLBUFOVERFLOW, PARTIALBUFOVERFLOW, NEVERFREE, PARTIALLEAK, DOUBLEFREE, FILENEVERCLOSE, FILEPARTIALCLOSE}; | ||
|
@@ -137,7 +137,7 @@ class GenericBug{ | |
assert(bugEventStack.size() != 0 && "bugEventStack should NOT be empty!"); | ||
} | ||
virtual ~GenericBug(); | ||
|
||
//GenericBug(const GenericBug &) = delete; | ||
/// returns bug type | ||
inline BugType getBugType() const { return bugType; } | ||
/// returns bug location as json format string | ||
|
@@ -147,8 +147,8 @@ class GenericBug{ | |
|
||
inline const EventStack& getEventStack() const { return bugEventStack; } | ||
|
||
virtual cJSON *getBugDescription() = 0; | ||
virtual void printBugToTerminal() = 0; | ||
virtual cJSON *getBugDescription() const = 0; | ||
virtual void printBugToTerminal() const = 0; | ||
}; | ||
|
||
class BufferOverflowBug: public GenericBug{ | ||
|
@@ -163,8 +163,8 @@ class BufferOverflowBug: public GenericBug{ | |
allocUpperBound(allocUpperBound), accessLowerBound(accessLowerBound), | ||
accessUpperBound(accessUpperBound){ } | ||
|
||
cJSON *getBugDescription(); | ||
void printBugToTerminal(); | ||
cJSON *getBugDescription() const; | ||
void printBugToTerminal() const; | ||
|
||
/// ClassOf | ||
static inline bool classof(const GenericBug *bug) | ||
|
@@ -208,8 +208,8 @@ class NeverFreeBug : public GenericBug{ | |
NeverFreeBug(const EventStack &bugEventStack): | ||
GenericBug(GenericBug::NEVERFREE, bugEventStack){ }; | ||
|
||
cJSON *getBugDescription(); | ||
void printBugToTerminal(); | ||
cJSON *getBugDescription() const; | ||
void printBugToTerminal() const; | ||
|
||
/// ClassOf | ||
static inline bool classof(const GenericBug *bug) | ||
|
@@ -219,15 +219,12 @@ class NeverFreeBug : public GenericBug{ | |
}; | ||
|
||
class PartialLeakBug : public GenericBug{ | ||
protected: | ||
Set<std::string> conditionalFreePath; | ||
|
||
public: | ||
PartialLeakBug(const EventStack &bugEventStack, Set<std::string> conditionalFreePath): | ||
GenericBug(GenericBug::PARTIALLEAK, bugEventStack), conditionalFreePath(conditionalFreePath){ } | ||
PartialLeakBug(const EventStack &bugEventStack): | ||
GenericBug(GenericBug::PARTIALLEAK, bugEventStack){ } | ||
|
||
cJSON *getBugDescription(); | ||
void printBugToTerminal(); | ||
cJSON *getBugDescription() const; | ||
void printBugToTerminal() const; | ||
|
||
/// ClassOf | ||
static inline bool classof(const GenericBug *bug) | ||
|
@@ -237,15 +234,12 @@ class PartialLeakBug : public GenericBug{ | |
}; | ||
|
||
class DoubleFreeBug : public GenericBug{ | ||
protected: | ||
Set<std::string> doubleFreePath; | ||
|
||
public: | ||
DoubleFreeBug(const EventStack &bugEventStack, Set<std::string> doubleFreePath): | ||
GenericBug(GenericBug::PARTIALLEAK, bugEventStack), doubleFreePath(doubleFreePath){ } | ||
DoubleFreeBug(const EventStack &bugEventStack): | ||
GenericBug(GenericBug::PARTIALLEAK, bugEventStack){ } | ||
|
||
cJSON *getBugDescription(); | ||
void printBugToTerminal(); | ||
cJSON *getBugDescription() const; | ||
void printBugToTerminal() const; | ||
|
||
/// ClassOf | ||
static inline bool classof(const GenericBug *bug) | ||
|
@@ -259,8 +253,8 @@ class FileNeverCloseBug : public GenericBug{ | |
FileNeverCloseBug(const EventStack &bugEventStack): | ||
GenericBug(GenericBug::NEVERFREE, bugEventStack){ }; | ||
|
||
cJSON *getBugDescription(); | ||
void printBugToTerminal(); | ||
cJSON *getBugDescription() const; | ||
void printBugToTerminal() const; | ||
|
||
/// ClassOf | ||
static inline bool classof(const GenericBug *bug) | ||
|
@@ -270,15 +264,12 @@ class FileNeverCloseBug : public GenericBug{ | |
}; | ||
|
||
class FilePartialCloseBug : public GenericBug{ | ||
protected: | ||
Set<std::string> conditionalFileClosePath; | ||
|
||
public: | ||
FilePartialCloseBug(const EventStack &bugEventStack, Set<std::string> conditionalFileClosePath): | ||
GenericBug(GenericBug::PARTIALLEAK, bugEventStack), conditionalFileClosePath(conditionalFileClosePath){ } | ||
FilePartialCloseBug(const EventStack &bugEventStack): | ||
GenericBug(GenericBug::PARTIALLEAK, bugEventStack){ } | ||
|
||
cJSON *getBugDescription(); | ||
void printBugToTerminal(); | ||
cJSON *getBugDescription() const; | ||
void printBugToTerminal() const; | ||
|
||
/// ClassOf | ||
static inline bool classof(const GenericBug *bug) | ||
|
@@ -292,7 +283,7 @@ class SVFBugReport | |
public: | ||
SVFBugReport() = default; | ||
~SVFBugReport(); | ||
typedef SVF::Set<GenericBug *> BugSet; | ||
typedef SVF::Set<const GenericBug *> BugSet; | ||
|
||
protected: | ||
BugSet bugSet; // maintain bugs | ||
|
@@ -303,21 +294,71 @@ class SVFBugReport | |
* it will add the bug into bugQueue. | ||
* usage: addBug<GenericBug::BOA>(BufferOverflowBug(bugInst, 0, 10, 1, 11)) | ||
*/ | ||
template <typename T> | ||
void addBug(T bug) | ||
void addSaberBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack) | ||
{ | ||
T *newBug = new T(bug); | ||
bugSet.insert(newBug); | ||
GenericBug *newBug; | ||
switch(bugType){ | ||
case GenericBug::NEVERFREE:{ | ||
newBug = new NeverFreeBug(eventStack); | ||
bugSet.insert(newBug); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. newBug is use at line 333 |
||
break; | ||
} | ||
case GenericBug::PARTIALLEAK:{ | ||
newBug = new PartialLeakBug(eventStack); | ||
bugSet.insert(newBug); | ||
break; | ||
} | ||
case GenericBug::DOUBLEFREE:{ | ||
newBug = new DoubleFreeBug(eventStack); | ||
bugSet.insert(newBug); | ||
break; | ||
} | ||
case GenericBug::FILENEVERCLOSE:{ | ||
newBug = new FileNeverCloseBug(eventStack); | ||
bugSet.insert(newBug); | ||
break; | ||
} | ||
case GenericBug::FILEPARTIALCLOSE:{ | ||
newBug = new FilePartialCloseBug(eventStack); | ||
bugSet.insert(newBug); | ||
break; | ||
} | ||
default:{ | ||
assert(false && "saber does NOT have this bug type!"); | ||
break; | ||
} | ||
} | ||
|
||
// when add a bug, also print it to terminal | ||
newBug->printBugToTerminal(); | ||
} | ||
|
||
void addAbsExecBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack, | ||
s64_t allocLowerBound, s64_t allocUpperBound, s64_t accessLowerBound, s64_t accessUpperBound){ | ||
GenericBug *newBug; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. GenericBug *newBug = nullptr; |
||
switch(bugType){ | ||
case GenericBug::FULLBUFOVERFLOW: { | ||
newBug = new FullBufferOverflowBug(eventStack, allocLowerBound, allocUpperBound, accessLowerBound, accessUpperBound); | ||
bugSet.insert(newBug); | ||
break; | ||
} | ||
case GenericBug::PARTIALBUFOVERFLOW:{ | ||
newBug = new PartialBufferOverflowBug(eventStack, allocLowerBound, allocUpperBound, accessLowerBound, accessUpperBound); | ||
bugSet.insert(newBug); | ||
break; | ||
} | ||
default:{ | ||
assert(false && "Abstract Execution does NOT hava his bug type!"); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
/* | ||
* function: pass file path, open the file and dump bug report as JSON format | ||
* usage: dumpToFile("/path/to/file") | ||
*/ | ||
void dumpToFile(const std::string& filePath); | ||
void dumpToJsonFile(const std::string& filePath); | ||
}; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -146,19 +146,20 @@ const CallICFGNode* ProgSlice::getRetSite(const SVFGEdge* edge) const | |
return getSVFG()->getCallSite(SVFUtil::cast<RetIndSVFGEdge>(edge)->getCallSiteId()); | ||
} | ||
|
||
Set<std::string> ProgSlice::evalFinalCondSet() const | ||
void ProgSlice::evalFinalCond2Event(GenericBug::EventStack &eventStack) const | ||
{ | ||
NodeBS elems = pathAllocator->exactCondElem(finalCond); | ||
Set<std::string> locations; | ||
for(NodeBS::iterator it = elems.begin(), eit = elems.end(); it!=eit; ++it) | ||
{ | ||
const SVFInstruction* tinst = pathAllocator->getCondInst(*it); | ||
auto stmt = PAG::getPAG()->getValueEdges(tinst); | ||
assert(stmt.size() == 1 && "returned SVFStmtSet should be of size 1!"); | ||
if(pathAllocator->isNegCond(*it)) | ||
locations.insert(tinst->getSourceLoc()+"|False"); | ||
eventStack.push_back(new BranchEvent(*(stmt.begin()), false)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. new BranchEvent(tinst, false) |
||
else | ||
locations.insert(tinst->getSourceLoc()+"|True"); | ||
eventStack.push_back(new BranchEvent(*(stmt.begin()), true)); | ||
} | ||
return locations; | ||
} | ||
|
||
/*! | ||
|
@@ -174,7 +175,18 @@ std::string ProgSlice::evalFinalCond() const | |
{ | ||
std::string str; | ||
std::stringstream rawstr(str); | ||
Set<std::string> locations = evalFinalCondSet(); | ||
Set<std::string> locations; | ||
NodeBS elems = pathAllocator->exactCondElem(finalCond); | ||
|
||
for(NodeBS::iterator it = elems.begin(), eit = elems.end(); it!=eit; ++it) | ||
{ | ||
const SVFInstruction* tinst = pathAllocator->getCondInst(*it); | ||
if(pathAllocator->isNegCond(*it)) | ||
locations.insert(tinst->getSourceLoc()+"|False"); | ||
else | ||
locations.insert(tinst->getSourceLoc()+"|True"); | ||
} | ||
|
||
/// print leak path after eliminating duplicated element | ||
for(Set<std::string>::iterator iter = locations.begin(), eiter = locations.end(); | ||
iter!=eiter; ++iter) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,7 +105,6 @@ void SrcSnkDDA::analyze(SVFModule* module) | |
|
||
reportBug(getCurSlice()); | ||
} | ||
|
||
finalize(); | ||
|
||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GenericBug *newBug = nullptr;