clang API Documentation
00001 //=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines malloc/free checker, which checks for potential memory 00011 // leaks, double free, and use-after-free problems. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "ClangSACheckers.h" 00016 #include "InterCheckerAPI.h" 00017 #include "clang/AST/Attr.h" 00018 #include "clang/AST/ParentMap.h" 00019 #include "clang/Basic/SourceManager.h" 00020 #include "clang/Basic/TargetInfo.h" 00021 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 00022 #include "clang/StaticAnalyzer/Core/Checker.h" 00023 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 00024 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 00025 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 00026 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 00027 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 00028 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 00029 #include "llvm/ADT/ImmutableMap.h" 00030 #include "llvm/ADT/STLExtras.h" 00031 #include "llvm/ADT/SmallString.h" 00032 #include "llvm/ADT/StringExtras.h" 00033 #include <climits> 00034 00035 using namespace clang; 00036 using namespace ento; 00037 00038 namespace { 00039 00040 // Used to check correspondence between allocators and deallocators. 00041 enum AllocationFamily { 00042 AF_None, 00043 AF_Malloc, 00044 AF_CXXNew, 00045 AF_CXXNewArray, 00046 AF_IfNameIndex 00047 }; 00048 00049 class RefState { 00050 enum Kind { // Reference to allocated memory. 00051 Allocated, 00052 // Reference to released/freed memory. 00053 Released, 00054 // The responsibility for freeing resources has transferred from 00055 // this reference. A relinquished symbol should not be freed. 00056 Relinquished, 00057 // We are no longer guaranteed to have observed all manipulations 00058 // of this pointer/memory. For example, it could have been 00059 // passed as a parameter to an opaque function. 00060 Escaped 00061 }; 00062 00063 const Stmt *S; 00064 unsigned K : 2; // Kind enum, but stored as a bitfield. 00065 unsigned Family : 30; // Rest of 32-bit word, currently just an allocation 00066 // family. 00067 00068 RefState(Kind k, const Stmt *s, unsigned family) 00069 : S(s), K(k), Family(family) { 00070 assert(family != AF_None); 00071 } 00072 public: 00073 bool isAllocated() const { return K == Allocated; } 00074 bool isReleased() const { return K == Released; } 00075 bool isRelinquished() const { return K == Relinquished; } 00076 bool isEscaped() const { return K == Escaped; } 00077 AllocationFamily getAllocationFamily() const { 00078 return (AllocationFamily)Family; 00079 } 00080 const Stmt *getStmt() const { return S; } 00081 00082 bool operator==(const RefState &X) const { 00083 return K == X.K && S == X.S && Family == X.Family; 00084 } 00085 00086 static RefState getAllocated(unsigned family, const Stmt *s) { 00087 return RefState(Allocated, s, family); 00088 } 00089 static RefState getReleased(unsigned family, const Stmt *s) { 00090 return RefState(Released, s, family); 00091 } 00092 static RefState getRelinquished(unsigned family, const Stmt *s) { 00093 return RefState(Relinquished, s, family); 00094 } 00095 static RefState getEscaped(const RefState *RS) { 00096 return RefState(Escaped, RS->getStmt(), RS->getAllocationFamily()); 00097 } 00098 00099 void Profile(llvm::FoldingSetNodeID &ID) const { 00100 ID.AddInteger(K); 00101 ID.AddPointer(S); 00102 ID.AddInteger(Family); 00103 } 00104 00105 void dump(raw_ostream &OS) const { 00106 switch (static_cast<Kind>(K)) { 00107 #define CASE(ID) case ID: OS << #ID; break; 00108 CASE(Allocated) 00109 CASE(Released) 00110 CASE(Relinquished) 00111 CASE(Escaped) 00112 } 00113 } 00114 00115 LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); } 00116 }; 00117 00118 enum ReallocPairKind { 00119 RPToBeFreedAfterFailure, 00120 // The symbol has been freed when reallocation failed. 00121 RPIsFreeOnFailure, 00122 // The symbol does not need to be freed after reallocation fails. 00123 RPDoNotTrackAfterFailure 00124 }; 00125 00126 /// \class ReallocPair 00127 /// \brief Stores information about the symbol being reallocated by a call to 00128 /// 'realloc' to allow modeling failed reallocation later in the path. 00129 struct ReallocPair { 00130 // \brief The symbol which realloc reallocated. 00131 SymbolRef ReallocatedSym; 00132 ReallocPairKind Kind; 00133 00134 ReallocPair(SymbolRef S, ReallocPairKind K) : 00135 ReallocatedSym(S), Kind(K) {} 00136 void Profile(llvm::FoldingSetNodeID &ID) const { 00137 ID.AddInteger(Kind); 00138 ID.AddPointer(ReallocatedSym); 00139 } 00140 bool operator==(const ReallocPair &X) const { 00141 return ReallocatedSym == X.ReallocatedSym && 00142 Kind == X.Kind; 00143 } 00144 }; 00145 00146 typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo; 00147 00148 class MallocChecker : public Checker<check::DeadSymbols, 00149 check::PointerEscape, 00150 check::ConstPointerEscape, 00151 check::PreStmt<ReturnStmt>, 00152 check::PreCall, 00153 check::PostStmt<CallExpr>, 00154 check::PostStmt<CXXNewExpr>, 00155 check::PreStmt<CXXDeleteExpr>, 00156 check::PostStmt<BlockExpr>, 00157 check::PostObjCMessage, 00158 check::Location, 00159 eval::Assume> 00160 { 00161 public: 00162 MallocChecker() 00163 : II_malloc(nullptr), II_free(nullptr), II_realloc(nullptr), 00164 II_calloc(nullptr), II_valloc(nullptr), II_reallocf(nullptr), 00165 II_strndup(nullptr), II_strdup(nullptr), II_kmalloc(nullptr), 00166 II_if_nameindex(nullptr), II_if_freenameindex(nullptr) {} 00167 00168 /// In pessimistic mode, the checker assumes that it does not know which 00169 /// functions might free the memory. 00170 enum CheckKind { 00171 CK_MallocPessimistic, 00172 CK_MallocOptimistic, 00173 CK_NewDeleteChecker, 00174 CK_NewDeleteLeaksChecker, 00175 CK_MismatchedDeallocatorChecker, 00176 CK_NumCheckKinds 00177 }; 00178 00179 enum class MemoryOperationKind { 00180 MOK_Allocate, 00181 MOK_Free, 00182 MOK_Any 00183 }; 00184 00185 DefaultBool ChecksEnabled[CK_NumCheckKinds]; 00186 CheckName CheckNames[CK_NumCheckKinds]; 00187 00188 void checkPreCall(const CallEvent &Call, CheckerContext &C) const; 00189 void checkPostStmt(const CallExpr *CE, CheckerContext &C) const; 00190 void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const; 00191 void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const; 00192 void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const; 00193 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const; 00194 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; 00195 void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const; 00196 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, 00197 bool Assumption) const; 00198 void checkLocation(SVal l, bool isLoad, const Stmt *S, 00199 CheckerContext &C) const; 00200 00201 ProgramStateRef checkPointerEscape(ProgramStateRef State, 00202 const InvalidatedSymbols &Escaped, 00203 const CallEvent *Call, 00204 PointerEscapeKind Kind) const; 00205 ProgramStateRef checkConstPointerEscape(ProgramStateRef State, 00206 const InvalidatedSymbols &Escaped, 00207 const CallEvent *Call, 00208 PointerEscapeKind Kind) const; 00209 00210 void printState(raw_ostream &Out, ProgramStateRef State, 00211 const char *NL, const char *Sep) const override; 00212 00213 private: 00214 mutable std::unique_ptr<BugType> BT_DoubleFree[CK_NumCheckKinds]; 00215 mutable std::unique_ptr<BugType> BT_DoubleDelete; 00216 mutable std::unique_ptr<BugType> BT_Leak[CK_NumCheckKinds]; 00217 mutable std::unique_ptr<BugType> BT_UseFree[CK_NumCheckKinds]; 00218 mutable std::unique_ptr<BugType> BT_BadFree[CK_NumCheckKinds]; 00219 mutable std::unique_ptr<BugType> BT_MismatchedDealloc; 00220 mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds]; 00221 mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc, 00222 *II_valloc, *II_reallocf, *II_strndup, *II_strdup, 00223 *II_kmalloc, *II_if_nameindex, *II_if_freenameindex; 00224 mutable Optional<uint64_t> KernelZeroFlagVal; 00225 00226 void initIdentifierInfo(ASTContext &C) const; 00227 00228 /// \brief Determine family of a deallocation expression. 00229 AllocationFamily getAllocationFamily(CheckerContext &C, const Stmt *S) const; 00230 00231 /// \brief Print names of allocators and deallocators. 00232 /// 00233 /// \returns true on success. 00234 bool printAllocDeallocName(raw_ostream &os, CheckerContext &C, 00235 const Expr *E) const; 00236 00237 /// \brief Print expected name of an allocator based on the deallocator's 00238 /// family derived from the DeallocExpr. 00239 void printExpectedAllocName(raw_ostream &os, CheckerContext &C, 00240 const Expr *DeallocExpr) const; 00241 /// \brief Print expected name of a deallocator based on the allocator's 00242 /// family. 00243 void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) const; 00244 00245 ///@{ 00246 /// Check if this is one of the functions which can allocate/reallocate memory 00247 /// pointed to by one of its arguments. 00248 bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const; 00249 bool isCMemFunction(const FunctionDecl *FD, 00250 ASTContext &C, 00251 AllocationFamily Family, 00252 MemoryOperationKind MemKind) const; 00253 bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const; 00254 ///@} 00255 ProgramStateRef MallocMemReturnsAttr(CheckerContext &C, 00256 const CallExpr *CE, 00257 const OwnershipAttr* Att) const; 00258 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, 00259 const Expr *SizeEx, SVal Init, 00260 ProgramStateRef State, 00261 AllocationFamily Family = AF_Malloc) { 00262 return MallocMemAux(C, CE, 00263 State->getSVal(SizeEx, C.getLocationContext()), 00264 Init, State, Family); 00265 } 00266 00267 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, 00268 SVal SizeEx, SVal Init, 00269 ProgramStateRef State, 00270 AllocationFamily Family = AF_Malloc); 00271 00272 // Check if this malloc() for special flags. At present that means M_ZERO or 00273 // __GFP_ZERO (in which case, treat it like calloc). 00274 llvm::Optional<ProgramStateRef> 00275 performKernelMalloc(const CallExpr *CE, CheckerContext &C, 00276 const ProgramStateRef &State) const; 00277 00278 /// Update the RefState to reflect the new memory allocation. 00279 static ProgramStateRef 00280 MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State, 00281 AllocationFamily Family = AF_Malloc); 00282 00283 ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE, 00284 const OwnershipAttr* Att) const; 00285 ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE, 00286 ProgramStateRef state, unsigned Num, 00287 bool Hold, 00288 bool &ReleasedAllocated, 00289 bool ReturnsNullOnFailure = false) const; 00290 ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *Arg, 00291 const Expr *ParentExpr, 00292 ProgramStateRef State, 00293 bool Hold, 00294 bool &ReleasedAllocated, 00295 bool ReturnsNullOnFailure = false) const; 00296 00297 ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE, 00298 bool FreesMemOnFailure) const; 00299 static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE); 00300 00301 ///\brief Check if the memory associated with this symbol was released. 00302 bool isReleased(SymbolRef Sym, CheckerContext &C) const; 00303 00304 bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const; 00305 00306 bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const; 00307 00308 /// Check if the function is known free memory, or if it is 00309 /// "interesting" and should be modeled explicitly. 00310 /// 00311 /// \param [out] EscapingSymbol A function might not free memory in general, 00312 /// but could be known to free a particular symbol. In this case, false is 00313 /// returned and the single escaping symbol is returned through the out 00314 /// parameter. 00315 /// 00316 /// We assume that pointers do not escape through calls to system functions 00317 /// not handled by this checker. 00318 bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call, 00319 ProgramStateRef State, 00320 SymbolRef &EscapingSymbol) const; 00321 00322 // Implementation of the checkPointerEscape callabcks. 00323 ProgramStateRef checkPointerEscapeAux(ProgramStateRef State, 00324 const InvalidatedSymbols &Escaped, 00325 const CallEvent *Call, 00326 PointerEscapeKind Kind, 00327 bool(*CheckRefState)(const RefState*)) const; 00328 00329 ///@{ 00330 /// Tells if a given family/call/symbol is tracked by the current checker. 00331 /// Sets CheckKind to the kind of the checker responsible for this 00332 /// family/call/symbol. 00333 Optional<CheckKind> getCheckIfTracked(AllocationFamily Family) const; 00334 Optional<CheckKind> getCheckIfTracked(CheckerContext &C, 00335 const Stmt *AllocDeallocStmt) const; 00336 Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym) const; 00337 ///@} 00338 static bool SummarizeValue(raw_ostream &os, SVal V); 00339 static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR); 00340 void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range, 00341 const Expr *DeallocExpr) const; 00342 void ReportMismatchedDealloc(CheckerContext &C, SourceRange Range, 00343 const Expr *DeallocExpr, const RefState *RS, 00344 SymbolRef Sym, bool OwnershipTransferred) const; 00345 void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range, 00346 const Expr *DeallocExpr, 00347 const Expr *AllocExpr = nullptr) const; 00348 void ReportUseAfterFree(CheckerContext &C, SourceRange Range, 00349 SymbolRef Sym) const; 00350 void ReportDoubleFree(CheckerContext &C, SourceRange Range, bool Released, 00351 SymbolRef Sym, SymbolRef PrevSym) const; 00352 00353 void ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const; 00354 00355 /// Find the location of the allocation for Sym on the path leading to the 00356 /// exploded node N. 00357 LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym, 00358 CheckerContext &C) const; 00359 00360 void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const; 00361 00362 /// The bug visitor which allows us to print extra diagnostics along the 00363 /// BugReport path. For example, showing the allocation site of the leaked 00364 /// region. 00365 class MallocBugVisitor : public BugReporterVisitorImpl<MallocBugVisitor> { 00366 protected: 00367 enum NotificationMode { 00368 Normal, 00369 ReallocationFailed 00370 }; 00371 00372 // The allocated region symbol tracked by the main analysis. 00373 SymbolRef Sym; 00374 00375 // The mode we are in, i.e. what kind of diagnostics will be emitted. 00376 NotificationMode Mode; 00377 00378 // A symbol from when the primary region should have been reallocated. 00379 SymbolRef FailedReallocSymbol; 00380 00381 bool IsLeak; 00382 00383 public: 00384 MallocBugVisitor(SymbolRef S, bool isLeak = false) 00385 : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), IsLeak(isLeak) {} 00386 00387 virtual ~MallocBugVisitor() {} 00388 00389 void Profile(llvm::FoldingSetNodeID &ID) const override { 00390 static int X = 0; 00391 ID.AddPointer(&X); 00392 ID.AddPointer(Sym); 00393 } 00394 00395 inline bool isAllocated(const RefState *S, const RefState *SPrev, 00396 const Stmt *Stmt) { 00397 // Did not track -> allocated. Other state (released) -> allocated. 00398 return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) && 00399 (S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated())); 00400 } 00401 00402 inline bool isReleased(const RefState *S, const RefState *SPrev, 00403 const Stmt *Stmt) { 00404 // Did not track -> released. Other state (allocated) -> released. 00405 return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt)) && 00406 (S && S->isReleased()) && (!SPrev || !SPrev->isReleased())); 00407 } 00408 00409 inline bool isRelinquished(const RefState *S, const RefState *SPrev, 00410 const Stmt *Stmt) { 00411 // Did not track -> relinquished. Other state (allocated) -> relinquished. 00412 return (Stmt && (isa<CallExpr>(Stmt) || isa<ObjCMessageExpr>(Stmt) || 00413 isa<ObjCPropertyRefExpr>(Stmt)) && 00414 (S && S->isRelinquished()) && 00415 (!SPrev || !SPrev->isRelinquished())); 00416 } 00417 00418 inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev, 00419 const Stmt *Stmt) { 00420 // If the expression is not a call, and the state change is 00421 // released -> allocated, it must be the realloc return value 00422 // check. If we have to handle more cases here, it might be cleaner just 00423 // to track this extra bit in the state itself. 00424 return ((!Stmt || !isa<CallExpr>(Stmt)) && 00425 (S && S->isAllocated()) && (SPrev && !SPrev->isAllocated())); 00426 } 00427 00428 PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 00429 const ExplodedNode *PrevN, 00430 BugReporterContext &BRC, 00431 BugReport &BR) override; 00432 00433 std::unique_ptr<PathDiagnosticPiece> 00434 getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode, 00435 BugReport &BR) override { 00436 if (!IsLeak) 00437 return nullptr; 00438 00439 PathDiagnosticLocation L = 00440 PathDiagnosticLocation::createEndOfPath(EndPathNode, 00441 BRC.getSourceManager()); 00442 // Do not add the statement itself as a range in case of leak. 00443 return llvm::make_unique<PathDiagnosticEventPiece>(L, BR.getDescription(), 00444 false); 00445 } 00446 00447 private: 00448 class StackHintGeneratorForReallocationFailed 00449 : public StackHintGeneratorForSymbol { 00450 public: 00451 StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M) 00452 : StackHintGeneratorForSymbol(S, M) {} 00453 00454 std::string getMessageForArg(const Expr *ArgE, 00455 unsigned ArgIndex) override { 00456 // Printed parameters start at 1, not 0. 00457 ++ArgIndex; 00458 00459 SmallString<200> buf; 00460 llvm::raw_svector_ostream os(buf); 00461 00462 os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex) 00463 << " parameter failed"; 00464 00465 return os.str(); 00466 } 00467 00468 std::string getMessageForReturn(const CallExpr *CallExpr) override { 00469 return "Reallocation of returned value failed"; 00470 } 00471 }; 00472 }; 00473 }; 00474 } // end anonymous namespace 00475 00476 REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState) 00477 REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair) 00478 00479 // A map from the freed symbol to the symbol representing the return value of 00480 // the free function. 00481 REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef) 00482 00483 namespace { 00484 class StopTrackingCallback : public SymbolVisitor { 00485 ProgramStateRef state; 00486 public: 00487 StopTrackingCallback(ProgramStateRef st) : state(st) {} 00488 ProgramStateRef getState() const { return state; } 00489 00490 bool VisitSymbol(SymbolRef sym) override { 00491 state = state->remove<RegionState>(sym); 00492 return true; 00493 } 00494 }; 00495 } // end anonymous namespace 00496 00497 void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { 00498 if (II_malloc) 00499 return; 00500 II_malloc = &Ctx.Idents.get("malloc"); 00501 II_free = &Ctx.Idents.get("free"); 00502 II_realloc = &Ctx.Idents.get("realloc"); 00503 II_reallocf = &Ctx.Idents.get("reallocf"); 00504 II_calloc = &Ctx.Idents.get("calloc"); 00505 II_valloc = &Ctx.Idents.get("valloc"); 00506 II_strdup = &Ctx.Idents.get("strdup"); 00507 II_strndup = &Ctx.Idents.get("strndup"); 00508 II_kmalloc = &Ctx.Idents.get("kmalloc"); 00509 II_if_nameindex = &Ctx.Idents.get("if_nameindex"); 00510 II_if_freenameindex = &Ctx.Idents.get("if_freenameindex"); 00511 } 00512 00513 bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const { 00514 if (isCMemFunction(FD, C, AF_Malloc, MemoryOperationKind::MOK_Any)) 00515 return true; 00516 00517 if (isCMemFunction(FD, C, AF_IfNameIndex, MemoryOperationKind::MOK_Any)) 00518 return true; 00519 00520 if (isStandardNewDelete(FD, C)) 00521 return true; 00522 00523 return false; 00524 } 00525 00526 bool MallocChecker::isCMemFunction(const FunctionDecl *FD, 00527 ASTContext &C, 00528 AllocationFamily Family, 00529 MemoryOperationKind MemKind) const { 00530 if (!FD) 00531 return false; 00532 00533 bool CheckFree = (MemKind == MemoryOperationKind::MOK_Any || 00534 MemKind == MemoryOperationKind::MOK_Free); 00535 bool CheckAlloc = (MemKind == MemoryOperationKind::MOK_Any || 00536 MemKind == MemoryOperationKind::MOK_Allocate); 00537 00538 if (FD->getKind() == Decl::Function) { 00539 const IdentifierInfo *FunI = FD->getIdentifier(); 00540 initIdentifierInfo(C); 00541 00542 if (Family == AF_Malloc && CheckFree) { 00543 if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf) 00544 return true; 00545 } 00546 00547 if (Family == AF_Malloc && CheckAlloc) { 00548 if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf || 00549 FunI == II_calloc || FunI == II_valloc || FunI == II_strdup || 00550 FunI == II_strndup || FunI == II_kmalloc) 00551 return true; 00552 } 00553 00554 if (Family == AF_IfNameIndex && CheckFree) { 00555 if (FunI == II_if_freenameindex) 00556 return true; 00557 } 00558 00559 if (Family == AF_IfNameIndex && CheckAlloc) { 00560 if (FunI == II_if_nameindex) 00561 return true; 00562 } 00563 } 00564 00565 if (Family != AF_Malloc) 00566 return false; 00567 00568 if (ChecksEnabled[CK_MallocOptimistic] && FD->hasAttrs()) { 00569 for (const auto *I : FD->specific_attrs<OwnershipAttr>()) { 00570 OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind(); 00571 if(OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds) { 00572 if (CheckFree) 00573 return true; 00574 } else if (OwnKind == OwnershipAttr::Returns) { 00575 if (CheckAlloc) 00576 return true; 00577 } 00578 } 00579 } 00580 00581 return false; 00582 } 00583 00584 // Tells if the callee is one of the following: 00585 // 1) A global non-placement new/delete operator function. 00586 // 2) A global placement operator function with the single placement argument 00587 // of type std::nothrow_t. 00588 bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD, 00589 ASTContext &C) const { 00590 if (!FD) 00591 return false; 00592 00593 OverloadedOperatorKind Kind = FD->getOverloadedOperator(); 00594 if (Kind != OO_New && Kind != OO_Array_New && 00595 Kind != OO_Delete && Kind != OO_Array_Delete) 00596 return false; 00597 00598 // Skip all operator new/delete methods. 00599 if (isa<CXXMethodDecl>(FD)) 00600 return false; 00601 00602 // Return true if tested operator is a standard placement nothrow operator. 00603 if (FD->getNumParams() == 2) { 00604 QualType T = FD->getParamDecl(1)->getType(); 00605 if (const IdentifierInfo *II = T.getBaseTypeIdentifier()) 00606 return II->getName().equals("nothrow_t"); 00607 } 00608 00609 // Skip placement operators. 00610 if (FD->getNumParams() != 1 || FD->isVariadic()) 00611 return false; 00612 00613 // One of the standard new/new[]/delete/delete[] non-placement operators. 00614 return true; 00615 } 00616 00617 llvm::Optional<ProgramStateRef> MallocChecker::performKernelMalloc( 00618 const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const { 00619 // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels: 00620 // 00621 // void *malloc(unsigned long size, struct malloc_type *mtp, int flags); 00622 // 00623 // One of the possible flags is M_ZERO, which means 'give me back an 00624 // allocation which is already zeroed', like calloc. 00625 00626 // 2-argument kmalloc(), as used in the Linux kernel: 00627 // 00628 // void *kmalloc(size_t size, gfp_t flags); 00629 // 00630 // Has the similar flag value __GFP_ZERO. 00631 00632 // This logic is largely cloned from O_CREAT in UnixAPIChecker, maybe some 00633 // code could be shared. 00634 00635 ASTContext &Ctx = C.getASTContext(); 00636 llvm::Triple::OSType OS = Ctx.getTargetInfo().getTriple().getOS(); 00637 00638 if (!KernelZeroFlagVal.hasValue()) { 00639 if (OS == llvm::Triple::FreeBSD) 00640 KernelZeroFlagVal = 0x0100; 00641 else if (OS == llvm::Triple::NetBSD) 00642 KernelZeroFlagVal = 0x0002; 00643 else if (OS == llvm::Triple::OpenBSD) 00644 KernelZeroFlagVal = 0x0008; 00645 else if (OS == llvm::Triple::Linux) 00646 // __GFP_ZERO 00647 KernelZeroFlagVal = 0x8000; 00648 else 00649 // FIXME: We need a more general way of getting the M_ZERO value. 00650 // See also: O_CREAT in UnixAPIChecker.cpp. 00651 00652 // Fall back to normal malloc behavior on platforms where we don't 00653 // know M_ZERO. 00654 return None; 00655 } 00656 00657 // We treat the last argument as the flags argument, and callers fall-back to 00658 // normal malloc on a None return. This works for the FreeBSD kernel malloc 00659 // as well as Linux kmalloc. 00660 if (CE->getNumArgs() < 2) 00661 return None; 00662 00663 const Expr *FlagsEx = CE->getArg(CE->getNumArgs() - 1); 00664 const SVal V = State->getSVal(FlagsEx, C.getLocationContext()); 00665 if (!V.getAs<NonLoc>()) { 00666 // The case where 'V' can be a location can only be due to a bad header, 00667 // so in this case bail out. 00668 return None; 00669 } 00670 00671 NonLoc Flags = V.castAs<NonLoc>(); 00672 NonLoc ZeroFlag = C.getSValBuilder() 00673 .makeIntVal(KernelZeroFlagVal.getValue(), FlagsEx->getType()) 00674 .castAs<NonLoc>(); 00675 SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN(State, BO_And, 00676 Flags, ZeroFlag, 00677 FlagsEx->getType()); 00678 if (MaskedFlagsUC.isUnknownOrUndef()) 00679 return None; 00680 DefinedSVal MaskedFlags = MaskedFlagsUC.castAs<DefinedSVal>(); 00681 00682 // Check if maskedFlags is non-zero. 00683 ProgramStateRef TrueState, FalseState; 00684 std::tie(TrueState, FalseState) = State->assume(MaskedFlags); 00685 00686 // If M_ZERO is set, treat this like calloc (initialized). 00687 if (TrueState && !FalseState) { 00688 SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy); 00689 return MallocMemAux(C, CE, CE->getArg(0), ZeroVal, TrueState); 00690 } 00691 00692 return None; 00693 } 00694 00695 void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { 00696 if (C.wasInlined) 00697 return; 00698 00699 const FunctionDecl *FD = C.getCalleeDecl(CE); 00700 if (!FD) 00701 return; 00702 00703 ProgramStateRef State = C.getState(); 00704 bool ReleasedAllocatedMemory = false; 00705 00706 if (FD->getKind() == Decl::Function) { 00707 initIdentifierInfo(C.getASTContext()); 00708 IdentifierInfo *FunI = FD->getIdentifier(); 00709 00710 if (FunI == II_malloc) { 00711 if (CE->getNumArgs() < 1) 00712 return; 00713 if (CE->getNumArgs() < 3) { 00714 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); 00715 } else if (CE->getNumArgs() == 3) { 00716 llvm::Optional<ProgramStateRef> MaybeState = 00717 performKernelMalloc(CE, C, State); 00718 if (MaybeState.hasValue()) 00719 State = MaybeState.getValue(); 00720 else 00721 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); 00722 } 00723 } else if (FunI == II_kmalloc) { 00724 llvm::Optional<ProgramStateRef> MaybeState = 00725 performKernelMalloc(CE, C, State); 00726 if (MaybeState.hasValue()) 00727 State = MaybeState.getValue(); 00728 else 00729 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); 00730 } else if (FunI == II_valloc) { 00731 if (CE->getNumArgs() < 1) 00732 return; 00733 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); 00734 } else if (FunI == II_realloc) { 00735 State = ReallocMem(C, CE, false); 00736 } else if (FunI == II_reallocf) { 00737 State = ReallocMem(C, CE, true); 00738 } else if (FunI == II_calloc) { 00739 State = CallocMem(C, CE); 00740 } else if (FunI == II_free) { 00741 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); 00742 } else if (FunI == II_strdup) { 00743 State = MallocUpdateRefState(C, CE, State); 00744 } else if (FunI == II_strndup) { 00745 State = MallocUpdateRefState(C, CE, State); 00746 } 00747 else if (isStandardNewDelete(FD, C.getASTContext())) { 00748 // Process direct calls to operator new/new[]/delete/delete[] functions 00749 // as distinct from new/new[]/delete/delete[] expressions that are 00750 // processed by the checkPostStmt callbacks for CXXNewExpr and 00751 // CXXDeleteExpr. 00752 OverloadedOperatorKind K = FD->getOverloadedOperator(); 00753 if (K == OO_New) 00754 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, 00755 AF_CXXNew); 00756 else if (K == OO_Array_New) 00757 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, 00758 AF_CXXNewArray); 00759 else if (K == OO_Delete || K == OO_Array_Delete) 00760 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); 00761 else 00762 llvm_unreachable("not a new/delete operator"); 00763 } else if (FunI == II_if_nameindex) { 00764 // Should we model this differently? We can allocate a fixed number of 00765 // elements with zeros in the last one. 00766 State = MallocMemAux(C, CE, UnknownVal(), UnknownVal(), State, 00767 AF_IfNameIndex); 00768 } else if (FunI == II_if_freenameindex) { 00769 State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory); 00770 } 00771 } 00772 00773 if (ChecksEnabled[CK_MallocOptimistic] || 00774 ChecksEnabled[CK_MismatchedDeallocatorChecker]) { 00775 // Check all the attributes, if there are any. 00776 // There can be multiple of these attributes. 00777 if (FD->hasAttrs()) 00778 for (const auto *I : FD->specific_attrs<OwnershipAttr>()) { 00779 switch (I->getOwnKind()) { 00780 case OwnershipAttr::Returns: 00781 State = MallocMemReturnsAttr(C, CE, I); 00782 break; 00783 case OwnershipAttr::Takes: 00784 case OwnershipAttr::Holds: 00785 State = FreeMemAttr(C, CE, I); 00786 break; 00787 } 00788 } 00789 } 00790 C.addTransition(State); 00791 } 00792 00793 static QualType getDeepPointeeType(QualType T) { 00794 QualType Result = T, PointeeType = T->getPointeeType(); 00795 while (!PointeeType.isNull()) { 00796 Result = PointeeType; 00797 PointeeType = PointeeType->getPointeeType(); 00798 } 00799 return Result; 00800 } 00801 00802 static bool treatUnusedNewEscaped(const CXXNewExpr *NE) { 00803 00804 const CXXConstructExpr *ConstructE = NE->getConstructExpr(); 00805 if (!ConstructE) 00806 return false; 00807 00808 if (!NE->getAllocatedType()->getAsCXXRecordDecl()) 00809 return false; 00810 00811 const CXXConstructorDecl *CtorD = ConstructE->getConstructor(); 00812 00813 // Iterate over the constructor parameters. 00814 for (const auto *CtorParam : CtorD->params()) { 00815 00816 QualType CtorParamPointeeT = CtorParam->getType()->getPointeeType(); 00817 if (CtorParamPointeeT.isNull()) 00818 continue; 00819 00820 CtorParamPointeeT = getDeepPointeeType(CtorParamPointeeT); 00821 00822 if (CtorParamPointeeT->getAsCXXRecordDecl()) 00823 return true; 00824 } 00825 00826 return false; 00827 } 00828 00829 void MallocChecker::checkPostStmt(const CXXNewExpr *NE, 00830 CheckerContext &C) const { 00831 00832 if (NE->getNumPlacementArgs()) 00833 for (CXXNewExpr::const_arg_iterator I = NE->placement_arg_begin(), 00834 E = NE->placement_arg_end(); I != E; ++I) 00835 if (SymbolRef Sym = C.getSVal(*I).getAsSymbol()) 00836 checkUseAfterFree(Sym, C, *I); 00837 00838 if (!isStandardNewDelete(NE->getOperatorNew(), C.getASTContext())) 00839 return; 00840 00841 ParentMap &PM = C.getLocationContext()->getParentMap(); 00842 if (!PM.isConsumedExpr(NE) && treatUnusedNewEscaped(NE)) 00843 return; 00844 00845 ProgramStateRef State = C.getState(); 00846 // The return value from operator new is bound to a specified initialization 00847 // value (if any) and we don't want to loose this value. So we call 00848 // MallocUpdateRefState() instead of MallocMemAux() which breakes the 00849 // existing binding. 00850 State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray 00851 : AF_CXXNew); 00852 C.addTransition(State); 00853 } 00854 00855 void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE, 00856 CheckerContext &C) const { 00857 00858 if (!ChecksEnabled[CK_NewDeleteChecker]) 00859 if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol()) 00860 checkUseAfterFree(Sym, C, DE->getArgument()); 00861 00862 if (!isStandardNewDelete(DE->getOperatorDelete(), C.getASTContext())) 00863 return; 00864 00865 ProgramStateRef State = C.getState(); 00866 bool ReleasedAllocated; 00867 State = FreeMemAux(C, DE->getArgument(), DE, State, 00868 /*Hold*/false, ReleasedAllocated); 00869 00870 C.addTransition(State); 00871 } 00872 00873 static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call) { 00874 // If the first selector piece is one of the names below, assume that the 00875 // object takes ownership of the memory, promising to eventually deallocate it 00876 // with free(). 00877 // Ex: [NSData dataWithBytesNoCopy:bytes length:10]; 00878 // (...unless a 'freeWhenDone' parameter is false, but that's checked later.) 00879 StringRef FirstSlot = Call.getSelector().getNameForSlot(0); 00880 if (FirstSlot == "dataWithBytesNoCopy" || 00881 FirstSlot == "initWithBytesNoCopy" || 00882 FirstSlot == "initWithCharactersNoCopy") 00883 return true; 00884 00885 return false; 00886 } 00887 00888 static Optional<bool> getFreeWhenDoneArg(const ObjCMethodCall &Call) { 00889 Selector S = Call.getSelector(); 00890 00891 // FIXME: We should not rely on fully-constrained symbols being folded. 00892 for (unsigned i = 1; i < S.getNumArgs(); ++i) 00893 if (S.getNameForSlot(i).equals("freeWhenDone")) 00894 return !Call.getArgSVal(i).isZeroConstant(); 00895 00896 return None; 00897 } 00898 00899 void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call, 00900 CheckerContext &C) const { 00901 if (C.wasInlined) 00902 return; 00903 00904 if (!isKnownDeallocObjCMethodName(Call)) 00905 return; 00906 00907 if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(Call)) 00908 if (!*FreeWhenDone) 00909 return; 00910 00911 bool ReleasedAllocatedMemory; 00912 ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0), 00913 Call.getOriginExpr(), C.getState(), 00914 /*Hold=*/true, ReleasedAllocatedMemory, 00915 /*RetNullOnFailure=*/true); 00916 00917 C.addTransition(State); 00918 } 00919 00920 ProgramStateRef 00921 MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, 00922 const OwnershipAttr *Att) const { 00923 if (Att->getModule() != II_malloc) 00924 return nullptr; 00925 00926 OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); 00927 if (I != E) { 00928 return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState()); 00929 } 00930 return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), C.getState()); 00931 } 00932 00933 ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, 00934 const CallExpr *CE, 00935 SVal Size, SVal Init, 00936 ProgramStateRef State, 00937 AllocationFamily Family) { 00938 00939 // We expect the malloc functions to return a pointer. 00940 if (!Loc::isLocType(CE->getType())) 00941 return nullptr; 00942 00943 // Bind the return value to the symbolic value from the heap region. 00944 // TODO: We could rewrite post visit to eval call; 'malloc' does not have 00945 // side effects other than what we model here. 00946 unsigned Count = C.blockCount(); 00947 SValBuilder &svalBuilder = C.getSValBuilder(); 00948 const LocationContext *LCtx = C.getPredecessor()->getLocationContext(); 00949 DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count) 00950 .castAs<DefinedSVal>(); 00951 State = State->BindExpr(CE, C.getLocationContext(), RetVal); 00952 00953 // Fill the region with the initialization value. 00954 State = State->bindDefault(RetVal, Init); 00955 00956 // Set the region's extent equal to the Size parameter. 00957 const SymbolicRegion *R = 00958 dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion()); 00959 if (!R) 00960 return nullptr; 00961 if (Optional<DefinedOrUnknownSVal> DefinedSize = 00962 Size.getAs<DefinedOrUnknownSVal>()) { 00963 SValBuilder &svalBuilder = C.getSValBuilder(); 00964 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder); 00965 DefinedOrUnknownSVal extentMatchesSize = 00966 svalBuilder.evalEQ(State, Extent, *DefinedSize); 00967 00968 State = State->assume(extentMatchesSize, true); 00969 assert(State); 00970 } 00971 00972 return MallocUpdateRefState(C, CE, State, Family); 00973 } 00974 00975 ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C, 00976 const Expr *E, 00977 ProgramStateRef State, 00978 AllocationFamily Family) { 00979 // Get the return value. 00980 SVal retVal = State->getSVal(E, C.getLocationContext()); 00981 00982 // We expect the malloc functions to return a pointer. 00983 if (!retVal.getAs<Loc>()) 00984 return nullptr; 00985 00986 SymbolRef Sym = retVal.getAsLocSymbol(); 00987 assert(Sym); 00988 00989 // Set the symbol's state to Allocated. 00990 return State->set<RegionState>(Sym, RefState::getAllocated(Family, E)); 00991 } 00992 00993 ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C, 00994 const CallExpr *CE, 00995 const OwnershipAttr *Att) const { 00996 if (Att->getModule() != II_malloc) 00997 return nullptr; 00998 00999 ProgramStateRef State = C.getState(); 01000 bool ReleasedAllocated = false; 01001 01002 for (const auto &Arg : Att->args()) { 01003 ProgramStateRef StateI = FreeMemAux(C, CE, State, Arg, 01004 Att->getOwnKind() == OwnershipAttr::Holds, 01005 ReleasedAllocated); 01006 if (StateI) 01007 State = StateI; 01008 } 01009 return State; 01010 } 01011 01012 ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, 01013 const CallExpr *CE, 01014 ProgramStateRef state, 01015 unsigned Num, 01016 bool Hold, 01017 bool &ReleasedAllocated, 01018 bool ReturnsNullOnFailure) const { 01019 if (CE->getNumArgs() < (Num + 1)) 01020 return nullptr; 01021 01022 return FreeMemAux(C, CE->getArg(Num), CE, state, Hold, 01023 ReleasedAllocated, ReturnsNullOnFailure); 01024 } 01025 01026 /// Checks if the previous call to free on the given symbol failed - if free 01027 /// failed, returns true. Also, returns the corresponding return value symbol. 01028 static bool didPreviousFreeFail(ProgramStateRef State, 01029 SymbolRef Sym, SymbolRef &RetStatusSymbol) { 01030 const SymbolRef *Ret = State->get<FreeReturnValue>(Sym); 01031 if (Ret) { 01032 assert(*Ret && "We should not store the null return symbol"); 01033 ConstraintManager &CMgr = State->getConstraintManager(); 01034 ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret); 01035 RetStatusSymbol = *Ret; 01036 return FreeFailed.isConstrainedTrue(); 01037 } 01038 return false; 01039 } 01040 01041 AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C, 01042 const Stmt *S) const { 01043 if (!S) 01044 return AF_None; 01045 01046 if (const CallExpr *CE = dyn_cast<CallExpr>(S)) { 01047 const FunctionDecl *FD = C.getCalleeDecl(CE); 01048 01049 if (!FD) 01050 FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl()); 01051 01052 ASTContext &Ctx = C.getASTContext(); 01053 01054 if (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any)) 01055 return AF_Malloc; 01056 01057 if (isStandardNewDelete(FD, Ctx)) { 01058 OverloadedOperatorKind Kind = FD->getOverloadedOperator(); 01059 if (Kind == OO_New || Kind == OO_Delete) 01060 return AF_CXXNew; 01061 else if (Kind == OO_Array_New || Kind == OO_Array_Delete) 01062 return AF_CXXNewArray; 01063 } 01064 01065 if (isCMemFunction(FD, Ctx, AF_IfNameIndex, MemoryOperationKind::MOK_Any)) 01066 return AF_IfNameIndex; 01067 01068 return AF_None; 01069 } 01070 01071 if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(S)) 01072 return NE->isArray() ? AF_CXXNewArray : AF_CXXNew; 01073 01074 if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(S)) 01075 return DE->isArrayForm() ? AF_CXXNewArray : AF_CXXNew; 01076 01077 if (isa<ObjCMessageExpr>(S)) 01078 return AF_Malloc; 01079 01080 return AF_None; 01081 } 01082 01083 bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C, 01084 const Expr *E) const { 01085 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) { 01086 // FIXME: This doesn't handle indirect calls. 01087 const FunctionDecl *FD = CE->getDirectCallee(); 01088 if (!FD) 01089 return false; 01090 01091 os << *FD; 01092 if (!FD->isOverloadedOperator()) 01093 os << "()"; 01094 return true; 01095 } 01096 01097 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) { 01098 if (Msg->isInstanceMessage()) 01099 os << "-"; 01100 else 01101 os << "+"; 01102 Msg->getSelector().print(os); 01103 return true; 01104 } 01105 01106 if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) { 01107 os << "'" 01108 << getOperatorSpelling(NE->getOperatorNew()->getOverloadedOperator()) 01109 << "'"; 01110 return true; 01111 } 01112 01113 if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(E)) { 01114 os << "'" 01115 << getOperatorSpelling(DE->getOperatorDelete()->getOverloadedOperator()) 01116 << "'"; 01117 return true; 01118 } 01119 01120 return false; 01121 } 01122 01123 void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C, 01124 const Expr *E) const { 01125 AllocationFamily Family = getAllocationFamily(C, E); 01126 01127 switch(Family) { 01128 case AF_Malloc: os << "malloc()"; return; 01129 case AF_CXXNew: os << "'new'"; return; 01130 case AF_CXXNewArray: os << "'new[]'"; return; 01131 case AF_IfNameIndex: os << "'if_nameindex()'"; return; 01132 case AF_None: llvm_unreachable("not a deallocation expression"); 01133 } 01134 } 01135 01136 void MallocChecker::printExpectedDeallocName(raw_ostream &os, 01137 AllocationFamily Family) const { 01138 switch(Family) { 01139 case AF_Malloc: os << "free()"; return; 01140 case AF_CXXNew: os << "'delete'"; return; 01141 case AF_CXXNewArray: os << "'delete[]'"; return; 01142 case AF_IfNameIndex: os << "'if_freenameindex()'"; return; 01143 case AF_None: llvm_unreachable("suspicious AF_None argument"); 01144 } 01145 } 01146 01147 ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, 01148 const Expr *ArgExpr, 01149 const Expr *ParentExpr, 01150 ProgramStateRef State, 01151 bool Hold, 01152 bool &ReleasedAllocated, 01153 bool ReturnsNullOnFailure) const { 01154 01155 SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext()); 01156 if (!ArgVal.getAs<DefinedOrUnknownSVal>()) 01157 return nullptr; 01158 DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>(); 01159 01160 // Check for null dereferences. 01161 if (!location.getAs<Loc>()) 01162 return nullptr; 01163 01164 // The explicit NULL case, no operation is performed. 01165 ProgramStateRef notNullState, nullState; 01166 std::tie(notNullState, nullState) = State->assume(location); 01167 if (nullState && !notNullState) 01168 return nullptr; 01169 01170 // Unknown values could easily be okay 01171 // Undefined values are handled elsewhere 01172 if (ArgVal.isUnknownOrUndef()) 01173 return nullptr; 01174 01175 const MemRegion *R = ArgVal.getAsRegion(); 01176 01177 // Nonlocs can't be freed, of course. 01178 // Non-region locations (labels and fixed addresses) also shouldn't be freed. 01179 if (!R) { 01180 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr); 01181 return nullptr; 01182 } 01183 01184 R = R->StripCasts(); 01185 01186 // Blocks might show up as heap data, but should not be free()d 01187 if (isa<BlockDataRegion>(R)) { 01188 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr); 01189 return nullptr; 01190 } 01191 01192 const MemSpaceRegion *MS = R->getMemorySpace(); 01193 01194 // Parameters, locals, statics, globals, and memory returned by alloca() 01195 // shouldn't be freed. 01196 if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) { 01197 // FIXME: at the time this code was written, malloc() regions were 01198 // represented by conjured symbols, which are all in UnknownSpaceRegion. 01199 // This means that there isn't actually anything from HeapSpaceRegion 01200 // that should be freed, even though we allow it here. 01201 // Of course, free() can work on memory allocated outside the current 01202 // function, so UnknownSpaceRegion is always a possibility. 01203 // False negatives are better than false positives. 01204 01205 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr); 01206 return nullptr; 01207 } 01208 01209 const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion()); 01210 // Various cases could lead to non-symbol values here. 01211 // For now, ignore them. 01212 if (!SrBase) 01213 return nullptr; 01214 01215 SymbolRef SymBase = SrBase->getSymbol(); 01216 const RefState *RsBase = State->get<RegionState>(SymBase); 01217 SymbolRef PreviousRetStatusSymbol = nullptr; 01218 01219 if (RsBase) { 01220 01221 // Check for double free first. 01222 if ((RsBase->isReleased() || RsBase->isRelinquished()) && 01223 !didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)) { 01224 ReportDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(), 01225 SymBase, PreviousRetStatusSymbol); 01226 return nullptr; 01227 01228 // If the pointer is allocated or escaped, but we are now trying to free it, 01229 // check that the call to free is proper. 01230 } else if (RsBase->isAllocated() || RsBase->isEscaped()) { 01231 01232 // Check if an expected deallocation function matches the real one. 01233 bool DeallocMatchesAlloc = 01234 RsBase->getAllocationFamily() == getAllocationFamily(C, ParentExpr); 01235 if (!DeallocMatchesAlloc) { 01236 ReportMismatchedDealloc(C, ArgExpr->getSourceRange(), 01237 ParentExpr, RsBase, SymBase, Hold); 01238 return nullptr; 01239 } 01240 01241 // Check if the memory location being freed is the actual location 01242 // allocated, or an offset. 01243 RegionOffset Offset = R->getAsOffset(); 01244 if (Offset.isValid() && 01245 !Offset.hasSymbolicOffset() && 01246 Offset.getOffset() != 0) { 01247 const Expr *AllocExpr = cast<Expr>(RsBase->getStmt()); 01248 ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr, 01249 AllocExpr); 01250 return nullptr; 01251 } 01252 } 01253 } 01254 01255 ReleasedAllocated = (RsBase != nullptr) && RsBase->isAllocated(); 01256 01257 // Clean out the info on previous call to free return info. 01258 State = State->remove<FreeReturnValue>(SymBase); 01259 01260 // Keep track of the return value. If it is NULL, we will know that free 01261 // failed. 01262 if (ReturnsNullOnFailure) { 01263 SVal RetVal = C.getSVal(ParentExpr); 01264 SymbolRef RetStatusSymbol = RetVal.getAsSymbol(); 01265 if (RetStatusSymbol) { 01266 C.getSymbolManager().addSymbolDependency(SymBase, RetStatusSymbol); 01267 State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol); 01268 } 01269 } 01270 01271 AllocationFamily Family = RsBase ? RsBase->getAllocationFamily() 01272 : getAllocationFamily(C, ParentExpr); 01273 // Normal free. 01274 if (Hold) 01275 return State->set<RegionState>(SymBase, 01276 RefState::getRelinquished(Family, 01277 ParentExpr)); 01278 01279 return State->set<RegionState>(SymBase, 01280 RefState::getReleased(Family, ParentExpr)); 01281 } 01282 01283 Optional<MallocChecker::CheckKind> 01284 MallocChecker::getCheckIfTracked(AllocationFamily Family) const { 01285 switch (Family) { 01286 case AF_Malloc: 01287 case AF_IfNameIndex: { 01288 if (ChecksEnabled[CK_MallocOptimistic]) { 01289 return CK_MallocOptimistic; 01290 } else if (ChecksEnabled[CK_MallocPessimistic]) { 01291 return CK_MallocPessimistic; 01292 } 01293 return Optional<MallocChecker::CheckKind>(); 01294 } 01295 case AF_CXXNew: 01296 case AF_CXXNewArray: { 01297 if (ChecksEnabled[CK_NewDeleteChecker]) { 01298 return CK_NewDeleteChecker; 01299 } 01300 return Optional<MallocChecker::CheckKind>(); 01301 } 01302 case AF_None: { 01303 llvm_unreachable("no family"); 01304 } 01305 } 01306 llvm_unreachable("unhandled family"); 01307 } 01308 01309 Optional<MallocChecker::CheckKind> 01310 MallocChecker::getCheckIfTracked(CheckerContext &C, 01311 const Stmt *AllocDeallocStmt) const { 01312 return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt)); 01313 } 01314 01315 Optional<MallocChecker::CheckKind> 01316 MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym) const { 01317 01318 const RefState *RS = C.getState()->get<RegionState>(Sym); 01319 assert(RS); 01320 return getCheckIfTracked(RS->getAllocationFamily()); 01321 } 01322 01323 bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) { 01324 if (Optional<nonloc::ConcreteInt> IntVal = V.getAs<nonloc::ConcreteInt>()) 01325 os << "an integer (" << IntVal->getValue() << ")"; 01326 else if (Optional<loc::ConcreteInt> ConstAddr = V.getAs<loc::ConcreteInt>()) 01327 os << "a constant address (" << ConstAddr->getValue() << ")"; 01328 else if (Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>()) 01329 os << "the address of the label '" << Label->getLabel()->getName() << "'"; 01330 else 01331 return false; 01332 01333 return true; 01334 } 01335 01336 bool MallocChecker::SummarizeRegion(raw_ostream &os, 01337 const MemRegion *MR) { 01338 switch (MR->getKind()) { 01339 case MemRegion::FunctionTextRegionKind: { 01340 const NamedDecl *FD = cast<FunctionTextRegion>(MR)->getDecl(); 01341 if (FD) 01342 os << "the address of the function '" << *FD << '\''; 01343 else 01344 os << "the address of a function"; 01345 return true; 01346 } 01347 case MemRegion::BlockTextRegionKind: 01348 os << "block text"; 01349 return true; 01350 case MemRegion::BlockDataRegionKind: 01351 // FIXME: where the block came from? 01352 os << "a block"; 01353 return true; 01354 default: { 01355 const MemSpaceRegion *MS = MR->getMemorySpace(); 01356 01357 if (isa<StackLocalsSpaceRegion>(MS)) { 01358 const VarRegion *VR = dyn_cast<VarRegion>(MR); 01359 const VarDecl *VD; 01360 if (VR) 01361 VD = VR->getDecl(); 01362 else 01363 VD = nullptr; 01364 01365 if (VD) 01366 os << "the address of the local variable '" << VD->getName() << "'"; 01367 else 01368 os << "the address of a local stack variable"; 01369 return true; 01370 } 01371 01372 if (isa<StackArgumentsSpaceRegion>(MS)) { 01373 const VarRegion *VR = dyn_cast<VarRegion>(MR); 01374 const VarDecl *VD; 01375 if (VR) 01376 VD = VR->getDecl(); 01377 else 01378 VD = nullptr; 01379 01380 if (VD) 01381 os << "the address of the parameter '" << VD->getName() << "'"; 01382 else 01383 os << "the address of a parameter"; 01384 return true; 01385 } 01386 01387 if (isa<GlobalsSpaceRegion>(MS)) { 01388 const VarRegion *VR = dyn_cast<VarRegion>(MR); 01389 const VarDecl *VD; 01390 if (VR) 01391 VD = VR->getDecl(); 01392 else 01393 VD = nullptr; 01394 01395 if (VD) { 01396 if (VD->isStaticLocal()) 01397 os << "the address of the static variable '" << VD->getName() << "'"; 01398 else 01399 os << "the address of the global variable '" << VD->getName() << "'"; 01400 } else 01401 os << "the address of a global variable"; 01402 return true; 01403 } 01404 01405 return false; 01406 } 01407 } 01408 } 01409 01410 void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal, 01411 SourceRange Range, 01412 const Expr *DeallocExpr) const { 01413 01414 if (!ChecksEnabled[CK_MallocOptimistic] && 01415 !ChecksEnabled[CK_MallocPessimistic] && 01416 !ChecksEnabled[CK_NewDeleteChecker]) 01417 return; 01418 01419 Optional<MallocChecker::CheckKind> CheckKind = 01420 getCheckIfTracked(C, DeallocExpr); 01421 if (!CheckKind.hasValue()) 01422 return; 01423 01424 if (ExplodedNode *N = C.generateSink()) { 01425 if (!BT_BadFree[*CheckKind]) 01426 BT_BadFree[*CheckKind].reset( 01427 new BugType(CheckNames[*CheckKind], "Bad free", "Memory Error")); 01428 01429 SmallString<100> buf; 01430 llvm::raw_svector_ostream os(buf); 01431 01432 const MemRegion *MR = ArgVal.getAsRegion(); 01433 while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR)) 01434 MR = ER->getSuperRegion(); 01435 01436 if (MR && isa<AllocaRegion>(MR)) 01437 os << "Memory allocated by alloca() should not be deallocated"; 01438 else { 01439 os << "Argument to "; 01440 if (!printAllocDeallocName(os, C, DeallocExpr)) 01441 os << "deallocator"; 01442 01443 os << " is "; 01444 bool Summarized = MR ? SummarizeRegion(os, MR) 01445 : SummarizeValue(os, ArgVal); 01446 if (Summarized) 01447 os << ", which is not memory allocated by "; 01448 else 01449 os << "not memory allocated by "; 01450 01451 printExpectedAllocName(os, C, DeallocExpr); 01452 } 01453 01454 BugReport *R = new BugReport(*BT_BadFree[*CheckKind], os.str(), N); 01455 R->markInteresting(MR); 01456 R->addRange(Range); 01457 C.emitReport(R); 01458 } 01459 } 01460 01461 void MallocChecker::ReportMismatchedDealloc(CheckerContext &C, 01462 SourceRange Range, 01463 const Expr *DeallocExpr, 01464 const RefState *RS, 01465 SymbolRef Sym, 01466 bool OwnershipTransferred) const { 01467 01468 if (!ChecksEnabled[CK_MismatchedDeallocatorChecker]) 01469 return; 01470 01471 if (ExplodedNode *N = C.generateSink()) { 01472 if (!BT_MismatchedDealloc) 01473 BT_MismatchedDealloc.reset( 01474 new BugType(CheckNames[CK_MismatchedDeallocatorChecker], 01475 "Bad deallocator", "Memory Error")); 01476 01477 SmallString<100> buf; 01478 llvm::raw_svector_ostream os(buf); 01479 01480 const Expr *AllocExpr = cast<Expr>(RS->getStmt()); 01481 SmallString<20> AllocBuf; 01482 llvm::raw_svector_ostream AllocOs(AllocBuf); 01483 SmallString<20> DeallocBuf; 01484 llvm::raw_svector_ostream DeallocOs(DeallocBuf); 01485 01486 if (OwnershipTransferred) { 01487 if (printAllocDeallocName(DeallocOs, C, DeallocExpr)) 01488 os << DeallocOs.str() << " cannot"; 01489 else 01490 os << "Cannot"; 01491 01492 os << " take ownership of memory"; 01493 01494 if (printAllocDeallocName(AllocOs, C, AllocExpr)) 01495 os << " allocated by " << AllocOs.str(); 01496 } else { 01497 os << "Memory"; 01498 if (printAllocDeallocName(AllocOs, C, AllocExpr)) 01499 os << " allocated by " << AllocOs.str(); 01500 01501 os << " should be deallocated by "; 01502 printExpectedDeallocName(os, RS->getAllocationFamily()); 01503 01504 if (printAllocDeallocName(DeallocOs, C, DeallocExpr)) 01505 os << ", not " << DeallocOs.str(); 01506 } 01507 01508 BugReport *R = new BugReport(*BT_MismatchedDealloc, os.str(), N); 01509 R->markInteresting(Sym); 01510 R->addRange(Range); 01511 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym)); 01512 C.emitReport(R); 01513 } 01514 } 01515 01516 void MallocChecker::ReportOffsetFree(CheckerContext &C, SVal ArgVal, 01517 SourceRange Range, const Expr *DeallocExpr, 01518 const Expr *AllocExpr) const { 01519 01520 if (!ChecksEnabled[CK_MallocOptimistic] && 01521 !ChecksEnabled[CK_MallocPessimistic] && 01522 !ChecksEnabled[CK_NewDeleteChecker]) 01523 return; 01524 01525 Optional<MallocChecker::CheckKind> CheckKind = 01526 getCheckIfTracked(C, AllocExpr); 01527 if (!CheckKind.hasValue()) 01528 return; 01529 01530 ExplodedNode *N = C.generateSink(); 01531 if (!N) 01532 return; 01533 01534 if (!BT_OffsetFree[*CheckKind]) 01535 BT_OffsetFree[*CheckKind].reset( 01536 new BugType(CheckNames[*CheckKind], "Offset free", "Memory Error")); 01537 01538 SmallString<100> buf; 01539 llvm::raw_svector_ostream os(buf); 01540 SmallString<20> AllocNameBuf; 01541 llvm::raw_svector_ostream AllocNameOs(AllocNameBuf); 01542 01543 const MemRegion *MR = ArgVal.getAsRegion(); 01544 assert(MR && "Only MemRegion based symbols can have offset free errors"); 01545 01546 RegionOffset Offset = MR->getAsOffset(); 01547 assert((Offset.isValid() && 01548 !Offset.hasSymbolicOffset() && 01549 Offset.getOffset() != 0) && 01550 "Only symbols with a valid offset can have offset free errors"); 01551 01552 int offsetBytes = Offset.getOffset() / C.getASTContext().getCharWidth(); 01553 01554 os << "Argument to "; 01555 if (!printAllocDeallocName(os, C, DeallocExpr)) 01556 os << "deallocator"; 01557 os << " is offset by " 01558 << offsetBytes 01559 << " " 01560 << ((abs(offsetBytes) > 1) ? "bytes" : "byte") 01561 << " from the start of "; 01562 if (AllocExpr && printAllocDeallocName(AllocNameOs, C, AllocExpr)) 01563 os << "memory allocated by " << AllocNameOs.str(); 01564 else 01565 os << "allocated memory"; 01566 01567 BugReport *R = new BugReport(*BT_OffsetFree[*CheckKind], os.str(), N); 01568 R->markInteresting(MR->getBaseRegion()); 01569 R->addRange(Range); 01570 C.emitReport(R); 01571 } 01572 01573 void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range, 01574 SymbolRef Sym) const { 01575 01576 if (!ChecksEnabled[CK_MallocOptimistic] && 01577 !ChecksEnabled[CK_MallocPessimistic] && 01578 !ChecksEnabled[CK_NewDeleteChecker]) 01579 return; 01580 01581 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym); 01582 if (!CheckKind.hasValue()) 01583 return; 01584 01585 if (ExplodedNode *N = C.generateSink()) { 01586 if (!BT_UseFree[*CheckKind]) 01587 BT_UseFree[*CheckKind].reset(new BugType( 01588 CheckNames[*CheckKind], "Use-after-free", "Memory Error")); 01589 01590 BugReport *R = new BugReport(*BT_UseFree[*CheckKind], 01591 "Use of memory after it is freed", N); 01592 01593 R->markInteresting(Sym); 01594 R->addRange(Range); 01595 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym)); 01596 C.emitReport(R); 01597 } 01598 } 01599 01600 void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range, 01601 bool Released, SymbolRef Sym, 01602 SymbolRef PrevSym) const { 01603 01604 if (!ChecksEnabled[CK_MallocOptimistic] && 01605 !ChecksEnabled[CK_MallocPessimistic] && 01606 !ChecksEnabled[CK_NewDeleteChecker]) 01607 return; 01608 01609 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym); 01610 if (!CheckKind.hasValue()) 01611 return; 01612 01613 if (ExplodedNode *N = C.generateSink()) { 01614 if (!BT_DoubleFree[*CheckKind]) 01615 BT_DoubleFree[*CheckKind].reset( 01616 new BugType(CheckNames[*CheckKind], "Double free", "Memory Error")); 01617 01618 BugReport *R = 01619 new BugReport(*BT_DoubleFree[*CheckKind], 01620 (Released ? "Attempt to free released memory" 01621 : "Attempt to free non-owned memory"), 01622 N); 01623 R->addRange(Range); 01624 R->markInteresting(Sym); 01625 if (PrevSym) 01626 R->markInteresting(PrevSym); 01627 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym)); 01628 C.emitReport(R); 01629 } 01630 } 01631 01632 void MallocChecker::ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const { 01633 01634 if (!ChecksEnabled[CK_NewDeleteChecker]) 01635 return; 01636 01637 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym); 01638 if (!CheckKind.hasValue()) 01639 return; 01640 assert(*CheckKind == CK_NewDeleteChecker && "invalid check kind"); 01641 01642 if (ExplodedNode *N = C.generateSink()) { 01643 if (!BT_DoubleDelete) 01644 BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker], 01645 "Double delete", "Memory Error")); 01646 01647 BugReport *R = new BugReport(*BT_DoubleDelete, 01648 "Attempt to delete released memory", N); 01649 01650 R->markInteresting(Sym); 01651 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym)); 01652 C.emitReport(R); 01653 } 01654 } 01655 01656 ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C, 01657 const CallExpr *CE, 01658 bool FreesOnFail) const { 01659 if (CE->getNumArgs() < 2) 01660 return nullptr; 01661 01662 ProgramStateRef state = C.getState(); 01663 const Expr *arg0Expr = CE->getArg(0); 01664 const LocationContext *LCtx = C.getLocationContext(); 01665 SVal Arg0Val = state->getSVal(arg0Expr, LCtx); 01666 if (!Arg0Val.getAs<DefinedOrUnknownSVal>()) 01667 return nullptr; 01668 DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>(); 01669 01670 SValBuilder &svalBuilder = C.getSValBuilder(); 01671 01672 DefinedOrUnknownSVal PtrEQ = 01673 svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull()); 01674 01675 // Get the size argument. If there is no size arg then give up. 01676 const Expr *Arg1 = CE->getArg(1); 01677 if (!Arg1) 01678 return nullptr; 01679 01680 // Get the value of the size argument. 01681 SVal Arg1ValG = state->getSVal(Arg1, LCtx); 01682 if (!Arg1ValG.getAs<DefinedOrUnknownSVal>()) 01683 return nullptr; 01684 DefinedOrUnknownSVal Arg1Val = Arg1ValG.castAs<DefinedOrUnknownSVal>(); 01685 01686 // Compare the size argument to 0. 01687 DefinedOrUnknownSVal SizeZero = 01688 svalBuilder.evalEQ(state, Arg1Val, 01689 svalBuilder.makeIntValWithPtrWidth(0, false)); 01690 01691 ProgramStateRef StatePtrIsNull, StatePtrNotNull; 01692 std::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ); 01693 ProgramStateRef StateSizeIsZero, StateSizeNotZero; 01694 std::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero); 01695 // We only assume exceptional states if they are definitely true; if the 01696 // state is under-constrained, assume regular realloc behavior. 01697 bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull; 01698 bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero; 01699 01700 // If the ptr is NULL and the size is not 0, the call is equivalent to 01701 // malloc(size). 01702 if ( PrtIsNull && !SizeIsZero) { 01703 ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1), 01704 UndefinedVal(), StatePtrIsNull); 01705 return stateMalloc; 01706 } 01707 01708 if (PrtIsNull && SizeIsZero) 01709 return nullptr; 01710 01711 // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size). 01712 assert(!PrtIsNull); 01713 SymbolRef FromPtr = arg0Val.getAsSymbol(); 01714 SVal RetVal = state->getSVal(CE, LCtx); 01715 SymbolRef ToPtr = RetVal.getAsSymbol(); 01716 if (!FromPtr || !ToPtr) 01717 return nullptr; 01718 01719 bool ReleasedAllocated = false; 01720 01721 // If the size is 0, free the memory. 01722 if (SizeIsZero) 01723 if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero, 0, 01724 false, ReleasedAllocated)){ 01725 // The semantics of the return value are: 01726 // If size was equal to 0, either NULL or a pointer suitable to be passed 01727 // to free() is returned. We just free the input pointer and do not add 01728 // any constrains on the output pointer. 01729 return stateFree; 01730 } 01731 01732 // Default behavior. 01733 if (ProgramStateRef stateFree = 01734 FreeMemAux(C, CE, state, 0, false, ReleasedAllocated)) { 01735 01736 ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1), 01737 UnknownVal(), stateFree); 01738 if (!stateRealloc) 01739 return nullptr; 01740 01741 ReallocPairKind Kind = RPToBeFreedAfterFailure; 01742 if (FreesOnFail) 01743 Kind = RPIsFreeOnFailure; 01744 else if (!ReleasedAllocated) 01745 Kind = RPDoNotTrackAfterFailure; 01746 01747 // Record the info about the reallocated symbol so that we could properly 01748 // process failed reallocation. 01749 stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr, 01750 ReallocPair(FromPtr, Kind)); 01751 // The reallocated symbol should stay alive for as long as the new symbol. 01752 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr); 01753 return stateRealloc; 01754 } 01755 return nullptr; 01756 } 01757 01758 ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){ 01759 if (CE->getNumArgs() < 2) 01760 return nullptr; 01761 01762 ProgramStateRef state = C.getState(); 01763 SValBuilder &svalBuilder = C.getSValBuilder(); 01764 const LocationContext *LCtx = C.getLocationContext(); 01765 SVal count = state->getSVal(CE->getArg(0), LCtx); 01766 SVal elementSize = state->getSVal(CE->getArg(1), LCtx); 01767 SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize, 01768 svalBuilder.getContext().getSizeType()); 01769 SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); 01770 01771 return MallocMemAux(C, CE, TotalSize, zeroVal, state); 01772 } 01773 01774 LeakInfo 01775 MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym, 01776 CheckerContext &C) const { 01777 const LocationContext *LeakContext = N->getLocationContext(); 01778 // Walk the ExplodedGraph backwards and find the first node that referred to 01779 // the tracked symbol. 01780 const ExplodedNode *AllocNode = N; 01781 const MemRegion *ReferenceRegion = nullptr; 01782 01783 while (N) { 01784 ProgramStateRef State = N->getState(); 01785 if (!State->get<RegionState>(Sym)) 01786 break; 01787 01788 // Find the most recent expression bound to the symbol in the current 01789 // context. 01790 if (!ReferenceRegion) { 01791 if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) { 01792 SVal Val = State->getSVal(MR); 01793 if (Val.getAsLocSymbol() == Sym) { 01794 const VarRegion* VR = MR->getBaseRegion()->getAs<VarRegion>(); 01795 // Do not show local variables belonging to a function other than 01796 // where the error is reported. 01797 if (!VR || 01798 (VR->getStackFrame() == LeakContext->getCurrentStackFrame())) 01799 ReferenceRegion = MR; 01800 } 01801 } 01802 } 01803 01804 // Allocation node, is the last node in the current context in which the 01805 // symbol was tracked. 01806 if (N->getLocationContext() == LeakContext) 01807 AllocNode = N; 01808 N = N->pred_empty() ? nullptr : *(N->pred_begin()); 01809 } 01810 01811 return LeakInfo(AllocNode, ReferenceRegion); 01812 } 01813 01814 void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N, 01815 CheckerContext &C) const { 01816 01817 if (!ChecksEnabled[CK_MallocOptimistic] && 01818 !ChecksEnabled[CK_MallocPessimistic] && 01819 !ChecksEnabled[CK_NewDeleteLeaksChecker]) 01820 return; 01821 01822 const RefState *RS = C.getState()->get<RegionState>(Sym); 01823 assert(RS && "cannot leak an untracked symbol"); 01824 AllocationFamily Family = RS->getAllocationFamily(); 01825 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family); 01826 if (!CheckKind.hasValue()) 01827 return; 01828 01829 // Special case for new and new[]; these are controlled by a separate checker 01830 // flag so that they can be selectively disabled. 01831 if (Family == AF_CXXNew || Family == AF_CXXNewArray) 01832 if (!ChecksEnabled[CK_NewDeleteLeaksChecker]) 01833 return; 01834 01835 assert(N); 01836 if (!BT_Leak[*CheckKind]) { 01837 BT_Leak[*CheckKind].reset( 01838 new BugType(CheckNames[*CheckKind], "Memory leak", "Memory Error")); 01839 // Leaks should not be reported if they are post-dominated by a sink: 01840 // (1) Sinks are higher importance bugs. 01841 // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending 01842 // with __noreturn functions such as assert() or exit(). We choose not 01843 // to report leaks on such paths. 01844 BT_Leak[*CheckKind]->setSuppressOnSink(true); 01845 } 01846 01847 // Most bug reports are cached at the location where they occurred. 01848 // With leaks, we want to unique them by the location where they were 01849 // allocated, and only report a single path. 01850 PathDiagnosticLocation LocUsedForUniqueing; 01851 const ExplodedNode *AllocNode = nullptr; 01852 const MemRegion *Region = nullptr; 01853 std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C); 01854 01855 ProgramPoint P = AllocNode->getLocation(); 01856 const Stmt *AllocationStmt = nullptr; 01857 if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>()) 01858 AllocationStmt = Exit->getCalleeContext()->getCallSite(); 01859 else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>()) 01860 AllocationStmt = SP->getStmt(); 01861 if (AllocationStmt) 01862 LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt, 01863 C.getSourceManager(), 01864 AllocNode->getLocationContext()); 01865 01866 SmallString<200> buf; 01867 llvm::raw_svector_ostream os(buf); 01868 if (Region && Region->canPrintPretty()) { 01869 os << "Potential leak of memory pointed to by "; 01870 Region->printPretty(os); 01871 } else { 01872 os << "Potential memory leak"; 01873 } 01874 01875 BugReport *R = 01876 new BugReport(*BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing, 01877 AllocNode->getLocationContext()->getDecl()); 01878 R->markInteresting(Sym); 01879 R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym, true)); 01880 C.emitReport(R); 01881 } 01882 01883 void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper, 01884 CheckerContext &C) const 01885 { 01886 if (!SymReaper.hasDeadSymbols()) 01887 return; 01888 01889 ProgramStateRef state = C.getState(); 01890 RegionStateTy RS = state->get<RegionState>(); 01891 RegionStateTy::Factory &F = state->get_context<RegionState>(); 01892 01893 SmallVector<SymbolRef, 2> Errors; 01894 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { 01895 if (SymReaper.isDead(I->first)) { 01896 if (I->second.isAllocated()) 01897 Errors.push_back(I->first); 01898 // Remove the dead symbol from the map. 01899 RS = F.remove(RS, I->first); 01900 01901 } 01902 } 01903 01904 // Cleanup the Realloc Pairs Map. 01905 ReallocPairsTy RP = state->get<ReallocPairs>(); 01906 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) { 01907 if (SymReaper.isDead(I->first) || 01908 SymReaper.isDead(I->second.ReallocatedSym)) { 01909 state = state->remove<ReallocPairs>(I->first); 01910 } 01911 } 01912 01913 // Cleanup the FreeReturnValue Map. 01914 FreeReturnValueTy FR = state->get<FreeReturnValue>(); 01915 for (FreeReturnValueTy::iterator I = FR.begin(), E = FR.end(); I != E; ++I) { 01916 if (SymReaper.isDead(I->first) || 01917 SymReaper.isDead(I->second)) { 01918 state = state->remove<FreeReturnValue>(I->first); 01919 } 01920 } 01921 01922 // Generate leak node. 01923 ExplodedNode *N = C.getPredecessor(); 01924 if (!Errors.empty()) { 01925 static CheckerProgramPointTag Tag("MallocChecker", "DeadSymbolsLeak"); 01926 N = C.addTransition(C.getState(), C.getPredecessor(), &Tag); 01927 for (SmallVectorImpl<SymbolRef>::iterator 01928 I = Errors.begin(), E = Errors.end(); I != E; ++I) { 01929 reportLeak(*I, N, C); 01930 } 01931 } 01932 01933 C.addTransition(state->set<RegionState>(RS), N); 01934 } 01935 01936 void MallocChecker::checkPreCall(const CallEvent &Call, 01937 CheckerContext &C) const { 01938 01939 if (const CXXDestructorCall *DC = dyn_cast<CXXDestructorCall>(&Call)) { 01940 SymbolRef Sym = DC->getCXXThisVal().getAsSymbol(); 01941 if (!Sym || checkDoubleDelete(Sym, C)) 01942 return; 01943 } 01944 01945 // We will check for double free in the post visit. 01946 if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) { 01947 const FunctionDecl *FD = FC->getDecl(); 01948 if (!FD) 01949 return; 01950 01951 ASTContext &Ctx = C.getASTContext(); 01952 if ((ChecksEnabled[CK_MallocOptimistic] || 01953 ChecksEnabled[CK_MallocPessimistic]) && 01954 (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Free) || 01955 isCMemFunction(FD, Ctx, AF_IfNameIndex, 01956 MemoryOperationKind::MOK_Free))) 01957 return; 01958 01959 if (ChecksEnabled[CK_NewDeleteChecker] && 01960 isStandardNewDelete(FD, Ctx)) 01961 return; 01962 } 01963 01964 // Check if the callee of a method is deleted. 01965 if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) { 01966 SymbolRef Sym = CC->getCXXThisVal().getAsSymbol(); 01967 if (!Sym || checkUseAfterFree(Sym, C, CC->getCXXThisExpr())) 01968 return; 01969 } 01970 01971 // Check arguments for being used after free. 01972 for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) { 01973 SVal ArgSVal = Call.getArgSVal(I); 01974 if (ArgSVal.getAs<Loc>()) { 01975 SymbolRef Sym = ArgSVal.getAsSymbol(); 01976 if (!Sym) 01977 continue; 01978 if (checkUseAfterFree(Sym, C, Call.getArgExpr(I))) 01979 return; 01980 } 01981 } 01982 } 01983 01984 void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const { 01985 const Expr *E = S->getRetValue(); 01986 if (!E) 01987 return; 01988 01989 // Check if we are returning a symbol. 01990 ProgramStateRef State = C.getState(); 01991 SVal RetVal = State->getSVal(E, C.getLocationContext()); 01992 SymbolRef Sym = RetVal.getAsSymbol(); 01993 if (!Sym) 01994 // If we are returning a field of the allocated struct or an array element, 01995 // the callee could still free the memory. 01996 // TODO: This logic should be a part of generic symbol escape callback. 01997 if (const MemRegion *MR = RetVal.getAsRegion()) 01998 if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR)) 01999 if (const SymbolicRegion *BMR = 02000 dyn_cast<SymbolicRegion>(MR->getBaseRegion())) 02001 Sym = BMR->getSymbol(); 02002 02003 // Check if we are returning freed memory. 02004 if (Sym) 02005 checkUseAfterFree(Sym, C, E); 02006 } 02007 02008 // TODO: Blocks should be either inlined or should call invalidate regions 02009 // upon invocation. After that's in place, special casing here will not be 02010 // needed. 02011 void MallocChecker::checkPostStmt(const BlockExpr *BE, 02012 CheckerContext &C) const { 02013 02014 // Scan the BlockDecRefExprs for any object the retain count checker 02015 // may be tracking. 02016 if (!BE->getBlockDecl()->hasCaptures()) 02017 return; 02018 02019 ProgramStateRef state = C.getState(); 02020 const BlockDataRegion *R = 02021 cast<BlockDataRegion>(state->getSVal(BE, 02022 C.getLocationContext()).getAsRegion()); 02023 02024 BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(), 02025 E = R->referenced_vars_end(); 02026 02027 if (I == E) 02028 return; 02029 02030 SmallVector<const MemRegion*, 10> Regions; 02031 const LocationContext *LC = C.getLocationContext(); 02032 MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager(); 02033 02034 for ( ; I != E; ++I) { 02035 const VarRegion *VR = I.getCapturedRegion(); 02036 if (VR->getSuperRegion() == R) { 02037 VR = MemMgr.getVarRegion(VR->getDecl(), LC); 02038 } 02039 Regions.push_back(VR); 02040 } 02041 02042 state = 02043 state->scanReachableSymbols<StopTrackingCallback>(Regions.data(), 02044 Regions.data() + Regions.size()).getState(); 02045 C.addTransition(state); 02046 } 02047 02048 bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const { 02049 assert(Sym); 02050 const RefState *RS = C.getState()->get<RegionState>(Sym); 02051 return (RS && RS->isReleased()); 02052 } 02053 02054 bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C, 02055 const Stmt *S) const { 02056 02057 if (isReleased(Sym, C)) { 02058 ReportUseAfterFree(C, S->getSourceRange(), Sym); 02059 return true; 02060 } 02061 02062 return false; 02063 } 02064 02065 bool MallocChecker::checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const { 02066 02067 if (isReleased(Sym, C)) { 02068 ReportDoubleDelete(C, Sym); 02069 return true; 02070 } 02071 return false; 02072 } 02073 02074 // Check if the location is a freed symbolic region. 02075 void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S, 02076 CheckerContext &C) const { 02077 SymbolRef Sym = l.getLocSymbolInBase(); 02078 if (Sym) 02079 checkUseAfterFree(Sym, C, S); 02080 } 02081 02082 // If a symbolic region is assumed to NULL (or another constant), stop tracking 02083 // it - assuming that allocation failed on this path. 02084 ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, 02085 SVal Cond, 02086 bool Assumption) const { 02087 RegionStateTy RS = state->get<RegionState>(); 02088 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { 02089 // If the symbol is assumed to be NULL, remove it from consideration. 02090 ConstraintManager &CMgr = state->getConstraintManager(); 02091 ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey()); 02092 if (AllocFailed.isConstrainedTrue()) 02093 state = state->remove<RegionState>(I.getKey()); 02094 } 02095 02096 // Realloc returns 0 when reallocation fails, which means that we should 02097 // restore the state of the pointer being reallocated. 02098 ReallocPairsTy RP = state->get<ReallocPairs>(); 02099 for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) { 02100 // If the symbol is assumed to be NULL, remove it from consideration. 02101 ConstraintManager &CMgr = state->getConstraintManager(); 02102 ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey()); 02103 if (!AllocFailed.isConstrainedTrue()) 02104 continue; 02105 02106 SymbolRef ReallocSym = I.getData().ReallocatedSym; 02107 if (const RefState *RS = state->get<RegionState>(ReallocSym)) { 02108 if (RS->isReleased()) { 02109 if (I.getData().Kind == RPToBeFreedAfterFailure) 02110 state = state->set<RegionState>(ReallocSym, 02111 RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt())); 02112 else if (I.getData().Kind == RPDoNotTrackAfterFailure) 02113 state = state->remove<RegionState>(ReallocSym); 02114 else 02115 assert(I.getData().Kind == RPIsFreeOnFailure); 02116 } 02117 } 02118 state = state->remove<ReallocPairs>(I.getKey()); 02119 } 02120 02121 return state; 02122 } 02123 02124 bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( 02125 const CallEvent *Call, 02126 ProgramStateRef State, 02127 SymbolRef &EscapingSymbol) const { 02128 assert(Call); 02129 EscapingSymbol = nullptr; 02130 02131 // For now, assume that any C++ or block call can free memory. 02132 // TODO: If we want to be more optimistic here, we'll need to make sure that 02133 // regions escape to C++ containers. They seem to do that even now, but for 02134 // mysterious reasons. 02135 if (!(isa<SimpleFunctionCall>(Call) || isa<ObjCMethodCall>(Call))) 02136 return true; 02137 02138 // Check Objective-C messages by selector name. 02139 if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) { 02140 // If it's not a framework call, or if it takes a callback, assume it 02141 // can free memory. 02142 if (!Call->isInSystemHeader() || Call->hasNonZeroCallbackArg()) 02143 return true; 02144 02145 // If it's a method we know about, handle it explicitly post-call. 02146 // This should happen before the "freeWhenDone" check below. 02147 if (isKnownDeallocObjCMethodName(*Msg)) 02148 return false; 02149 02150 // If there's a "freeWhenDone" parameter, but the method isn't one we know 02151 // about, we can't be sure that the object will use free() to deallocate the 02152 // memory, so we can't model it explicitly. The best we can do is use it to 02153 // decide whether the pointer escapes. 02154 if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(*Msg)) 02155 return *FreeWhenDone; 02156 02157 // If the first selector piece ends with "NoCopy", and there is no 02158 // "freeWhenDone" parameter set to zero, we know ownership is being 02159 // transferred. Again, though, we can't be sure that the object will use 02160 // free() to deallocate the memory, so we can't model it explicitly. 02161 StringRef FirstSlot = Msg->getSelector().getNameForSlot(0); 02162 if (FirstSlot.endswith("NoCopy")) 02163 return true; 02164 02165 // If the first selector starts with addPointer, insertPointer, 02166 // or replacePointer, assume we are dealing with NSPointerArray or similar. 02167 // This is similar to C++ containers (vector); we still might want to check 02168 // that the pointers get freed by following the container itself. 02169 if (FirstSlot.startswith("addPointer") || 02170 FirstSlot.startswith("insertPointer") || 02171 FirstSlot.startswith("replacePointer") || 02172 FirstSlot.equals("valueWithPointer")) { 02173 return true; 02174 } 02175 02176 // We should escape receiver on call to 'init'. This is especially relevant 02177 // to the receiver, as the corresponding symbol is usually not referenced 02178 // after the call. 02179 if (Msg->getMethodFamily() == OMF_init) { 02180 EscapingSymbol = Msg->getReceiverSVal().getAsSymbol(); 02181 return true; 02182 } 02183 02184 // Otherwise, assume that the method does not free memory. 02185 // Most framework methods do not free memory. 02186 return false; 02187 } 02188 02189 // At this point the only thing left to handle is straight function calls. 02190 const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl(); 02191 if (!FD) 02192 return true; 02193 02194 ASTContext &ASTC = State->getStateManager().getContext(); 02195 02196 // If it's one of the allocation functions we can reason about, we model 02197 // its behavior explicitly. 02198 if (isMemFunction(FD, ASTC)) 02199 return false; 02200 02201 // If it's not a system call, assume it frees memory. 02202 if (!Call->isInSystemHeader()) 02203 return true; 02204 02205 // White list the system functions whose arguments escape. 02206 const IdentifierInfo *II = FD->getIdentifier(); 02207 if (!II) 02208 return true; 02209 StringRef FName = II->getName(); 02210 02211 // White list the 'XXXNoCopy' CoreFoundation functions. 02212 // We specifically check these before 02213 if (FName.endswith("NoCopy")) { 02214 // Look for the deallocator argument. We know that the memory ownership 02215 // is not transferred only if the deallocator argument is 02216 // 'kCFAllocatorNull'. 02217 for (unsigned i = 1; i < Call->getNumArgs(); ++i) { 02218 const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts(); 02219 if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) { 02220 StringRef DeallocatorName = DE->getFoundDecl()->getName(); 02221 if (DeallocatorName == "kCFAllocatorNull") 02222 return false; 02223 } 02224 } 02225 return true; 02226 } 02227 02228 // Associating streams with malloced buffers. The pointer can escape if 02229 // 'closefn' is specified (and if that function does free memory), 02230 // but it will not if closefn is not specified. 02231 // Currently, we do not inspect the 'closefn' function (PR12101). 02232 if (FName == "funopen") 02233 if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0)) 02234 return false; 02235 02236 // Do not warn on pointers passed to 'setbuf' when used with std streams, 02237 // these leaks might be intentional when setting the buffer for stdio. 02238 // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer 02239 if (FName == "setbuf" || FName =="setbuffer" || 02240 FName == "setlinebuf" || FName == "setvbuf") { 02241 if (Call->getNumArgs() >= 1) { 02242 const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts(); 02243 if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE)) 02244 if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl())) 02245 if (D->getCanonicalDecl()->getName().find("std") != StringRef::npos) 02246 return true; 02247 } 02248 } 02249 02250 // A bunch of other functions which either take ownership of a pointer or 02251 // wrap the result up in a struct or object, meaning it can be freed later. 02252 // (See RetainCountChecker.) Not all the parameters here are invalidated, 02253 // but the Malloc checker cannot differentiate between them. The right way 02254 // of doing this would be to implement a pointer escapes callback. 02255 if (FName == "CGBitmapContextCreate" || 02256 FName == "CGBitmapContextCreateWithData" || 02257 FName == "CVPixelBufferCreateWithBytes" || 02258 FName == "CVPixelBufferCreateWithPlanarBytes" || 02259 FName == "OSAtomicEnqueue") { 02260 return true; 02261 } 02262 02263 // Handle cases where we know a buffer's /address/ can escape. 02264 // Note that the above checks handle some special cases where we know that 02265 // even though the address escapes, it's still our responsibility to free the 02266 // buffer. 02267 if (Call->argumentsMayEscape()) 02268 return true; 02269 02270 // Otherwise, assume that the function does not free memory. 02271 // Most system calls do not free the memory. 02272 return false; 02273 } 02274 02275 static bool retTrue(const RefState *RS) { 02276 return true; 02277 } 02278 02279 static bool checkIfNewOrNewArrayFamily(const RefState *RS) { 02280 return (RS->getAllocationFamily() == AF_CXXNewArray || 02281 RS->getAllocationFamily() == AF_CXXNew); 02282 } 02283 02284 ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State, 02285 const InvalidatedSymbols &Escaped, 02286 const CallEvent *Call, 02287 PointerEscapeKind Kind) const { 02288 return checkPointerEscapeAux(State, Escaped, Call, Kind, &retTrue); 02289 } 02290 02291 ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State, 02292 const InvalidatedSymbols &Escaped, 02293 const CallEvent *Call, 02294 PointerEscapeKind Kind) const { 02295 return checkPointerEscapeAux(State, Escaped, Call, Kind, 02296 &checkIfNewOrNewArrayFamily); 02297 } 02298 02299 ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State, 02300 const InvalidatedSymbols &Escaped, 02301 const CallEvent *Call, 02302 PointerEscapeKind Kind, 02303 bool(*CheckRefState)(const RefState*)) const { 02304 // If we know that the call does not free memory, or we want to process the 02305 // call later, keep tracking the top level arguments. 02306 SymbolRef EscapingSymbol = nullptr; 02307 if (Kind == PSK_DirectEscapeOnCall && 02308 !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State, 02309 EscapingSymbol) && 02310 !EscapingSymbol) { 02311 return State; 02312 } 02313 02314 for (InvalidatedSymbols::const_iterator I = Escaped.begin(), 02315 E = Escaped.end(); 02316 I != E; ++I) { 02317 SymbolRef sym = *I; 02318 02319 if (EscapingSymbol && EscapingSymbol != sym) 02320 continue; 02321 02322 if (const RefState *RS = State->get<RegionState>(sym)) { 02323 if (RS->isAllocated() && CheckRefState(RS)) { 02324 State = State->remove<RegionState>(sym); 02325 State = State->set<RegionState>(sym, RefState::getEscaped(RS)); 02326 } 02327 } 02328 } 02329 return State; 02330 } 02331 02332 static SymbolRef findFailedReallocSymbol(ProgramStateRef currState, 02333 ProgramStateRef prevState) { 02334 ReallocPairsTy currMap = currState->get<ReallocPairs>(); 02335 ReallocPairsTy prevMap = prevState->get<ReallocPairs>(); 02336 02337 for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end(); 02338 I != E; ++I) { 02339 SymbolRef sym = I.getKey(); 02340 if (!currMap.lookup(sym)) 02341 return sym; 02342 } 02343 02344 return nullptr; 02345 } 02346 02347 PathDiagnosticPiece * 02348 MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N, 02349 const ExplodedNode *PrevN, 02350 BugReporterContext &BRC, 02351 BugReport &BR) { 02352 ProgramStateRef state = N->getState(); 02353 ProgramStateRef statePrev = PrevN->getState(); 02354 02355 const RefState *RS = state->get<RegionState>(Sym); 02356 const RefState *RSPrev = statePrev->get<RegionState>(Sym); 02357 if (!RS) 02358 return nullptr; 02359 02360 const Stmt *S = nullptr; 02361 const char *Msg = nullptr; 02362 StackHintGeneratorForSymbol *StackHint = nullptr; 02363 02364 // Retrieve the associated statement. 02365 ProgramPoint ProgLoc = N->getLocation(); 02366 if (Optional<StmtPoint> SP = ProgLoc.getAs<StmtPoint>()) { 02367 S = SP->getStmt(); 02368 } else if (Optional<CallExitEnd> Exit = ProgLoc.getAs<CallExitEnd>()) { 02369 S = Exit->getCalleeContext()->getCallSite(); 02370 } else if (Optional<BlockEdge> Edge = ProgLoc.getAs<BlockEdge>()) { 02371 // If an assumption was made on a branch, it should be caught 02372 // here by looking at the state transition. 02373 S = Edge->getSrc()->getTerminator(); 02374 } 02375 02376 if (!S) 02377 return nullptr; 02378 02379 // FIXME: We will eventually need to handle non-statement-based events 02380 // (__attribute__((cleanup))). 02381 02382 // Find out if this is an interesting point and what is the kind. 02383 if (Mode == Normal) { 02384 if (isAllocated(RS, RSPrev, S)) { 02385 Msg = "Memory is allocated"; 02386 StackHint = new StackHintGeneratorForSymbol(Sym, 02387 "Returned allocated memory"); 02388 } else if (isReleased(RS, RSPrev, S)) { 02389 Msg = "Memory is released"; 02390 StackHint = new StackHintGeneratorForSymbol(Sym, 02391 "Returning; memory was released"); 02392 } else if (isRelinquished(RS, RSPrev, S)) { 02393 Msg = "Memory ownership is transferred"; 02394 StackHint = new StackHintGeneratorForSymbol(Sym, ""); 02395 } else if (isReallocFailedCheck(RS, RSPrev, S)) { 02396 Mode = ReallocationFailed; 02397 Msg = "Reallocation failed"; 02398 StackHint = new StackHintGeneratorForReallocationFailed(Sym, 02399 "Reallocation failed"); 02400 02401 if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) { 02402 // Is it possible to fail two reallocs WITHOUT testing in between? 02403 assert((!FailedReallocSymbol || FailedReallocSymbol == sym) && 02404 "We only support one failed realloc at a time."); 02405 BR.markInteresting(sym); 02406 FailedReallocSymbol = sym; 02407 } 02408 } 02409 02410 // We are in a special mode if a reallocation failed later in the path. 02411 } else if (Mode == ReallocationFailed) { 02412 assert(FailedReallocSymbol && "No symbol to look for."); 02413 02414 // Is this is the first appearance of the reallocated symbol? 02415 if (!statePrev->get<RegionState>(FailedReallocSymbol)) { 02416 // We're at the reallocation point. 02417 Msg = "Attempt to reallocate memory"; 02418 StackHint = new StackHintGeneratorForSymbol(Sym, 02419 "Returned reallocated memory"); 02420 FailedReallocSymbol = nullptr; 02421 Mode = Normal; 02422 } 02423 } 02424 02425 if (!Msg) 02426 return nullptr; 02427 assert(StackHint); 02428 02429 // Generate the extra diagnostic. 02430 PathDiagnosticLocation Pos(S, BRC.getSourceManager(), 02431 N->getLocationContext()); 02432 return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint); 02433 } 02434 02435 void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State, 02436 const char *NL, const char *Sep) const { 02437 02438 RegionStateTy RS = State->get<RegionState>(); 02439 02440 if (!RS.isEmpty()) { 02441 Out << Sep << "MallocChecker :" << NL; 02442 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { 02443 const RefState *RefS = State->get<RegionState>(I.getKey()); 02444 AllocationFamily Family = RefS->getAllocationFamily(); 02445 Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family); 02446 02447 I.getKey()->dumpToStream(Out); 02448 Out << " : "; 02449 I.getData().dump(Out); 02450 if (CheckKind.hasValue()) 02451 Out << " (" << CheckNames[*CheckKind].getName() << ")"; 02452 Out << NL; 02453 } 02454 } 02455 } 02456 02457 void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) { 02458 registerCStringCheckerBasic(mgr); 02459 MallocChecker *checker = mgr.registerChecker<MallocChecker>(); 02460 checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true; 02461 checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] = 02462 mgr.getCurrentCheckName(); 02463 // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete 02464 // checker. 02465 if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker]) 02466 checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true; 02467 } 02468 02469 #define REGISTER_CHECKER(name) \ 02470 void ento::register##name(CheckerManager &mgr) { \ 02471 registerCStringCheckerBasic(mgr); \ 02472 MallocChecker *checker = mgr.registerChecker<MallocChecker>(); \ 02473 checker->ChecksEnabled[MallocChecker::CK_##name] = true; \ 02474 checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \ 02475 } 02476 02477 REGISTER_CHECKER(MallocPessimistic) 02478 REGISTER_CHECKER(MallocOptimistic) 02479 REGISTER_CHECKER(NewDeleteChecker) 02480 REGISTER_CHECKER(MismatchedDeallocatorChecker)