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/StaticAnalyzer/Core/Checker.h" 00018 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 00019 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 00020 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 00021 #include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" 00022 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 00023 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 00024 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 00025 #include "clang/Basic/SourceManager.h" 00026 #include "llvm/ADT/ImmutableMap.h" 00027 #include "llvm/ADT/SmallString.h" 00028 #include "llvm/ADT/STLExtras.h" 00029 #include <climits> 00030 00031 using namespace clang; 00032 using namespace ento; 00033 00034 namespace { 00035 00036 class RefState { 00037 enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped, 00038 Relinquished } K; 00039 const Stmt *S; 00040 00041 public: 00042 RefState(Kind k, const Stmt *s) : K(k), S(s) {} 00043 00044 bool isAllocated() const { return K == AllocateUnchecked; } 00045 bool isReleased() const { return K == Released; } 00046 00047 const Stmt *getStmt() const { return S; } 00048 00049 bool operator==(const RefState &X) const { 00050 return K == X.K && S == X.S; 00051 } 00052 00053 static RefState getAllocateUnchecked(const Stmt *s) { 00054 return RefState(AllocateUnchecked, s); 00055 } 00056 static RefState getAllocateFailed() { 00057 return RefState(AllocateFailed, 0); 00058 } 00059 static RefState getReleased(const Stmt *s) { return RefState(Released, s); } 00060 static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); } 00061 static RefState getRelinquished(const Stmt *s) { 00062 return RefState(Relinquished, s); 00063 } 00064 00065 void Profile(llvm::FoldingSetNodeID &ID) const { 00066 ID.AddInteger(K); 00067 ID.AddPointer(S); 00068 } 00069 }; 00070 00071 struct ReallocPair { 00072 SymbolRef ReallocatedSym; 00073 bool IsFreeOnFailure; 00074 ReallocPair(SymbolRef S, bool F) : ReallocatedSym(S), IsFreeOnFailure(F) {} 00075 void Profile(llvm::FoldingSetNodeID &ID) const { 00076 ID.AddInteger(IsFreeOnFailure); 00077 ID.AddPointer(ReallocatedSym); 00078 } 00079 bool operator==(const ReallocPair &X) const { 00080 return ReallocatedSym == X.ReallocatedSym && 00081 IsFreeOnFailure == X.IsFreeOnFailure; 00082 } 00083 }; 00084 00085 typedef std::pair<const Stmt*, const MemRegion*> LeakInfo; 00086 00087 class MallocChecker : public Checker<check::DeadSymbols, 00088 check::EndPath, 00089 check::PreStmt<ReturnStmt>, 00090 check::PreStmt<CallExpr>, 00091 check::PostStmt<CallExpr>, 00092 check::PostStmt<BlockExpr>, 00093 check::Location, 00094 check::Bind, 00095 eval::Assume, 00096 check::RegionChanges> 00097 { 00098 mutable OwningPtr<BugType> BT_DoubleFree; 00099 mutable OwningPtr<BugType> BT_Leak; 00100 mutable OwningPtr<BugType> BT_UseFree; 00101 mutable OwningPtr<BugType> BT_BadFree; 00102 mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc, 00103 *II_valloc, *II_reallocf, *II_strndup, *II_strdup; 00104 00105 public: 00106 MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0), 00107 II_valloc(0), II_reallocf(0), II_strndup(0), II_strdup(0) {} 00108 00109 /// In pessimistic mode, the checker assumes that it does not know which 00110 /// functions might free the memory. 00111 struct ChecksFilter { 00112 DefaultBool CMallocPessimistic; 00113 DefaultBool CMallocOptimistic; 00114 }; 00115 00116 ChecksFilter Filter; 00117 00118 void checkPreStmt(const CallExpr *S, CheckerContext &C) const; 00119 void checkPostStmt(const CallExpr *CE, CheckerContext &C) const; 00120 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const; 00121 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; 00122 void checkEndPath(CheckerContext &C) const; 00123 void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const; 00124 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, 00125 bool Assumption) const; 00126 void checkLocation(SVal l, bool isLoad, const Stmt *S, 00127 CheckerContext &C) const; 00128 void checkBind(SVal location, SVal val, const Stmt*S, 00129 CheckerContext &C) const; 00130 ProgramStateRef 00131 checkRegionChanges(ProgramStateRef state, 00132 const StoreManager::InvalidatedSymbols *invalidated, 00133 ArrayRef<const MemRegion *> ExplicitRegions, 00134 ArrayRef<const MemRegion *> Regions, 00135 const CallOrObjCMessage *Call) const; 00136 bool wantsRegionChangeUpdate(ProgramStateRef state) const { 00137 return true; 00138 } 00139 00140 void printState(raw_ostream &Out, ProgramStateRef State, 00141 const char *NL, const char *Sep) const; 00142 00143 private: 00144 void initIdentifierInfo(ASTContext &C) const; 00145 00146 /// Check if this is one of the functions which can allocate/reallocate memory 00147 /// pointed to by one of its arguments. 00148 bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const; 00149 bool isFreeFunction(const FunctionDecl *FD, ASTContext &C) const; 00150 bool isAllocationFunction(const FunctionDecl *FD, ASTContext &C) const; 00151 00152 static ProgramStateRef MallocMemReturnsAttr(CheckerContext &C, 00153 const CallExpr *CE, 00154 const OwnershipAttr* Att); 00155 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, 00156 const Expr *SizeEx, SVal Init, 00157 ProgramStateRef state) { 00158 return MallocMemAux(C, CE, 00159 state->getSVal(SizeEx, C.getLocationContext()), 00160 Init, state); 00161 } 00162 00163 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, 00164 SVal SizeEx, SVal Init, 00165 ProgramStateRef state); 00166 00167 /// Update the RefState to reflect the new memory allocation. 00168 static ProgramStateRef MallocUpdateRefState(CheckerContext &C, 00169 const CallExpr *CE, 00170 ProgramStateRef state); 00171 00172 ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE, 00173 const OwnershipAttr* Att) const; 00174 ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE, 00175 ProgramStateRef state, unsigned Num, 00176 bool Hold) const; 00177 00178 ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE, 00179 bool FreesMemOnFailure) const; 00180 static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE); 00181 00182 ///\brief Check if the memory associated with this symbol was released. 00183 bool isReleased(SymbolRef Sym, CheckerContext &C) const; 00184 00185 bool checkEscape(SymbolRef Sym, const Stmt *S, CheckerContext &C) const; 00186 bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, 00187 const Stmt *S = 0) const; 00188 00189 /// Check if the function is not known to us. So, for example, we could 00190 /// conservatively assume it can free/reallocate it's pointer arguments. 00191 bool doesNotFreeMemory(const CallOrObjCMessage *Call, 00192 ProgramStateRef State) const; 00193 00194 static bool SummarizeValue(raw_ostream &os, SVal V); 00195 static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR); 00196 void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const; 00197 00198 /// Find the location of the allocation for Sym on the path leading to the 00199 /// exploded node N. 00200 LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym, 00201 CheckerContext &C) const; 00202 00203 void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const; 00204 00205 /// The bug visitor which allows us to print extra diagnostics along the 00206 /// BugReport path. For example, showing the allocation site of the leaked 00207 /// region. 00208 class MallocBugVisitor : public BugReporterVisitorImpl<MallocBugVisitor> { 00209 protected: 00210 enum NotificationMode { 00211 Normal, 00212 ReallocationFailed 00213 }; 00214 00215 // The allocated region symbol tracked by the main analysis. 00216 SymbolRef Sym; 00217 00218 // The mode we are in, i.e. what kind of diagnostics will be emitted. 00219 NotificationMode Mode; 00220 00221 // A symbol from when the primary region should have been reallocated. 00222 SymbolRef FailedReallocSymbol; 00223 00224 bool IsLeak; 00225 00226 public: 00227 MallocBugVisitor(SymbolRef S, bool isLeak = false) 00228 : Sym(S), Mode(Normal), FailedReallocSymbol(0), IsLeak(isLeak) {} 00229 00230 virtual ~MallocBugVisitor() {} 00231 00232 void Profile(llvm::FoldingSetNodeID &ID) const { 00233 static int X = 0; 00234 ID.AddPointer(&X); 00235 ID.AddPointer(Sym); 00236 } 00237 00238 inline bool isAllocated(const RefState *S, const RefState *SPrev, 00239 const Stmt *Stmt) { 00240 // Did not track -> allocated. Other state (released) -> allocated. 00241 return (Stmt && isa<CallExpr>(Stmt) && 00242 (S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated())); 00243 } 00244 00245 inline bool isReleased(const RefState *S, const RefState *SPrev, 00246 const Stmt *Stmt) { 00247 // Did not track -> released. Other state (allocated) -> released. 00248 return (Stmt && isa<CallExpr>(Stmt) && 00249 (S && S->isReleased()) && (!SPrev || !SPrev->isReleased())); 00250 } 00251 00252 inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev, 00253 const Stmt *Stmt) { 00254 // If the expression is not a call, and the state change is 00255 // released -> allocated, it must be the realloc return value 00256 // check. If we have to handle more cases here, it might be cleaner just 00257 // to track this extra bit in the state itself. 00258 return ((!Stmt || !isa<CallExpr>(Stmt)) && 00259 (S && S->isAllocated()) && (SPrev && !SPrev->isAllocated())); 00260 } 00261 00262 PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 00263 const ExplodedNode *PrevN, 00264 BugReporterContext &BRC, 00265 BugReport &BR); 00266 00267 PathDiagnosticPiece* getEndPath(BugReporterContext &BRC, 00268 const ExplodedNode *EndPathNode, 00269 BugReport &BR) { 00270 if (!IsLeak) 00271 return 0; 00272 00273 PathDiagnosticLocation L = 00274 PathDiagnosticLocation::createEndOfPath(EndPathNode, 00275 BRC.getSourceManager()); 00276 // Do not add the statement itself as a range in case of leak. 00277 return new PathDiagnosticEventPiece(L, BR.getDescription(), false); 00278 } 00279 00280 private: 00281 class StackHintGeneratorForReallocationFailed 00282 : public StackHintGeneratorForSymbol { 00283 public: 00284 StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M) 00285 : StackHintGeneratorForSymbol(S, M) {} 00286 00287 virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) { 00288 SmallString<200> buf; 00289 llvm::raw_svector_ostream os(buf); 00290 00291 os << "Reallocation of "; 00292 // Printed parameters start at 1, not 0. 00293 printOrdinal(++ArgIndex, os); 00294 os << " parameter failed"; 00295 00296 return os.str(); 00297 } 00298 00299 virtual std::string getMessageForReturn(const CallExpr *CallExpr) { 00300 return "Reallocation of returned value failed"; 00301 } 00302 }; 00303 }; 00304 }; 00305 } // end anonymous namespace 00306 00307 typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy; 00308 typedef llvm::ImmutableMap<SymbolRef, ReallocPair > ReallocMap; 00309 class RegionState {}; 00310 class ReallocPairs {}; 00311 namespace clang { 00312 namespace ento { 00313 template <> 00314 struct ProgramStateTrait<RegionState> 00315 : public ProgramStatePartialTrait<RegionStateTy> { 00316 static void *GDMIndex() { static int x; return &x; } 00317 }; 00318 00319 template <> 00320 struct ProgramStateTrait<ReallocPairs> 00321 : public ProgramStatePartialTrait<ReallocMap> { 00322 static void *GDMIndex() { static int x; return &x; } 00323 }; 00324 } 00325 } 00326 00327 namespace { 00328 class StopTrackingCallback : public SymbolVisitor { 00329 ProgramStateRef state; 00330 public: 00331 StopTrackingCallback(ProgramStateRef st) : state(st) {} 00332 ProgramStateRef getState() const { return state; } 00333 00334 bool VisitSymbol(SymbolRef sym) { 00335 state = state->remove<RegionState>(sym); 00336 return true; 00337 } 00338 }; 00339 } // end anonymous namespace 00340 00341 void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { 00342 if (II_malloc) 00343 return; 00344 II_malloc = &Ctx.Idents.get("malloc"); 00345 II_free = &Ctx.Idents.get("free"); 00346 II_realloc = &Ctx.Idents.get("realloc"); 00347 II_reallocf = &Ctx.Idents.get("reallocf"); 00348 II_calloc = &Ctx.Idents.get("calloc"); 00349 II_valloc = &Ctx.Idents.get("valloc"); 00350 II_strdup = &Ctx.Idents.get("strdup"); 00351 II_strndup = &Ctx.Idents.get("strndup"); 00352 } 00353 00354 bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const { 00355 if (isFreeFunction(FD, C)) 00356 return true; 00357 00358 if (isAllocationFunction(FD, C)) 00359 return true; 00360 00361 return false; 00362 } 00363 00364 bool MallocChecker::isAllocationFunction(const FunctionDecl *FD, 00365 ASTContext &C) const { 00366 if (!FD) 00367 return false; 00368 00369 IdentifierInfo *FunI = FD->getIdentifier(); 00370 if (!FunI) 00371 return false; 00372 00373 initIdentifierInfo(C); 00374 00375 if (FunI == II_malloc || FunI == II_realloc || 00376 FunI == II_reallocf || FunI == II_calloc || FunI == II_valloc || 00377 FunI == II_strdup || FunI == II_strndup) 00378 return true; 00379 00380 if (Filter.CMallocOptimistic && FD->hasAttrs()) 00381 for (specific_attr_iterator<OwnershipAttr> 00382 i = FD->specific_attr_begin<OwnershipAttr>(), 00383 e = FD->specific_attr_end<OwnershipAttr>(); 00384 i != e; ++i) 00385 if ((*i)->getOwnKind() == OwnershipAttr::Returns) 00386 return true; 00387 return false; 00388 } 00389 00390 bool MallocChecker::isFreeFunction(const FunctionDecl *FD, ASTContext &C) const { 00391 if (!FD) 00392 return false; 00393 00394 IdentifierInfo *FunI = FD->getIdentifier(); 00395 if (!FunI) 00396 return false; 00397 00398 initIdentifierInfo(C); 00399 00400 if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf) 00401 return true; 00402 00403 if (Filter.CMallocOptimistic && FD->hasAttrs()) 00404 for (specific_attr_iterator<OwnershipAttr> 00405 i = FD->specific_attr_begin<OwnershipAttr>(), 00406 e = FD->specific_attr_end<OwnershipAttr>(); 00407 i != e; ++i) 00408 if ((*i)->getOwnKind() == OwnershipAttr::Takes || 00409 (*i)->getOwnKind() == OwnershipAttr::Holds) 00410 return true; 00411 return false; 00412 } 00413 00414 void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { 00415 const FunctionDecl *FD = C.getCalleeDecl(CE); 00416 if (!FD) 00417 return; 00418 00419 initIdentifierInfo(C.getASTContext()); 00420 IdentifierInfo *FunI = FD->getIdentifier(); 00421 if (!FunI) 00422 return; 00423 00424 ProgramStateRef State = C.getState(); 00425 if (FunI == II_malloc || FunI == II_valloc) { 00426 if (CE->getNumArgs() < 1) 00427 return; 00428 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); 00429 } else if (FunI == II_realloc) { 00430 State = ReallocMem(C, CE, false); 00431 } else if (FunI == II_reallocf) { 00432 State = ReallocMem(C, CE, true); 00433 } else if (FunI == II_calloc) { 00434 State = CallocMem(C, CE); 00435 } else if (FunI == II_free) { 00436 State = FreeMemAux(C, CE, C.getState(), 0, false); 00437 } else if (FunI == II_strdup) { 00438 State = MallocUpdateRefState(C, CE, State); 00439 } else if (FunI == II_strndup) { 00440 State = MallocUpdateRefState(C, CE, State); 00441 } else if (Filter.CMallocOptimistic) { 00442 // Check all the attributes, if there are any. 00443 // There can be multiple of these attributes. 00444 if (FD->hasAttrs()) 00445 for (specific_attr_iterator<OwnershipAttr> 00446 i = FD->specific_attr_begin<OwnershipAttr>(), 00447 e = FD->specific_attr_end<OwnershipAttr>(); 00448 i != e; ++i) { 00449 switch ((*i)->getOwnKind()) { 00450 case OwnershipAttr::Returns: 00451 State = MallocMemReturnsAttr(C, CE, *i); 00452 break; 00453 case OwnershipAttr::Takes: 00454 case OwnershipAttr::Holds: 00455 State = FreeMemAttr(C, CE, *i); 00456 break; 00457 } 00458 } 00459 } 00460 C.addTransition(State); 00461 } 00462 00463 ProgramStateRef MallocChecker::MallocMemReturnsAttr(CheckerContext &C, 00464 const CallExpr *CE, 00465 const OwnershipAttr* Att) { 00466 if (Att->getModule() != "malloc") 00467 return 0; 00468 00469 OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); 00470 if (I != E) { 00471 return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState()); 00472 } 00473 return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), C.getState()); 00474 } 00475 00476 ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, 00477 const CallExpr *CE, 00478 SVal Size, SVal Init, 00479 ProgramStateRef state) { 00480 // Get the return value. 00481 SVal retVal = state->getSVal(CE, C.getLocationContext()); 00482 00483 // We expect the malloc functions to return a pointer. 00484 if (!isa<Loc>(retVal)) 00485 return 0; 00486 00487 // Fill the region with the initialization value. 00488 state = state->bindDefault(retVal, Init); 00489 00490 // Set the region's extent equal to the Size parameter. 00491 const SymbolicRegion *R = 00492 dyn_cast_or_null<SymbolicRegion>(retVal.getAsRegion()); 00493 if (!R) 00494 return 0; 00495 if (isa<DefinedOrUnknownSVal>(Size)) { 00496 SValBuilder &svalBuilder = C.getSValBuilder(); 00497 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder); 00498 DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size); 00499 DefinedOrUnknownSVal extentMatchesSize = 00500 svalBuilder.evalEQ(state, Extent, DefinedSize); 00501 00502 state = state->assume(extentMatchesSize, true); 00503 assert(state); 00504 } 00505 00506 return MallocUpdateRefState(C, CE, state); 00507 } 00508 00509 ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C, 00510 const CallExpr *CE, 00511 ProgramStateRef state) { 00512 // Get the return value. 00513 SVal retVal = state->getSVal(CE, C.getLocationContext()); 00514 00515 // We expect the malloc functions to return a pointer. 00516 if (!isa<Loc>(retVal)) 00517 return 0; 00518 00519 SymbolRef Sym = retVal.getAsLocSymbol(); 00520 assert(Sym); 00521 00522 // Set the symbol's state to Allocated. 00523 return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE)); 00524 00525 } 00526 00527 ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C, 00528 const CallExpr *CE, 00529 const OwnershipAttr* Att) const { 00530 if (Att->getModule() != "malloc") 00531 return 0; 00532 00533 ProgramStateRef State = C.getState(); 00534 00535 for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); 00536 I != E; ++I) { 00537 ProgramStateRef StateI = FreeMemAux(C, CE, State, *I, 00538 Att->getOwnKind() == OwnershipAttr::Holds); 00539 if (StateI) 00540 State = StateI; 00541 } 00542 return State; 00543 } 00544 00545 ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, 00546 const CallExpr *CE, 00547 ProgramStateRef state, 00548 unsigned Num, 00549 bool Hold) const { 00550 if (CE->getNumArgs() < (Num + 1)) 00551 return 0; 00552 00553 const Expr *ArgExpr = CE->getArg(Num); 00554 SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext()); 00555 if (!isa<DefinedOrUnknownSVal>(ArgVal)) 00556 return 0; 00557 DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal); 00558 00559 // Check for null dereferences. 00560 if (!isa<Loc>(location)) 00561 return 0; 00562 00563 // The explicit NULL case, no operation is performed. 00564 ProgramStateRef notNullState, nullState; 00565 llvm::tie(notNullState, nullState) = state->assume(location); 00566 if (nullState && !notNullState) 00567 return 0; 00568 00569 // Unknown values could easily be okay 00570 // Undefined values are handled elsewhere 00571 if (ArgVal.isUnknownOrUndef()) 00572 return 0; 00573 00574 const MemRegion *R = ArgVal.getAsRegion(); 00575 00576 // Nonlocs can't be freed, of course. 00577 // Non-region locations (labels and fixed addresses) also shouldn't be freed. 00578 if (!R) { 00579 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange()); 00580 return 0; 00581 } 00582 00583 R = R->StripCasts(); 00584 00585 // Blocks might show up as heap data, but should not be free()d 00586 if (isa<BlockDataRegion>(R)) { 00587 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange()); 00588 return 0; 00589 } 00590 00591 const MemSpaceRegion *MS = R->getMemorySpace(); 00592 00593 // Parameters, locals, statics, and globals shouldn't be freed. 00594 if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) { 00595 // FIXME: at the time this code was written, malloc() regions were 00596 // represented by conjured symbols, which are all in UnknownSpaceRegion. 00597 // This means that there isn't actually anything from HeapSpaceRegion 00598 // that should be freed, even though we allow it here. 00599 // Of course, free() can work on memory allocated outside the current 00600 // function, so UnknownSpaceRegion is always a possibility. 00601 // False negatives are better than false positives. 00602 00603 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange()); 00604 return 0; 00605 } 00606 00607 const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R); 00608 // Various cases could lead to non-symbol values here. 00609 // For now, ignore them. 00610 if (!SR) 00611 return 0; 00612 00613 SymbolRef Sym = SR->getSymbol(); 00614 const RefState *RS = state->get<RegionState>(Sym); 00615 00616 // If the symbol has not been tracked, return. This is possible when free() is 00617 // called on a pointer that does not get its pointee directly from malloc(). 00618 // Full support of this requires inter-procedural analysis. 00619 if (!RS) 00620 return 0; 00621 00622 // Check double free. 00623 if (RS->isReleased()) { 00624 if (ExplodedNode *N = C.generateSink()) { 00625 if (!BT_DoubleFree) 00626 BT_DoubleFree.reset( 00627 new BugType("Double free", "Memory Error")); 00628 BugReport *R = new BugReport(*BT_DoubleFree, 00629 "Attempt to free released memory", N); 00630 R->addRange(ArgExpr->getSourceRange()); 00631 R->markInteresting(Sym); 00632 R->addVisitor(new MallocBugVisitor(Sym)); 00633 C.EmitReport(R); 00634 } 00635 return 0; 00636 } 00637 00638 // Normal free. 00639 if (Hold) 00640 return state->set<RegionState>(Sym, RefState::getRelinquished(CE)); 00641 return state->set<RegionState>(Sym, RefState::getReleased(CE)); 00642 } 00643 00644 bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) { 00645 if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V)) 00646 os << "an integer (" << IntVal->getValue() << ")"; 00647 else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V)) 00648 os << "a constant address (" << ConstAddr->getValue() << ")"; 00649 else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V)) 00650 os << "the address of the label '" << Label->getLabel()->getName() << "'"; 00651 else 00652 return false; 00653 00654 return true; 00655 } 00656 00657 bool MallocChecker::SummarizeRegion(raw_ostream &os, 00658 const MemRegion *MR) { 00659 switch (MR->getKind()) { 00660 case MemRegion::FunctionTextRegionKind: { 00661 const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl(); 00662 if (FD) 00663 os << "the address of the function '" << *FD << '\''; 00664 else 00665 os << "the address of a function"; 00666 return true; 00667 } 00668 case MemRegion::BlockTextRegionKind: 00669 os << "block text"; 00670 return true; 00671 case MemRegion::BlockDataRegionKind: 00672 // FIXME: where the block came from? 00673 os << "a block"; 00674 return true; 00675 default: { 00676 const MemSpaceRegion *MS = MR->getMemorySpace(); 00677 00678 if (isa<StackLocalsSpaceRegion>(MS)) { 00679 const VarRegion *VR = dyn_cast<VarRegion>(MR); 00680 const VarDecl *VD; 00681 if (VR) 00682 VD = VR->getDecl(); 00683 else 00684 VD = NULL; 00685 00686 if (VD) 00687 os << "the address of the local variable '" << VD->getName() << "'"; 00688 else 00689 os << "the address of a local stack variable"; 00690 return true; 00691 } 00692 00693 if (isa<StackArgumentsSpaceRegion>(MS)) { 00694 const VarRegion *VR = dyn_cast<VarRegion>(MR); 00695 const VarDecl *VD; 00696 if (VR) 00697 VD = VR->getDecl(); 00698 else 00699 VD = NULL; 00700 00701 if (VD) 00702 os << "the address of the parameter '" << VD->getName() << "'"; 00703 else 00704 os << "the address of a parameter"; 00705 return true; 00706 } 00707 00708 if (isa<GlobalsSpaceRegion>(MS)) { 00709 const VarRegion *VR = dyn_cast<VarRegion>(MR); 00710 const VarDecl *VD; 00711 if (VR) 00712 VD = VR->getDecl(); 00713 else 00714 VD = NULL; 00715 00716 if (VD) { 00717 if (VD->isStaticLocal()) 00718 os << "the address of the static variable '" << VD->getName() << "'"; 00719 else 00720 os << "the address of the global variable '" << VD->getName() << "'"; 00721 } else 00722 os << "the address of a global variable"; 00723 return true; 00724 } 00725 00726 return false; 00727 } 00728 } 00729 } 00730 00731 void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal, 00732 SourceRange range) const { 00733 if (ExplodedNode *N = C.generateSink()) { 00734 if (!BT_BadFree) 00735 BT_BadFree.reset(new BugType("Bad free", "Memory Error")); 00736 00737 SmallString<100> buf; 00738 llvm::raw_svector_ostream os(buf); 00739 00740 const MemRegion *MR = ArgVal.getAsRegion(); 00741 if (MR) { 00742 while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR)) 00743 MR = ER->getSuperRegion(); 00744 00745 // Special case for alloca() 00746 if (isa<AllocaRegion>(MR)) 00747 os << "Argument to free() was allocated by alloca(), not malloc()"; 00748 else { 00749 os << "Argument to free() is "; 00750 if (SummarizeRegion(os, MR)) 00751 os << ", which is not memory allocated by malloc()"; 00752 else 00753 os << "not memory allocated by malloc()"; 00754 } 00755 } else { 00756 os << "Argument to free() is "; 00757 if (SummarizeValue(os, ArgVal)) 00758 os << ", which is not memory allocated by malloc()"; 00759 else 00760 os << "not memory allocated by malloc()"; 00761 } 00762 00763 BugReport *R = new BugReport(*BT_BadFree, os.str(), N); 00764 R->markInteresting(MR); 00765 R->addRange(range); 00766 C.EmitReport(R); 00767 } 00768 } 00769 00770 ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C, 00771 const CallExpr *CE, 00772 bool FreesOnFail) const { 00773 if (CE->getNumArgs() < 2) 00774 return 0; 00775 00776 ProgramStateRef state = C.getState(); 00777 const Expr *arg0Expr = CE->getArg(0); 00778 const LocationContext *LCtx = C.getLocationContext(); 00779 SVal Arg0Val = state->getSVal(arg0Expr, LCtx); 00780 if (!isa<DefinedOrUnknownSVal>(Arg0Val)) 00781 return 0; 00782 DefinedOrUnknownSVal arg0Val = cast<DefinedOrUnknownSVal>(Arg0Val); 00783 00784 SValBuilder &svalBuilder = C.getSValBuilder(); 00785 00786 DefinedOrUnknownSVal PtrEQ = 00787 svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull()); 00788 00789 // Get the size argument. If there is no size arg then give up. 00790 const Expr *Arg1 = CE->getArg(1); 00791 if (!Arg1) 00792 return 0; 00793 00794 // Get the value of the size argument. 00795 SVal Arg1ValG = state->getSVal(Arg1, LCtx); 00796 if (!isa<DefinedOrUnknownSVal>(Arg1ValG)) 00797 return 0; 00798 DefinedOrUnknownSVal Arg1Val = cast<DefinedOrUnknownSVal>(Arg1ValG); 00799 00800 // Compare the size argument to 0. 00801 DefinedOrUnknownSVal SizeZero = 00802 svalBuilder.evalEQ(state, Arg1Val, 00803 svalBuilder.makeIntValWithPtrWidth(0, false)); 00804 00805 ProgramStateRef StatePtrIsNull, StatePtrNotNull; 00806 llvm::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ); 00807 ProgramStateRef StateSizeIsZero, StateSizeNotZero; 00808 llvm::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero); 00809 // We only assume exceptional states if they are definitely true; if the 00810 // state is under-constrained, assume regular realloc behavior. 00811 bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull; 00812 bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero; 00813 00814 // If the ptr is NULL and the size is not 0, the call is equivalent to 00815 // malloc(size). 00816 if ( PrtIsNull && !SizeIsZero) { 00817 ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1), 00818 UndefinedVal(), StatePtrIsNull); 00819 return stateMalloc; 00820 } 00821 00822 if (PrtIsNull && SizeIsZero) 00823 return 0; 00824 00825 // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size). 00826 assert(!PrtIsNull); 00827 SymbolRef FromPtr = arg0Val.getAsSymbol(); 00828 SVal RetVal = state->getSVal(CE, LCtx); 00829 SymbolRef ToPtr = RetVal.getAsSymbol(); 00830 if (!FromPtr || !ToPtr) 00831 return 0; 00832 00833 // If the size is 0, free the memory. 00834 if (SizeIsZero) 00835 if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero,0,false)){ 00836 // The semantics of the return value are: 00837 // If size was equal to 0, either NULL or a pointer suitable to be passed 00838 // to free() is returned. 00839 stateFree = stateFree->set<ReallocPairs>(ToPtr, 00840 ReallocPair(FromPtr, FreesOnFail)); 00841 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr); 00842 return stateFree; 00843 } 00844 00845 // Default behavior. 00846 if (ProgramStateRef stateFree = FreeMemAux(C, CE, state, 0, false)) { 00847 // FIXME: We should copy the content of the original buffer. 00848 ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1), 00849 UnknownVal(), stateFree); 00850 if (!stateRealloc) 00851 return 0; 00852 stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr, 00853 ReallocPair(FromPtr, FreesOnFail)); 00854 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr); 00855 return stateRealloc; 00856 } 00857 return 0; 00858 } 00859 00860 ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){ 00861 if (CE->getNumArgs() < 2) 00862 return 0; 00863 00864 ProgramStateRef state = C.getState(); 00865 SValBuilder &svalBuilder = C.getSValBuilder(); 00866 const LocationContext *LCtx = C.getLocationContext(); 00867 SVal count = state->getSVal(CE->getArg(0), LCtx); 00868 SVal elementSize = state->getSVal(CE->getArg(1), LCtx); 00869 SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize, 00870 svalBuilder.getContext().getSizeType()); 00871 SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); 00872 00873 return MallocMemAux(C, CE, TotalSize, zeroVal, state); 00874 } 00875 00876 LeakInfo 00877 MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym, 00878 CheckerContext &C) const { 00879 const LocationContext *LeakContext = N->getLocationContext(); 00880 // Walk the ExplodedGraph backwards and find the first node that referred to 00881 // the tracked symbol. 00882 const ExplodedNode *AllocNode = N; 00883 const MemRegion *ReferenceRegion = 0; 00884 00885 while (N) { 00886 ProgramStateRef State = N->getState(); 00887 if (!State->get<RegionState>(Sym)) 00888 break; 00889 00890 // Find the most recent expression bound to the symbol in the current 00891 // context. 00892 if (!ReferenceRegion) { 00893 if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) { 00894 SVal Val = State->getSVal(MR); 00895 if (Val.getAsLocSymbol() == Sym) 00896 ReferenceRegion = MR; 00897 } 00898 } 00899 00900 // Allocation node, is the last node in the current context in which the 00901 // symbol was tracked. 00902 if (N->getLocationContext() == LeakContext) 00903 AllocNode = N; 00904 N = N->pred_empty() ? NULL : *(N->pred_begin()); 00905 } 00906 00907 ProgramPoint P = AllocNode->getLocation(); 00908 const Stmt *AllocationStmt = 0; 00909 if (isa<StmtPoint>(P)) 00910 AllocationStmt = cast<StmtPoint>(P).getStmt(); 00911 00912 return LeakInfo(AllocationStmt, ReferenceRegion); 00913 } 00914 00915 void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N, 00916 CheckerContext &C) const { 00917 assert(N); 00918 if (!BT_Leak) { 00919 BT_Leak.reset(new BugType("Memory leak", "Memory Error")); 00920 // Leaks should not be reported if they are post-dominated by a sink: 00921 // (1) Sinks are higher importance bugs. 00922 // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending 00923 // with __noreturn functions such as assert() or exit(). We choose not 00924 // to report leaks on such paths. 00925 BT_Leak->setSuppressOnSink(true); 00926 } 00927 00928 // Most bug reports are cached at the location where they occurred. 00929 // With leaks, we want to unique them by the location where they were 00930 // allocated, and only report a single path. 00931 PathDiagnosticLocation LocUsedForUniqueing; 00932 const Stmt *AllocStmt = 0; 00933 const MemRegion *Region = 0; 00934 llvm::tie(AllocStmt, Region) = getAllocationSite(N, Sym, C); 00935 if (AllocStmt) 00936 LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocStmt, 00937 C.getSourceManager(), N->getLocationContext()); 00938 00939 SmallString<200> buf; 00940 llvm::raw_svector_ostream os(buf); 00941 os << "Memory is never released; potential leak"; 00942 if (Region) { 00943 os << " of memory pointed to by '"; 00944 Region->dumpPretty(os); 00945 os <<'\''; 00946 } 00947 00948 BugReport *R = new BugReport(*BT_Leak, os.str(), N, LocUsedForUniqueing); 00949 R->markInteresting(Sym); 00950 R->addVisitor(new MallocBugVisitor(Sym, true)); 00951 C.EmitReport(R); 00952 } 00953 00954 void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper, 00955 CheckerContext &C) const 00956 { 00957 if (!SymReaper.hasDeadSymbols()) 00958 return; 00959 00960 ProgramStateRef state = C.getState(); 00961 RegionStateTy RS = state->get<RegionState>(); 00962 RegionStateTy::Factory &F = state->get_context<RegionState>(); 00963 00964 bool generateReport = false; 00965 llvm::SmallVector<SymbolRef, 2> Errors; 00966 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { 00967 if (SymReaper.isDead(I->first)) { 00968 if (I->second.isAllocated()) { 00969 generateReport = true; 00970 Errors.push_back(I->first); 00971 } 00972 // Remove the dead symbol from the map. 00973 RS = F.remove(RS, I->first); 00974 00975 } 00976 } 00977 00978 // Cleanup the Realloc Pairs Map. 00979 ReallocMap RP = state->get<ReallocPairs>(); 00980 for (ReallocMap::iterator I = RP.begin(), E = RP.end(); I != E; ++I) { 00981 if (SymReaper.isDead(I->first) || 00982 SymReaper.isDead(I->second.ReallocatedSym)) { 00983 state = state->remove<ReallocPairs>(I->first); 00984 } 00985 } 00986 00987 // Generate leak node. 00988 static SimpleProgramPointTag Tag("MallocChecker : DeadSymbolsLeak"); 00989 ExplodedNode *N = C.addTransition(C.getState(), C.getPredecessor(), &Tag); 00990 00991 if (generateReport) { 00992 for (llvm::SmallVector<SymbolRef, 2>::iterator 00993 I = Errors.begin(), E = Errors.end(); I != E; ++I) { 00994 reportLeak(*I, N, C); 00995 } 00996 } 00997 C.addTransition(state->set<RegionState>(RS), N); 00998 } 00999 01000 void MallocChecker::checkEndPath(CheckerContext &C) const { 01001 ProgramStateRef state = C.getState(); 01002 RegionStateTy M = state->get<RegionState>(); 01003 01004 // If inside inlined call, skip it. 01005 if (C.getLocationContext()->getParent() != 0) 01006 return; 01007 01008 for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) { 01009 RefState RS = I->second; 01010 if (RS.isAllocated()) { 01011 ExplodedNode *N = C.addTransition(state); 01012 if (N) 01013 reportLeak(I->first, N, C); 01014 } 01015 } 01016 } 01017 01018 bool MallocChecker::checkEscape(SymbolRef Sym, const Stmt *S, 01019 CheckerContext &C) const { 01020 ProgramStateRef state = C.getState(); 01021 const RefState *RS = state->get<RegionState>(Sym); 01022 if (!RS) 01023 return false; 01024 01025 if (RS->isAllocated()) { 01026 state = state->set<RegionState>(Sym, RefState::getEscaped(S)); 01027 C.addTransition(state); 01028 return true; 01029 } 01030 return false; 01031 } 01032 01033 void MallocChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { 01034 // We will check for double free in the post visit. 01035 if (isFreeFunction(C.getCalleeDecl(CE), C.getASTContext())) 01036 return; 01037 01038 // Check use after free, when a freed pointer is passed to a call. 01039 ProgramStateRef State = C.getState(); 01040 for (CallExpr::const_arg_iterator I = CE->arg_begin(), 01041 E = CE->arg_end(); I != E; ++I) { 01042 const Expr *A = *I; 01043 if (A->getType().getTypePtr()->isAnyPointerType()) { 01044 SymbolRef Sym = State->getSVal(A, C.getLocationContext()).getAsSymbol(); 01045 if (!Sym) 01046 continue; 01047 if (checkUseAfterFree(Sym, C, A)) 01048 return; 01049 } 01050 } 01051 } 01052 01053 void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const { 01054 const Expr *E = S->getRetValue(); 01055 if (!E) 01056 return; 01057 01058 // Check if we are returning a symbol. 01059 SVal RetVal = C.getState()->getSVal(E, C.getLocationContext()); 01060 SymbolRef Sym = RetVal.getAsSymbol(); 01061 if (!Sym) 01062 // If we are returning a field of the allocated struct or an array element, 01063 // the callee could still free the memory. 01064 // TODO: This logic should be a part of generic symbol escape callback. 01065 if (const MemRegion *MR = RetVal.getAsRegion()) 01066 if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR)) 01067 if (const SymbolicRegion *BMR = 01068 dyn_cast<SymbolicRegion>(MR->getBaseRegion())) 01069 Sym = BMR->getSymbol(); 01070 if (!Sym) 01071 return; 01072 01073 // Check if we are returning freed memory. 01074 if (checkUseAfterFree(Sym, C, E)) 01075 return; 01076 01077 // If this function body is not inlined, check if the symbol is escaping. 01078 if (C.getLocationContext()->getParent() == 0) 01079 checkEscape(Sym, E, C); 01080 } 01081 01082 // TODO: Blocks should be either inlined or should call invalidate regions 01083 // upon invocation. After that's in place, special casing here will not be 01084 // needed. 01085 void MallocChecker::checkPostStmt(const BlockExpr *BE, 01086 CheckerContext &C) const { 01087 01088 // Scan the BlockDecRefExprs for any object the retain count checker 01089 // may be tracking. 01090 if (!BE->getBlockDecl()->hasCaptures()) 01091 return; 01092 01093 ProgramStateRef state = C.getState(); 01094 const BlockDataRegion *R = 01095 cast<BlockDataRegion>(state->getSVal(BE, 01096 C.getLocationContext()).getAsRegion()); 01097 01098 BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(), 01099 E = R->referenced_vars_end(); 01100 01101 if (I == E) 01102 return; 01103 01104 SmallVector<const MemRegion*, 10> Regions; 01105 const LocationContext *LC = C.getLocationContext(); 01106 MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager(); 01107 01108 for ( ; I != E; ++I) { 01109 const VarRegion *VR = *I; 01110 if (VR->getSuperRegion() == R) { 01111 VR = MemMgr.getVarRegion(VR->getDecl(), LC); 01112 } 01113 Regions.push_back(VR); 01114 } 01115 01116 state = 01117 state->scanReachableSymbols<StopTrackingCallback>(Regions.data(), 01118 Regions.data() + Regions.size()).getState(); 01119 C.addTransition(state); 01120 } 01121 01122 bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const { 01123 assert(Sym); 01124 const RefState *RS = C.getState()->get<RegionState>(Sym); 01125 return (RS && RS->isReleased()); 01126 } 01127 01128 bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C, 01129 const Stmt *S) const { 01130 if (isReleased(Sym, C)) { 01131 if (ExplodedNode *N = C.generateSink()) { 01132 if (!BT_UseFree) 01133 BT_UseFree.reset(new BugType("Use-after-free", "Memory Error")); 01134 01135 BugReport *R = new BugReport(*BT_UseFree, 01136 "Use of memory after it is freed",N); 01137 if (S) 01138 R->addRange(S->getSourceRange()); 01139 R->markInteresting(Sym); 01140 R->addVisitor(new MallocBugVisitor(Sym)); 01141 C.EmitReport(R); 01142 return true; 01143 } 01144 } 01145 return false; 01146 } 01147 01148 // Check if the location is a freed symbolic region. 01149 void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S, 01150 CheckerContext &C) const { 01151 SymbolRef Sym = l.getLocSymbolInBase(); 01152 if (Sym) 01153 checkUseAfterFree(Sym, C, S); 01154 } 01155 01156 //===----------------------------------------------------------------------===// 01157 // Check various ways a symbol can be invalidated. 01158 // TODO: This logic (the next 3 functions) is copied/similar to the 01159 // RetainRelease checker. We might want to factor this out. 01160 //===----------------------------------------------------------------------===// 01161 01162 // Stop tracking symbols when a value escapes as a result of checkBind. 01163 // A value escapes in three possible cases: 01164 // (1) we are binding to something that is not a memory region. 01165 // (2) we are binding to a memregion that does not have stack storage 01166 // (3) we are binding to a memregion with stack storage that the store 01167 // does not understand. 01168 void MallocChecker::checkBind(SVal loc, SVal val, const Stmt *S, 01169 CheckerContext &C) const { 01170 // Are we storing to something that causes the value to "escape"? 01171 bool escapes = true; 01172 ProgramStateRef state = C.getState(); 01173 01174 if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) { 01175 escapes = !regionLoc->getRegion()->hasStackStorage(); 01176 01177 if (!escapes) { 01178 // To test (3), generate a new state with the binding added. If it is 01179 // the same state, then it escapes (since the store cannot represent 01180 // the binding). 01181 // Do this only if we know that the store is not supposed to generate the 01182 // same state. 01183 SVal StoredVal = state->getSVal(regionLoc->getRegion()); 01184 if (StoredVal != val) 01185 escapes = (state == (state->bindLoc(*regionLoc, val))); 01186 } 01187 if (!escapes) { 01188 // Case 4: We do not currently model what happens when a symbol is 01189 // assigned to a struct field, so be conservative here and let the symbol 01190 // go. TODO: This could definitely be improved upon. 01191 escapes = !isa<VarRegion>(regionLoc->getRegion()); 01192 } 01193 } 01194 01195 // If our store can represent the binding and we aren't storing to something 01196 // that doesn't have local storage then just return and have the simulation 01197 // state continue as is. 01198 if (!escapes) 01199 return; 01200 01201 // Otherwise, find all symbols referenced by 'val' that we are tracking 01202 // and stop tracking them. 01203 state = state->scanReachableSymbols<StopTrackingCallback>(val).getState(); 01204 C.addTransition(state); 01205 } 01206 01207 // If a symbolic region is assumed to NULL (or another constant), stop tracking 01208 // it - assuming that allocation failed on this path. 01209 ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, 01210 SVal Cond, 01211 bool Assumption) const { 01212 RegionStateTy RS = state->get<RegionState>(); 01213 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { 01214 // If the symbol is assumed to NULL or another constant, this will 01215 // return an APSInt*. 01216 if (state->getSymVal(I.getKey())) 01217 state = state->remove<RegionState>(I.getKey()); 01218 } 01219 01220 // Realloc returns 0 when reallocation fails, which means that we should 01221 // restore the state of the pointer being reallocated. 01222 ReallocMap RP = state->get<ReallocPairs>(); 01223 for (ReallocMap::iterator I = RP.begin(), E = RP.end(); I != E; ++I) { 01224 // If the symbol is assumed to NULL or another constant, this will 01225 // return an APSInt*. 01226 if (state->getSymVal(I.getKey())) { 01227 SymbolRef ReallocSym = I.getData().ReallocatedSym; 01228 const RefState *RS = state->get<RegionState>(ReallocSym); 01229 if (RS) { 01230 if (RS->isReleased() && ! I.getData().IsFreeOnFailure) 01231 state = state->set<RegionState>(ReallocSym, 01232 RefState::getAllocateUnchecked(RS->getStmt())); 01233 } 01234 state = state->remove<ReallocPairs>(I.getKey()); 01235 } 01236 } 01237 01238 return state; 01239 } 01240 01241 // Check if the function is known to us. So, for example, we could 01242 // conservatively assume it can free/reallocate it's pointer arguments. 01243 // (We assume that the pointers cannot escape through calls to system 01244 // functions not handled by this checker.) 01245 bool MallocChecker::doesNotFreeMemory(const CallOrObjCMessage *Call, 01246 ProgramStateRef State) const { 01247 if (!Call) 01248 return false; 01249 01250 // For now, assume that any C++ call can free memory. 01251 // TODO: If we want to be more optimistic here, we'll need to make sure that 01252 // regions escape to C++ containers. They seem to do that even now, but for 01253 // mysterious reasons. 01254 if (Call->isCXXCall()) 01255 return false; 01256 01257 const Decl *D = Call->getDecl(); 01258 if (!D) 01259 return false; 01260 01261 ASTContext &ASTC = State->getStateManager().getContext(); 01262 01263 // If it's one of the allocation functions we can reason about, we model 01264 // its behavior explicitly. 01265 if (isa<FunctionDecl>(D) && isMemFunction(cast<FunctionDecl>(D), ASTC)) { 01266 return true; 01267 } 01268 01269 // If it's not a system call, assume it frees memory. 01270 SourceManager &SM = ASTC.getSourceManager(); 01271 if (!SM.isInSystemHeader(D->getLocation())) 01272 return false; 01273 01274 // Process C/ObjC functions. 01275 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 01276 // White list the system functions whose arguments escape. 01277 const IdentifierInfo *II = FD->getIdentifier(); 01278 if (!II) 01279 return true; 01280 StringRef FName = II->getName(); 01281 01282 // White list thread local storage. 01283 if (FName.equals("pthread_setspecific")) 01284 return false; 01285 01286 // White list the 'XXXNoCopy' ObjC functions. 01287 if (FName.endswith("NoCopy")) { 01288 // Look for the deallocator argument. We know that the memory ownership 01289 // is not transfered only if the deallocator argument is 01290 // 'kCFAllocatorNull'. 01291 for (unsigned i = 1; i < Call->getNumArgs(); ++i) { 01292 const Expr *ArgE = Call->getArg(i)->IgnoreParenCasts(); 01293 if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) { 01294 StringRef DeallocatorName = DE->getFoundDecl()->getName(); 01295 if (DeallocatorName == "kCFAllocatorNull") 01296 return true; 01297 } 01298 } 01299 return false; 01300 } 01301 01302 // PR12101 01303 // Many CoreFoundation and CoreGraphics might allow a tracked object 01304 // to escape. 01305 if (Call->isCFCGAllowingEscape(FName)) 01306 return false; 01307 01308 // Associating streams with malloced buffers. The pointer can escape if 01309 // 'closefn' is specified (and if that function does free memory). 01310 // Currently, we do not inspect the 'closefn' function (PR12101). 01311 if (FName == "funopen") 01312 if (Call->getNumArgs() >= 4 && !Call->getArgSVal(4).isConstant(0)) 01313 return false; 01314 01315 // Do not warn on pointers passed to 'setbuf' when used with std streams, 01316 // these leaks might be intentional when setting the buffer for stdio. 01317 // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer 01318 if (FName == "setbuf" || FName =="setbuffer" || 01319 FName == "setlinebuf" || FName == "setvbuf") { 01320 if (Call->getNumArgs() >= 1) 01321 if (const DeclRefExpr *Arg = 01322 dyn_cast<DeclRefExpr>(Call->getArg(0)->IgnoreParenCasts())) 01323 if (const VarDecl *D = dyn_cast<VarDecl>(Arg->getDecl())) 01324 if (D->getCanonicalDecl()->getName().find("std") 01325 != StringRef::npos) 01326 return false; 01327 } 01328 01329 // A bunch of other functions, which take ownership of a pointer (See retain 01330 // release checker). Not all the parameters here are invalidated, but the 01331 // Malloc checker cannot differentiate between them. The right way of doing 01332 // this would be to implement a pointer escapes callback. 01333 if (FName == "CVPixelBufferCreateWithBytes" || 01334 FName == "CGBitmapContextCreateWithData" || 01335 FName == "CVPixelBufferCreateWithPlanarBytes" || 01336 FName == "OSAtomicEnqueue") { 01337 return false; 01338 } 01339 01340 // Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can 01341 // be deallocated by NSMapRemove. 01342 if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos)) 01343 return false; 01344 01345 // If the call has a callback as an argument, assume the memory 01346 // can be freed. 01347 if (Call->hasNonZeroCallbackArg()) 01348 return false; 01349 01350 // Otherwise, assume that the function does not free memory. 01351 // Most system calls, do not free the memory. 01352 return true; 01353 01354 // Process ObjC functions. 01355 } else if (const ObjCMethodDecl * ObjCD = dyn_cast<ObjCMethodDecl>(D)) { 01356 Selector S = ObjCD->getSelector(); 01357 01358 // White list the ObjC functions which do free memory. 01359 // - Anything containing 'freeWhenDone' param set to 1. 01360 // Ex: dataWithBytesNoCopy:length:freeWhenDone. 01361 for (unsigned i = 1; i < S.getNumArgs(); ++i) { 01362 if (S.getNameForSlot(i).equals("freeWhenDone")) { 01363 if (Call->getArgSVal(i).isConstant(1)) 01364 return false; 01365 else 01366 return true; 01367 } 01368 } 01369 01370 // If the first selector ends with NoCopy, assume that the ownership is 01371 // transfered as well. 01372 // Ex: [NSData dataWithBytesNoCopy:bytes length:10]; 01373 if (S.getNameForSlot(0).endswith("NoCopy")) { 01374 return false; 01375 } 01376 01377 // If the call has a callback as an argument, assume the memory 01378 // can be freed. 01379 if (Call->hasNonZeroCallbackArg()) 01380 return false; 01381 01382 // Otherwise, assume that the function does not free memory. 01383 // Most system calls, do not free the memory. 01384 return true; 01385 } 01386 01387 // Otherwise, assume that the function can free memory. 01388 return false; 01389 01390 } 01391 01392 // If the symbol we are tracking is invalidated, but not explicitly (ex: the &p 01393 // escapes, when we are tracking p), do not track the symbol as we cannot reason 01394 // about it anymore. 01395 ProgramStateRef 01396 MallocChecker::checkRegionChanges(ProgramStateRef State, 01397 const StoreManager::InvalidatedSymbols *invalidated, 01398 ArrayRef<const MemRegion *> ExplicitRegions, 01399 ArrayRef<const MemRegion *> Regions, 01400 const CallOrObjCMessage *Call) const { 01401 if (!invalidated || invalidated->empty()) 01402 return State; 01403 llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols; 01404 01405 // If it's a call which might free or reallocate memory, we assume that all 01406 // regions (explicit and implicit) escaped. 01407 01408 // Otherwise, whitelist explicit pointers; we still can track them. 01409 if (!Call || doesNotFreeMemory(Call, State)) { 01410 for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(), 01411 E = ExplicitRegions.end(); I != E; ++I) { 01412 if (const SymbolicRegion *R = (*I)->StripCasts()->getAs<SymbolicRegion>()) 01413 WhitelistedSymbols.insert(R->getSymbol()); 01414 } 01415 } 01416 01417 for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(), 01418 E = invalidated->end(); I!=E; ++I) { 01419 SymbolRef sym = *I; 01420 if (WhitelistedSymbols.count(sym)) 01421 continue; 01422 // The symbol escaped. 01423 if (const RefState *RS = State->get<RegionState>(sym)) 01424 State = State->set<RegionState>(sym, RefState::getEscaped(RS->getStmt())); 01425 } 01426 return State; 01427 } 01428 01429 static SymbolRef findFailedReallocSymbol(ProgramStateRef currState, 01430 ProgramStateRef prevState) { 01431 ReallocMap currMap = currState->get<ReallocPairs>(); 01432 ReallocMap prevMap = prevState->get<ReallocPairs>(); 01433 01434 for (ReallocMap::iterator I = prevMap.begin(), E = prevMap.end(); 01435 I != E; ++I) { 01436 SymbolRef sym = I.getKey(); 01437 if (!currMap.lookup(sym)) 01438 return sym; 01439 } 01440 01441 return NULL; 01442 } 01443 01444 PathDiagnosticPiece * 01445 MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N, 01446 const ExplodedNode *PrevN, 01447 BugReporterContext &BRC, 01448 BugReport &BR) { 01449 ProgramStateRef state = N->getState(); 01450 ProgramStateRef statePrev = PrevN->getState(); 01451 01452 const RefState *RS = state->get<RegionState>(Sym); 01453 const RefState *RSPrev = statePrev->get<RegionState>(Sym); 01454 if (!RS && !RSPrev) 01455 return 0; 01456 01457 const Stmt *S = 0; 01458 const char *Msg = 0; 01459 StackHintGeneratorForSymbol *StackHint = 0; 01460 01461 // Retrieve the associated statement. 01462 ProgramPoint ProgLoc = N->getLocation(); 01463 if (isa<StmtPoint>(ProgLoc)) 01464 S = cast<StmtPoint>(ProgLoc).getStmt(); 01465 // If an assumption was made on a branch, it should be caught 01466 // here by looking at the state transition. 01467 if (isa<BlockEdge>(ProgLoc)) { 01468 const CFGBlock *srcBlk = cast<BlockEdge>(ProgLoc).getSrc(); 01469 S = srcBlk->getTerminator(); 01470 } 01471 if (!S) 01472 return 0; 01473 01474 // Find out if this is an interesting point and what is the kind. 01475 if (Mode == Normal) { 01476 if (isAllocated(RS, RSPrev, S)) { 01477 Msg = "Memory is allocated"; 01478 StackHint = new StackHintGeneratorForSymbol(Sym, 01479 "Returned allocated memory"); 01480 } else if (isReleased(RS, RSPrev, S)) { 01481 Msg = "Memory is released"; 01482 StackHint = new StackHintGeneratorForSymbol(Sym, 01483 "Returned released memory"); 01484 } else if (isReallocFailedCheck(RS, RSPrev, S)) { 01485 Mode = ReallocationFailed; 01486 Msg = "Reallocation failed"; 01487 StackHint = new StackHintGeneratorForReallocationFailed(Sym, 01488 "Reallocation failed"); 01489 01490 if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) { 01491 // Is it possible to fail two reallocs WITHOUT testing in between? 01492 assert((!FailedReallocSymbol || FailedReallocSymbol == sym) && 01493 "We only support one failed realloc at a time."); 01494 BR.markInteresting(sym); 01495 FailedReallocSymbol = sym; 01496 } 01497 } 01498 01499 // We are in a special mode if a reallocation failed later in the path. 01500 } else if (Mode == ReallocationFailed) { 01501 assert(FailedReallocSymbol && "No symbol to look for."); 01502 01503 // Is this is the first appearance of the reallocated symbol? 01504 if (!statePrev->get<RegionState>(FailedReallocSymbol)) { 01505 // If we ever hit this assert, that means BugReporter has decided to skip 01506 // node pairs or visit them out of order. 01507 assert(state->get<RegionState>(FailedReallocSymbol) && 01508 "Missed the reallocation point"); 01509 01510 // We're at the reallocation point. 01511 Msg = "Attempt to reallocate memory"; 01512 StackHint = new StackHintGeneratorForSymbol(Sym, 01513 "Returned reallocated memory"); 01514 FailedReallocSymbol = NULL; 01515 Mode = Normal; 01516 } 01517 } 01518 01519 if (!Msg) 01520 return 0; 01521 assert(StackHint); 01522 01523 // Generate the extra diagnostic. 01524 PathDiagnosticLocation Pos(S, BRC.getSourceManager(), 01525 N->getLocationContext()); 01526 return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint); 01527 } 01528 01529 void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State, 01530 const char *NL, const char *Sep) const { 01531 01532 RegionStateTy RS = State->get<RegionState>(); 01533 01534 if (!RS.isEmpty()) 01535 Out << "Has Malloc data" << NL; 01536 } 01537 01538 #define REGISTER_CHECKER(name) \ 01539 void ento::register##name(CheckerManager &mgr) {\ 01540 registerCStringCheckerBasic(mgr); \ 01541 mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\ 01542 } 01543 01544 REGISTER_CHECKER(MallocPessimistic) 01545 REGISTER_CHECKER(MallocOptimistic)