diff options
author | Daniel Marjamaki <daniel.marjamaki@evidente.se> | 2017-05-02 11:46:12 +0000 |
---|---|---|
committer | Daniel Marjamaki <daniel.marjamaki@evidente.se> | 2017-05-02 11:46:12 +0000 |
commit | 14c91c7c5b96466cb9d445a17f375cc7944654da (patch) | |
tree | 33ab8bea8064f685d340f85a8cfc493ad65b7c35 /lib/StaticAnalyzer | |
parent | 5c23dd5604a4b2e4a99d87cd1281892603ff9f22 (diff) |
[analyzer] Detect bad free of function pointers
Differential Revision: https://reviews.llvm.org/D31650
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@301913 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 5730517289..9a7e83c149 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -401,6 +401,9 @@ private: void ReportUseZeroAllocated(CheckerContext &C, SourceRange Range, SymbolRef Sym) const; + void ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal, + SourceRange Range, const Expr *FreeExpr) const; + /// Find the location of the allocation for Sym on the path leading to the /// exploded node N. LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym, @@ -1564,6 +1567,11 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, } } + if (SymBase->getType()->isFunctionPointerType()) { + ReportFunctionPointerFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr); + return nullptr; + } + ReleasedAllocated = (RsBase != nullptr) && (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero()); @@ -2024,10 +2032,45 @@ void MallocChecker::ReportUseZeroAllocated(CheckerContext &C, } } +void MallocChecker::ReportFunctionPointerFree(CheckerContext &C, SVal ArgVal, + SourceRange Range, + const Expr *FreeExpr) const { + if (!ChecksEnabled[CK_MallocChecker]) + return; + + Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, FreeExpr); + if (!CheckKind.hasValue()) + return; + + if (ExplodedNode *N = C.generateErrorNode()) { + if (!BT_BadFree[*CheckKind]) + BT_BadFree[*CheckKind].reset( + new BugType(CheckNames[*CheckKind], "Bad free", "Memory Error")); + + SmallString<100> Buf; + llvm::raw_svector_ostream Os(Buf); + + const MemRegion *MR = ArgVal.getAsRegion(); + while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR)) + MR = ER->getSuperRegion(); + + Os << "Argument to "; + if (!printAllocDeallocName(Os, C, FreeExpr)) + Os << "deallocator"; + + Os << " is a function pointer"; + + auto R = llvm::make_unique<BugReport>(*BT_BadFree[*CheckKind], Os.str(), N); + R->markInteresting(MR); + R->addRange(Range); + C.emitReport(std::move(R)); + } +} + ProgramStateRef MallocChecker::ReallocMemAux(CheckerContext &C, const CallExpr *CE, bool FreesOnFail, - ProgramStateRef State, + ProgramStateRef State, bool SuffixWithN) const { if (!State) return nullptr; |