MallocChecker.cpp revision aca0ac58d2ae80d764e3832456667d7322445e0c
1//=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines malloc/free checker, which checks for potential memory 11// leaks, double free, and use-after-free problems. 12// 13//===----------------------------------------------------------------------===// 14 15#include "ClangSACheckers.h" 16#include "InterCheckerAPI.h" 17#include "clang/StaticAnalyzer/Core/Checker.h" 18#include "clang/StaticAnalyzer/Core/CheckerManager.h" 19#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 20#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 21#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" 22#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 23#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 24#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 25#include "clang/Basic/SourceManager.h" 26#include "llvm/ADT/ImmutableMap.h" 27#include "llvm/ADT/SmallString.h" 28#include "llvm/ADT/STLExtras.h" 29#include <climits> 30 31using namespace clang; 32using namespace ento; 33 34namespace { 35 36class RefState { 37 enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped, 38 Relinquished } K; 39 const Stmt *S; 40 41public: 42 RefState(Kind k, const Stmt *s) : K(k), S(s) {} 43 44 bool isAllocated() const { return K == AllocateUnchecked; } 45 bool isReleased() const { return K == Released; } 46 47 const Stmt *getStmt() const { return S; } 48 49 bool operator==(const RefState &X) const { 50 return K == X.K && S == X.S; 51 } 52 53 static RefState getAllocateUnchecked(const Stmt *s) { 54 return RefState(AllocateUnchecked, s); 55 } 56 static RefState getAllocateFailed() { 57 return RefState(AllocateFailed, 0); 58 } 59 static RefState getReleased(const Stmt *s) { return RefState(Released, s); } 60 static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); } 61 static RefState getRelinquished(const Stmt *s) { 62 return RefState(Relinquished, s); 63 } 64 65 void Profile(llvm::FoldingSetNodeID &ID) const { 66 ID.AddInteger(K); 67 ID.AddPointer(S); 68 } 69}; 70 71struct ReallocPair { 72 SymbolRef ReallocatedSym; 73 bool IsFreeOnFailure; 74 ReallocPair(SymbolRef S, bool F) : ReallocatedSym(S), IsFreeOnFailure(F) {} 75 void Profile(llvm::FoldingSetNodeID &ID) const { 76 ID.AddInteger(IsFreeOnFailure); 77 ID.AddPointer(ReallocatedSym); 78 } 79 bool operator==(const ReallocPair &X) const { 80 return ReallocatedSym == X.ReallocatedSym && 81 IsFreeOnFailure == X.IsFreeOnFailure; 82 } 83}; 84 85typedef std::pair<const Stmt*, const MemRegion*> LeakInfo; 86 87class MallocChecker : public Checker<check::DeadSymbols, 88 check::EndPath, 89 check::PreStmt<ReturnStmt>, 90 check::PreStmt<CallExpr>, 91 check::PostStmt<CallExpr>, 92 check::PostStmt<BlockExpr>, 93 check::Location, 94 check::Bind, 95 eval::Assume, 96 check::RegionChanges> 97{ 98 mutable OwningPtr<BugType> BT_DoubleFree; 99 mutable OwningPtr<BugType> BT_Leak; 100 mutable OwningPtr<BugType> BT_UseFree; 101 mutable OwningPtr<BugType> BT_BadFree; 102 mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc, 103 *II_valloc, *II_reallocf, *II_strndup, *II_strdup; 104 105public: 106 MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0), 107 II_valloc(0), II_reallocf(0), II_strndup(0), II_strdup(0) {} 108 109 /// In pessimistic mode, the checker assumes that it does not know which 110 /// functions might free the memory. 111 struct ChecksFilter { 112 DefaultBool CMallocPessimistic; 113 DefaultBool CMallocOptimistic; 114 }; 115 116 ChecksFilter Filter; 117 118 void checkPreStmt(const CallExpr *S, CheckerContext &C) const; 119 void checkPostStmt(const CallExpr *CE, CheckerContext &C) const; 120 void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const; 121 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; 122 void checkEndPath(CheckerContext &C) const; 123 void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const; 124 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, 125 bool Assumption) const; 126 void checkLocation(SVal l, bool isLoad, const Stmt *S, 127 CheckerContext &C) const; 128 void checkBind(SVal location, SVal val, const Stmt*S, 129 CheckerContext &C) const; 130 ProgramStateRef 131 checkRegionChanges(ProgramStateRef state, 132 const StoreManager::InvalidatedSymbols *invalidated, 133 ArrayRef<const MemRegion *> ExplicitRegions, 134 ArrayRef<const MemRegion *> Regions, 135 const CallOrObjCMessage *Call) const; 136 bool wantsRegionChangeUpdate(ProgramStateRef state) const { 137 return true; 138 } 139 140 void printState(raw_ostream &Out, ProgramStateRef State, 141 const char *NL, const char *Sep) const; 142 143private: 144 void initIdentifierInfo(ASTContext &C) const; 145 146 /// Check if this is one of the functions which can allocate/reallocate memory 147 /// pointed to by one of its arguments. 148 bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const; 149 150 static ProgramStateRef MallocMemReturnsAttr(CheckerContext &C, 151 const CallExpr *CE, 152 const OwnershipAttr* Att); 153 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, 154 const Expr *SizeEx, SVal Init, 155 ProgramStateRef state) { 156 return MallocMemAux(C, CE, 157 state->getSVal(SizeEx, C.getLocationContext()), 158 Init, state); 159 } 160 161 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, 162 SVal SizeEx, SVal Init, 163 ProgramStateRef state); 164 165 /// Update the RefState to reflect the new memory allocation. 166 static ProgramStateRef MallocUpdateRefState(CheckerContext &C, 167 const CallExpr *CE, 168 ProgramStateRef state); 169 170 ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE, 171 const OwnershipAttr* Att) const; 172 ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE, 173 ProgramStateRef state, unsigned Num, 174 bool Hold) const; 175 176 ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE, 177 bool FreesMemOnFailure) const; 178 static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE); 179 180 bool checkEscape(SymbolRef Sym, const Stmt *S, CheckerContext &C) const; 181 bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, 182 const Stmt *S = 0) const; 183 184 /// Check if the function is not known to us. So, for example, we could 185 /// conservatively assume it can free/reallocate it's pointer arguments. 186 bool doesNotFreeMemory(const CallOrObjCMessage *Call, 187 ProgramStateRef State) const; 188 189 static bool SummarizeValue(raw_ostream &os, SVal V); 190 static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR); 191 void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const; 192 193 /// Find the location of the allocation for Sym on the path leading to the 194 /// exploded node N. 195 LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym, 196 CheckerContext &C) const; 197 198 void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const; 199 200 /// The bug visitor which allows us to print extra diagnostics along the 201 /// BugReport path. For example, showing the allocation site of the leaked 202 /// region. 203 class MallocBugVisitor : public BugReporterVisitorImpl<MallocBugVisitor> { 204 protected: 205 enum NotificationMode { 206 Normal, 207 ReallocationFailed 208 }; 209 210 // The allocated region symbol tracked by the main analysis. 211 SymbolRef Sym; 212 213 // The mode we are in, i.e. what kind of diagnostics will be emitted. 214 NotificationMode Mode; 215 216 // A symbol from when the primary region should have been reallocated. 217 SymbolRef FailedReallocSymbol; 218 219 public: 220 MallocBugVisitor(SymbolRef S) 221 : Sym(S), Mode(Normal), FailedReallocSymbol(0) {} 222 223 virtual ~MallocBugVisitor() {} 224 225 void Profile(llvm::FoldingSetNodeID &ID) const { 226 static int X = 0; 227 ID.AddPointer(&X); 228 ID.AddPointer(Sym); 229 } 230 231 inline bool isAllocated(const RefState *S, const RefState *SPrev, 232 const Stmt *Stmt) { 233 // Did not track -> allocated. Other state (released) -> allocated. 234 return (Stmt && isa<CallExpr>(Stmt) && 235 (S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated())); 236 } 237 238 inline bool isReleased(const RefState *S, const RefState *SPrev, 239 const Stmt *Stmt) { 240 // Did not track -> released. Other state (allocated) -> released. 241 return (Stmt && isa<CallExpr>(Stmt) && 242 (S && S->isReleased()) && (!SPrev || !SPrev->isReleased())); 243 } 244 245 inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev, 246 const Stmt *Stmt) { 247 // If the expression is not a call, and the state change is 248 // released -> allocated, it must be the realloc return value 249 // check. If we have to handle more cases here, it might be cleaner just 250 // to track this extra bit in the state itself. 251 return ((!Stmt || !isa<CallExpr>(Stmt)) && 252 (S && S->isAllocated()) && (SPrev && !SPrev->isAllocated())); 253 } 254 255 PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 256 const ExplodedNode *PrevN, 257 BugReporterContext &BRC, 258 BugReport &BR); 259 private: 260 class StackHintGeneratorForReallocationFailed 261 : public StackHintGeneratorForSymbol { 262 public: 263 StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M) 264 : StackHintGeneratorForSymbol(S, M) {} 265 266 virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) { 267 SmallString<200> buf; 268 llvm::raw_svector_ostream os(buf); 269 270 os << "Reallocation of "; 271 // Printed parameters start at 1, not 0. 272 printOrdinal(++ArgIndex, os); 273 os << " parameter failed"; 274 275 return os.str(); 276 } 277 278 virtual std::string getMessageForReturn(const CallExpr *CallExpr) { 279 return "Reallocation of returned value failed"; 280 } 281 }; 282 }; 283}; 284} // end anonymous namespace 285 286typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy; 287typedef llvm::ImmutableMap<SymbolRef, ReallocPair > ReallocMap; 288class RegionState {}; 289class ReallocPairs {}; 290namespace clang { 291namespace ento { 292 template <> 293 struct ProgramStateTrait<RegionState> 294 : public ProgramStatePartialTrait<RegionStateTy> { 295 static void *GDMIndex() { static int x; return &x; } 296 }; 297 298 template <> 299 struct ProgramStateTrait<ReallocPairs> 300 : public ProgramStatePartialTrait<ReallocMap> { 301 static void *GDMIndex() { static int x; return &x; } 302 }; 303} 304} 305 306namespace { 307class StopTrackingCallback : public SymbolVisitor { 308 ProgramStateRef state; 309public: 310 StopTrackingCallback(ProgramStateRef st) : state(st) {} 311 ProgramStateRef getState() const { return state; } 312 313 bool VisitSymbol(SymbolRef sym) { 314 state = state->remove<RegionState>(sym); 315 return true; 316 } 317}; 318} // end anonymous namespace 319 320void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { 321 if (!II_malloc) 322 II_malloc = &Ctx.Idents.get("malloc"); 323 if (!II_free) 324 II_free = &Ctx.Idents.get("free"); 325 if (!II_realloc) 326 II_realloc = &Ctx.Idents.get("realloc"); 327 if (!II_reallocf) 328 II_reallocf = &Ctx.Idents.get("reallocf"); 329 if (!II_calloc) 330 II_calloc = &Ctx.Idents.get("calloc"); 331 if (!II_valloc) 332 II_valloc = &Ctx.Idents.get("valloc"); 333 if (!II_strdup) 334 II_strdup = &Ctx.Idents.get("strdup"); 335 if (!II_strndup) 336 II_strndup = &Ctx.Idents.get("strndup"); 337} 338 339bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const { 340 if (!FD) 341 return false; 342 IdentifierInfo *FunI = FD->getIdentifier(); 343 if (!FunI) 344 return false; 345 346 initIdentifierInfo(C); 347 348 if (FunI == II_malloc || FunI == II_free || FunI == II_realloc || 349 FunI == II_reallocf || FunI == II_calloc || FunI == II_valloc || 350 FunI == II_strdup || FunI == II_strndup) 351 return true; 352 353 if (Filter.CMallocOptimistic && FD->hasAttrs() && 354 FD->specific_attr_begin<OwnershipAttr>() != 355 FD->specific_attr_end<OwnershipAttr>()) 356 return true; 357 358 359 return false; 360} 361 362void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { 363 const FunctionDecl *FD = C.getCalleeDecl(CE); 364 if (!FD) 365 return; 366 367 initIdentifierInfo(C.getASTContext()); 368 IdentifierInfo *FunI = FD->getIdentifier(); 369 if (!FunI) 370 return; 371 372 ProgramStateRef State = C.getState(); 373 if (FunI == II_malloc || FunI == II_valloc) { 374 if (CE->getNumArgs() < 1) 375 return; 376 State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State); 377 } else if (FunI == II_realloc) { 378 State = ReallocMem(C, CE, false); 379 } else if (FunI == II_reallocf) { 380 State = ReallocMem(C, CE, true); 381 } else if (FunI == II_calloc) { 382 State = CallocMem(C, CE); 383 } else if (FunI == II_free) { 384 State = FreeMemAux(C, CE, C.getState(), 0, false); 385 } else if (FunI == II_strdup) { 386 State = MallocUpdateRefState(C, CE, State); 387 } else if (FunI == II_strndup) { 388 State = MallocUpdateRefState(C, CE, State); 389 } else if (Filter.CMallocOptimistic) { 390 // Check all the attributes, if there are any. 391 // There can be multiple of these attributes. 392 if (FD->hasAttrs()) 393 for (specific_attr_iterator<OwnershipAttr> 394 i = FD->specific_attr_begin<OwnershipAttr>(), 395 e = FD->specific_attr_end<OwnershipAttr>(); 396 i != e; ++i) { 397 switch ((*i)->getOwnKind()) { 398 case OwnershipAttr::Returns: 399 State = MallocMemReturnsAttr(C, CE, *i); 400 break; 401 case OwnershipAttr::Takes: 402 case OwnershipAttr::Holds: 403 State = FreeMemAttr(C, CE, *i); 404 break; 405 } 406 } 407 } 408 C.addTransition(State); 409} 410 411ProgramStateRef MallocChecker::MallocMemReturnsAttr(CheckerContext &C, 412 const CallExpr *CE, 413 const OwnershipAttr* Att) { 414 if (Att->getModule() != "malloc") 415 return 0; 416 417 OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); 418 if (I != E) { 419 return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState()); 420 } 421 return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), C.getState()); 422} 423 424ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, 425 const CallExpr *CE, 426 SVal Size, SVal Init, 427 ProgramStateRef state) { 428 // Get the return value. 429 SVal retVal = state->getSVal(CE, C.getLocationContext()); 430 431 // We expect the malloc functions to return a pointer. 432 if (!isa<Loc>(retVal)) 433 return 0; 434 435 // Fill the region with the initialization value. 436 state = state->bindDefault(retVal, Init); 437 438 // Set the region's extent equal to the Size parameter. 439 const SymbolicRegion *R = 440 dyn_cast_or_null<SymbolicRegion>(retVal.getAsRegion()); 441 if (!R) 442 return 0; 443 if (isa<DefinedOrUnknownSVal>(Size)) { 444 SValBuilder &svalBuilder = C.getSValBuilder(); 445 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder); 446 DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size); 447 DefinedOrUnknownSVal extentMatchesSize = 448 svalBuilder.evalEQ(state, Extent, DefinedSize); 449 450 state = state->assume(extentMatchesSize, true); 451 assert(state); 452 } 453 454 return MallocUpdateRefState(C, CE, state); 455} 456 457ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C, 458 const CallExpr *CE, 459 ProgramStateRef state) { 460 // Get the return value. 461 SVal retVal = state->getSVal(CE, C.getLocationContext()); 462 463 // We expect the malloc functions to return a pointer. 464 if (!isa<Loc>(retVal)) 465 return 0; 466 467 SymbolRef Sym = retVal.getAsLocSymbol(); 468 assert(Sym); 469 470 // Set the symbol's state to Allocated. 471 return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE)); 472 473} 474 475ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C, 476 const CallExpr *CE, 477 const OwnershipAttr* Att) const { 478 if (Att->getModule() != "malloc") 479 return 0; 480 481 ProgramStateRef State = C.getState(); 482 483 for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); 484 I != E; ++I) { 485 ProgramStateRef StateI = FreeMemAux(C, CE, State, *I, 486 Att->getOwnKind() == OwnershipAttr::Holds); 487 if (StateI) 488 State = StateI; 489 } 490 return State; 491} 492 493ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, 494 const CallExpr *CE, 495 ProgramStateRef state, 496 unsigned Num, 497 bool Hold) const { 498 if (CE->getNumArgs() < (Num + 1)) 499 return 0; 500 501 const Expr *ArgExpr = CE->getArg(Num); 502 SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext()); 503 if (!isa<DefinedOrUnknownSVal>(ArgVal)) 504 return 0; 505 DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal); 506 507 // Check for null dereferences. 508 if (!isa<Loc>(location)) 509 return 0; 510 511 // The explicit NULL case, no operation is performed. 512 ProgramStateRef notNullState, nullState; 513 llvm::tie(notNullState, nullState) = state->assume(location); 514 if (nullState && !notNullState) 515 return 0; 516 517 // Unknown values could easily be okay 518 // Undefined values are handled elsewhere 519 if (ArgVal.isUnknownOrUndef()) 520 return 0; 521 522 const MemRegion *R = ArgVal.getAsRegion(); 523 524 // Nonlocs can't be freed, of course. 525 // Non-region locations (labels and fixed addresses) also shouldn't be freed. 526 if (!R) { 527 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange()); 528 return 0; 529 } 530 531 R = R->StripCasts(); 532 533 // Blocks might show up as heap data, but should not be free()d 534 if (isa<BlockDataRegion>(R)) { 535 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange()); 536 return 0; 537 } 538 539 const MemSpaceRegion *MS = R->getMemorySpace(); 540 541 // Parameters, locals, statics, and globals shouldn't be freed. 542 if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) { 543 // FIXME: at the time this code was written, malloc() regions were 544 // represented by conjured symbols, which are all in UnknownSpaceRegion. 545 // This means that there isn't actually anything from HeapSpaceRegion 546 // that should be freed, even though we allow it here. 547 // Of course, free() can work on memory allocated outside the current 548 // function, so UnknownSpaceRegion is always a possibility. 549 // False negatives are better than false positives. 550 551 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange()); 552 return 0; 553 } 554 555 const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R); 556 // Various cases could lead to non-symbol values here. 557 // For now, ignore them. 558 if (!SR) 559 return 0; 560 561 SymbolRef Sym = SR->getSymbol(); 562 const RefState *RS = state->get<RegionState>(Sym); 563 564 // If the symbol has not been tracked, return. This is possible when free() is 565 // called on a pointer that does not get its pointee directly from malloc(). 566 // Full support of this requires inter-procedural analysis. 567 if (!RS) 568 return 0; 569 570 // Check double free. 571 if (RS->isReleased()) { 572 if (ExplodedNode *N = C.generateSink()) { 573 if (!BT_DoubleFree) 574 BT_DoubleFree.reset( 575 new BugType("Double free", "Memory Error")); 576 BugReport *R = new BugReport(*BT_DoubleFree, 577 "Attempt to free released memory", N); 578 R->addRange(ArgExpr->getSourceRange()); 579 R->markInteresting(Sym); 580 R->addVisitor(new MallocBugVisitor(Sym)); 581 C.EmitReport(R); 582 } 583 return 0; 584 } 585 586 // Normal free. 587 if (Hold) 588 return state->set<RegionState>(Sym, RefState::getRelinquished(CE)); 589 return state->set<RegionState>(Sym, RefState::getReleased(CE)); 590} 591 592bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) { 593 if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V)) 594 os << "an integer (" << IntVal->getValue() << ")"; 595 else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V)) 596 os << "a constant address (" << ConstAddr->getValue() << ")"; 597 else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V)) 598 os << "the address of the label '" << Label->getLabel()->getName() << "'"; 599 else 600 return false; 601 602 return true; 603} 604 605bool MallocChecker::SummarizeRegion(raw_ostream &os, 606 const MemRegion *MR) { 607 switch (MR->getKind()) { 608 case MemRegion::FunctionTextRegionKind: { 609 const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl(); 610 if (FD) 611 os << "the address of the function '" << *FD << '\''; 612 else 613 os << "the address of a function"; 614 return true; 615 } 616 case MemRegion::BlockTextRegionKind: 617 os << "block text"; 618 return true; 619 case MemRegion::BlockDataRegionKind: 620 // FIXME: where the block came from? 621 os << "a block"; 622 return true; 623 default: { 624 const MemSpaceRegion *MS = MR->getMemorySpace(); 625 626 if (isa<StackLocalsSpaceRegion>(MS)) { 627 const VarRegion *VR = dyn_cast<VarRegion>(MR); 628 const VarDecl *VD; 629 if (VR) 630 VD = VR->getDecl(); 631 else 632 VD = NULL; 633 634 if (VD) 635 os << "the address of the local variable '" << VD->getName() << "'"; 636 else 637 os << "the address of a local stack variable"; 638 return true; 639 } 640 641 if (isa<StackArgumentsSpaceRegion>(MS)) { 642 const VarRegion *VR = dyn_cast<VarRegion>(MR); 643 const VarDecl *VD; 644 if (VR) 645 VD = VR->getDecl(); 646 else 647 VD = NULL; 648 649 if (VD) 650 os << "the address of the parameter '" << VD->getName() << "'"; 651 else 652 os << "the address of a parameter"; 653 return true; 654 } 655 656 if (isa<GlobalsSpaceRegion>(MS)) { 657 const VarRegion *VR = dyn_cast<VarRegion>(MR); 658 const VarDecl *VD; 659 if (VR) 660 VD = VR->getDecl(); 661 else 662 VD = NULL; 663 664 if (VD) { 665 if (VD->isStaticLocal()) 666 os << "the address of the static variable '" << VD->getName() << "'"; 667 else 668 os << "the address of the global variable '" << VD->getName() << "'"; 669 } else 670 os << "the address of a global variable"; 671 return true; 672 } 673 674 return false; 675 } 676 } 677} 678 679void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal, 680 SourceRange range) const { 681 if (ExplodedNode *N = C.generateSink()) { 682 if (!BT_BadFree) 683 BT_BadFree.reset(new BugType("Bad free", "Memory Error")); 684 685 SmallString<100> buf; 686 llvm::raw_svector_ostream os(buf); 687 688 const MemRegion *MR = ArgVal.getAsRegion(); 689 if (MR) { 690 while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR)) 691 MR = ER->getSuperRegion(); 692 693 // Special case for alloca() 694 if (isa<AllocaRegion>(MR)) 695 os << "Argument to free() was allocated by alloca(), not malloc()"; 696 else { 697 os << "Argument to free() is "; 698 if (SummarizeRegion(os, MR)) 699 os << ", which is not memory allocated by malloc()"; 700 else 701 os << "not memory allocated by malloc()"; 702 } 703 } else { 704 os << "Argument to free() is "; 705 if (SummarizeValue(os, ArgVal)) 706 os << ", which is not memory allocated by malloc()"; 707 else 708 os << "not memory allocated by malloc()"; 709 } 710 711 BugReport *R = new BugReport(*BT_BadFree, os.str(), N); 712 R->markInteresting(MR); 713 R->addRange(range); 714 C.EmitReport(R); 715 } 716} 717 718ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C, 719 const CallExpr *CE, 720 bool FreesOnFail) const { 721 if (CE->getNumArgs() < 2) 722 return 0; 723 724 ProgramStateRef state = C.getState(); 725 const Expr *arg0Expr = CE->getArg(0); 726 const LocationContext *LCtx = C.getLocationContext(); 727 SVal Arg0Val = state->getSVal(arg0Expr, LCtx); 728 if (!isa<DefinedOrUnknownSVal>(Arg0Val)) 729 return 0; 730 DefinedOrUnknownSVal arg0Val = cast<DefinedOrUnknownSVal>(Arg0Val); 731 732 SValBuilder &svalBuilder = C.getSValBuilder(); 733 734 DefinedOrUnknownSVal PtrEQ = 735 svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull()); 736 737 // Get the size argument. If there is no size arg then give up. 738 const Expr *Arg1 = CE->getArg(1); 739 if (!Arg1) 740 return 0; 741 742 // Get the value of the size argument. 743 SVal Arg1ValG = state->getSVal(Arg1, LCtx); 744 if (!isa<DefinedOrUnknownSVal>(Arg1ValG)) 745 return 0; 746 DefinedOrUnknownSVal Arg1Val = cast<DefinedOrUnknownSVal>(Arg1ValG); 747 748 // Compare the size argument to 0. 749 DefinedOrUnknownSVal SizeZero = 750 svalBuilder.evalEQ(state, Arg1Val, 751 svalBuilder.makeIntValWithPtrWidth(0, false)); 752 753 ProgramStateRef StatePtrIsNull, StatePtrNotNull; 754 llvm::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ); 755 ProgramStateRef StateSizeIsZero, StateSizeNotZero; 756 llvm::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero); 757 // We only assume exceptional states if they are definitely true; if the 758 // state is under-constrained, assume regular realloc behavior. 759 bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull; 760 bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero; 761 762 // If the ptr is NULL and the size is not 0, the call is equivalent to 763 // malloc(size). 764 if ( PrtIsNull && !SizeIsZero) { 765 ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1), 766 UndefinedVal(), StatePtrIsNull); 767 return stateMalloc; 768 } 769 770 if (PrtIsNull && SizeIsZero) 771 return 0; 772 773 // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size). 774 assert(!PrtIsNull); 775 SymbolRef FromPtr = arg0Val.getAsSymbol(); 776 SVal RetVal = state->getSVal(CE, LCtx); 777 SymbolRef ToPtr = RetVal.getAsSymbol(); 778 if (!FromPtr || !ToPtr) 779 return 0; 780 781 // If the size is 0, free the memory. 782 if (SizeIsZero) 783 if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero,0,false)){ 784 // The semantics of the return value are: 785 // If size was equal to 0, either NULL or a pointer suitable to be passed 786 // to free() is returned. 787 stateFree = stateFree->set<ReallocPairs>(ToPtr, 788 ReallocPair(FromPtr, FreesOnFail)); 789 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr); 790 return stateFree; 791 } 792 793 // Default behavior. 794 if (ProgramStateRef stateFree = FreeMemAux(C, CE, state, 0, false)) { 795 // FIXME: We should copy the content of the original buffer. 796 ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1), 797 UnknownVal(), stateFree); 798 if (!stateRealloc) 799 return 0; 800 stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr, 801 ReallocPair(FromPtr, FreesOnFail)); 802 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr); 803 return stateRealloc; 804 } 805 return 0; 806} 807 808ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){ 809 if (CE->getNumArgs() < 2) 810 return 0; 811 812 ProgramStateRef state = C.getState(); 813 SValBuilder &svalBuilder = C.getSValBuilder(); 814 const LocationContext *LCtx = C.getLocationContext(); 815 SVal count = state->getSVal(CE->getArg(0), LCtx); 816 SVal elementSize = state->getSVal(CE->getArg(1), LCtx); 817 SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize, 818 svalBuilder.getContext().getSizeType()); 819 SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); 820 821 return MallocMemAux(C, CE, TotalSize, zeroVal, state); 822} 823 824LeakInfo 825MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym, 826 CheckerContext &C) const { 827 const LocationContext *LeakContext = N->getLocationContext(); 828 // Walk the ExplodedGraph backwards and find the first node that referred to 829 // the tracked symbol. 830 const ExplodedNode *AllocNode = N; 831 const MemRegion *ReferenceRegion = 0; 832 833 while (N) { 834 ProgramStateRef State = N->getState(); 835 if (!State->get<RegionState>(Sym)) 836 break; 837 838 // Find the most recent expression bound to the symbol in the current 839 // context. 840 if (!ReferenceRegion) { 841 if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) { 842 SVal Val = State->getSVal(MR); 843 if (Val.getAsLocSymbol() == Sym) 844 ReferenceRegion = MR; 845 } 846 } 847 848 // Allocation node, is the last node in the current context in which the 849 // symbol was tracked. 850 if (N->getLocationContext() == LeakContext) 851 AllocNode = N; 852 N = N->pred_empty() ? NULL : *(N->pred_begin()); 853 } 854 855 ProgramPoint P = AllocNode->getLocation(); 856 const Stmt *AllocationStmt = 0; 857 if (isa<StmtPoint>(P)) 858 AllocationStmt = cast<StmtPoint>(P).getStmt(); 859 860 return LeakInfo(AllocationStmt, ReferenceRegion); 861} 862 863void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N, 864 CheckerContext &C) const { 865 assert(N); 866 if (!BT_Leak) { 867 BT_Leak.reset(new BugType("Memory leak", "Memory Error")); 868 // Leaks should not be reported if they are post-dominated by a sink: 869 // (1) Sinks are higher importance bugs. 870 // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending 871 // with __noreturn functions such as assert() or exit(). We choose not 872 // to report leaks on such paths. 873 BT_Leak->setSuppressOnSink(true); 874 } 875 876 // Most bug reports are cached at the location where they occurred. 877 // With leaks, we want to unique them by the location where they were 878 // allocated, and only report a single path. 879 PathDiagnosticLocation LocUsedForUniqueing; 880 const Stmt *AllocStmt = 0; 881 const MemRegion *Region = 0; 882 llvm::tie(AllocStmt, Region) = getAllocationSite(N, Sym, C); 883 if (AllocStmt) 884 LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocStmt, 885 C.getSourceManager(), N->getLocationContext()); 886 887 SmallString<200> buf; 888 llvm::raw_svector_ostream os(buf); 889 os << "Memory is never released; potential leak"; 890 if (Region) { 891 os << " of memory pointed to by '"; 892 Region->dumpPretty(os); 893 os <<'\''; 894 } 895 896 BugReport *R = new BugReport(*BT_Leak, os.str(), N, LocUsedForUniqueing); 897 R->markInteresting(Sym); 898 R->addVisitor(new MallocBugVisitor(Sym)); 899 C.EmitReport(R); 900} 901 902void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper, 903 CheckerContext &C) const 904{ 905 if (!SymReaper.hasDeadSymbols()) 906 return; 907 908 ProgramStateRef state = C.getState(); 909 RegionStateTy RS = state->get<RegionState>(); 910 RegionStateTy::Factory &F = state->get_context<RegionState>(); 911 912 bool generateReport = false; 913 llvm::SmallVector<SymbolRef, 2> Errors; 914 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { 915 if (SymReaper.isDead(I->first)) { 916 if (I->second.isAllocated()) { 917 generateReport = true; 918 Errors.push_back(I->first); 919 } 920 // Remove the dead symbol from the map. 921 RS = F.remove(RS, I->first); 922 923 } 924 } 925 926 // Cleanup the Realloc Pairs Map. 927 ReallocMap RP = state->get<ReallocPairs>(); 928 for (ReallocMap::iterator I = RP.begin(), E = RP.end(); I != E; ++I) { 929 if (SymReaper.isDead(I->first) || 930 SymReaper.isDead(I->second.ReallocatedSym)) { 931 state = state->remove<ReallocPairs>(I->first); 932 } 933 } 934 935 // Generate leak node. 936 static SimpleProgramPointTag Tag("MallocChecker : DeadSymbolsLeak"); 937 ExplodedNode *N = C.addTransition(C.getState(), C.getPredecessor(), &Tag); 938 939 if (generateReport) { 940 for (llvm::SmallVector<SymbolRef, 2>::iterator 941 I = Errors.begin(), E = Errors.end(); I != E; ++I) { 942 reportLeak(*I, N, C); 943 } 944 } 945 C.addTransition(state->set<RegionState>(RS), N); 946} 947 948void MallocChecker::checkEndPath(CheckerContext &C) const { 949 ProgramStateRef state = C.getState(); 950 RegionStateTy M = state->get<RegionState>(); 951 952 // If inside inlined call, skip it. 953 if (C.getLocationContext()->getParent() != 0) 954 return; 955 956 for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) { 957 RefState RS = I->second; 958 if (RS.isAllocated()) { 959 ExplodedNode *N = C.addTransition(state); 960 if (N) 961 reportLeak(I->first, N, C); 962 } 963 } 964} 965 966bool MallocChecker::checkEscape(SymbolRef Sym, const Stmt *S, 967 CheckerContext &C) const { 968 ProgramStateRef state = C.getState(); 969 const RefState *RS = state->get<RegionState>(Sym); 970 if (!RS) 971 return false; 972 973 if (RS->isAllocated()) { 974 state = state->set<RegionState>(Sym, RefState::getEscaped(S)); 975 C.addTransition(state); 976 return true; 977 } 978 return false; 979} 980 981void MallocChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { 982 if (isMemFunction(C.getCalleeDecl(CE), C.getASTContext())) 983 return; 984 985 // Check use after free, when a freed pointer is passed to a call. 986 ProgramStateRef State = C.getState(); 987 for (CallExpr::const_arg_iterator I = CE->arg_begin(), 988 E = CE->arg_end(); I != E; ++I) { 989 const Expr *A = *I; 990 if (A->getType().getTypePtr()->isAnyPointerType()) { 991 SymbolRef Sym = State->getSVal(A, C.getLocationContext()).getAsSymbol(); 992 if (!Sym) 993 continue; 994 if (checkUseAfterFree(Sym, C, A)) 995 return; 996 } 997 } 998} 999 1000void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const { 1001 const Expr *E = S->getRetValue(); 1002 if (!E) 1003 return; 1004 1005 // Check if we are returning a symbol. 1006 SVal RetVal = C.getState()->getSVal(E, C.getLocationContext()); 1007 SymbolRef Sym = RetVal.getAsSymbol(); 1008 if (!Sym) 1009 // If we are returning a field of the allocated struct or an array element, 1010 // the callee could still free the memory. 1011 // TODO: This logic should be a part of generic symbol escape callback. 1012 if (const MemRegion *MR = RetVal.getAsRegion()) 1013 if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR)) 1014 if (const SymbolicRegion *BMR = 1015 dyn_cast<SymbolicRegion>(MR->getBaseRegion())) 1016 Sym = BMR->getSymbol(); 1017 if (!Sym) 1018 return; 1019 1020 // Check if we are returning freed memory. 1021 if (checkUseAfterFree(Sym, C, E)) 1022 return; 1023 1024 // If this function body is not inlined, check if the symbol is escaping. 1025 if (C.getLocationContext()->getParent() == 0) 1026 checkEscape(Sym, E, C); 1027} 1028 1029// TODO: Blocks should be either inlined or should call invalidate regions 1030// upon invocation. After that's in place, special casing here will not be 1031// needed. 1032void MallocChecker::checkPostStmt(const BlockExpr *BE, 1033 CheckerContext &C) const { 1034 1035 // Scan the BlockDecRefExprs for any object the retain count checker 1036 // may be tracking. 1037 if (!BE->getBlockDecl()->hasCaptures()) 1038 return; 1039 1040 ProgramStateRef state = C.getState(); 1041 const BlockDataRegion *R = 1042 cast<BlockDataRegion>(state->getSVal(BE, 1043 C.getLocationContext()).getAsRegion()); 1044 1045 BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(), 1046 E = R->referenced_vars_end(); 1047 1048 if (I == E) 1049 return; 1050 1051 SmallVector<const MemRegion*, 10> Regions; 1052 const LocationContext *LC = C.getLocationContext(); 1053 MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager(); 1054 1055 for ( ; I != E; ++I) { 1056 const VarRegion *VR = *I; 1057 if (VR->getSuperRegion() == R) { 1058 VR = MemMgr.getVarRegion(VR->getDecl(), LC); 1059 } 1060 Regions.push_back(VR); 1061 } 1062 1063 state = 1064 state->scanReachableSymbols<StopTrackingCallback>(Regions.data(), 1065 Regions.data() + Regions.size()).getState(); 1066 C.addTransition(state); 1067} 1068 1069bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C, 1070 const Stmt *S) const { 1071 assert(Sym); 1072 const RefState *RS = C.getState()->get<RegionState>(Sym); 1073 if (RS && RS->isReleased()) { 1074 if (ExplodedNode *N = C.generateSink()) { 1075 if (!BT_UseFree) 1076 BT_UseFree.reset(new BugType("Use-after-free", "Memory Error")); 1077 1078 BugReport *R = new BugReport(*BT_UseFree, 1079 "Use of memory after it is freed",N); 1080 if (S) 1081 R->addRange(S->getSourceRange()); 1082 R->markInteresting(Sym); 1083 R->addVisitor(new MallocBugVisitor(Sym)); 1084 C.EmitReport(R); 1085 return true; 1086 } 1087 } 1088 return false; 1089} 1090 1091// Check if the location is a freed symbolic region. 1092void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S, 1093 CheckerContext &C) const { 1094 SymbolRef Sym = l.getLocSymbolInBase(); 1095 if (Sym) 1096 checkUseAfterFree(Sym, C); 1097} 1098 1099//===----------------------------------------------------------------------===// 1100// Check various ways a symbol can be invalidated. 1101// TODO: This logic (the next 3 functions) is copied/similar to the 1102// RetainRelease checker. We might want to factor this out. 1103//===----------------------------------------------------------------------===// 1104 1105// Stop tracking symbols when a value escapes as a result of checkBind. 1106// A value escapes in three possible cases: 1107// (1) we are binding to something that is not a memory region. 1108// (2) we are binding to a memregion that does not have stack storage 1109// (3) we are binding to a memregion with stack storage that the store 1110// does not understand. 1111void MallocChecker::checkBind(SVal loc, SVal val, const Stmt *S, 1112 CheckerContext &C) const { 1113 // Are we storing to something that causes the value to "escape"? 1114 bool escapes = true; 1115 ProgramStateRef state = C.getState(); 1116 1117 if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) { 1118 escapes = !regionLoc->getRegion()->hasStackStorage(); 1119 1120 if (!escapes) { 1121 // To test (3), generate a new state with the binding added. If it is 1122 // the same state, then it escapes (since the store cannot represent 1123 // the binding). 1124 // Do this only if we know that the store is not supposed to generate the 1125 // same state. 1126 SVal StoredVal = state->getSVal(regionLoc->getRegion()); 1127 if (StoredVal != val) 1128 escapes = (state == (state->bindLoc(*regionLoc, val))); 1129 } 1130 if (!escapes) { 1131 // Case 4: We do not currently model what happens when a symbol is 1132 // assigned to a struct field, so be conservative here and let the symbol 1133 // go. TODO: This could definitely be improved upon. 1134 escapes = !isa<VarRegion>(regionLoc->getRegion()); 1135 } 1136 } 1137 1138 // If our store can represent the binding and we aren't storing to something 1139 // that doesn't have local storage then just return and have the simulation 1140 // state continue as is. 1141 if (!escapes) 1142 return; 1143 1144 // Otherwise, find all symbols referenced by 'val' that we are tracking 1145 // and stop tracking them. 1146 state = state->scanReachableSymbols<StopTrackingCallback>(val).getState(); 1147 C.addTransition(state); 1148} 1149 1150// If a symbolic region is assumed to NULL (or another constant), stop tracking 1151// it - assuming that allocation failed on this path. 1152ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, 1153 SVal Cond, 1154 bool Assumption) const { 1155 RegionStateTy RS = state->get<RegionState>(); 1156 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { 1157 // If the symbol is assumed to NULL or another constant, this will 1158 // return an APSInt*. 1159 if (state->getSymVal(I.getKey())) 1160 state = state->remove<RegionState>(I.getKey()); 1161 } 1162 1163 // Realloc returns 0 when reallocation fails, which means that we should 1164 // restore the state of the pointer being reallocated. 1165 ReallocMap RP = state->get<ReallocPairs>(); 1166 for (ReallocMap::iterator I = RP.begin(), E = RP.end(); I != E; ++I) { 1167 // If the symbol is assumed to NULL or another constant, this will 1168 // return an APSInt*. 1169 if (state->getSymVal(I.getKey())) { 1170 SymbolRef ReallocSym = I.getData().ReallocatedSym; 1171 const RefState *RS = state->get<RegionState>(ReallocSym); 1172 if (RS) { 1173 if (RS->isReleased() && ! I.getData().IsFreeOnFailure) 1174 state = state->set<RegionState>(ReallocSym, 1175 RefState::getAllocateUnchecked(RS->getStmt())); 1176 } 1177 state = state->remove<ReallocPairs>(I.getKey()); 1178 } 1179 } 1180 1181 return state; 1182} 1183 1184// Check if the function is known to us. So, for example, we could 1185// conservatively assume it can free/reallocate it's pointer arguments. 1186// (We assume that the pointers cannot escape through calls to system 1187// functions not handled by this checker.) 1188bool MallocChecker::doesNotFreeMemory(const CallOrObjCMessage *Call, 1189 ProgramStateRef State) const { 1190 if (!Call) 1191 return false; 1192 1193 // For now, assume that any C++ call can free memory. 1194 // TODO: If we want to be more optimistic here, we'll need to make sure that 1195 // regions escape to C++ containers. They seem to do that even now, but for 1196 // mysterious reasons. 1197 if (Call->isCXXCall()) 1198 return false; 1199 1200 const Decl *D = Call->getDecl(); 1201 if (!D) 1202 return false; 1203 1204 ASTContext &ASTC = State->getStateManager().getContext(); 1205 1206 // If it's one of the allocation functions we can reason about, we model 1207 // its behavior explicitly. 1208 if (isa<FunctionDecl>(D) && isMemFunction(cast<FunctionDecl>(D), ASTC)) { 1209 return true; 1210 } 1211 1212 // If it's not a system call, assume it frees memory. 1213 SourceManager &SM = ASTC.getSourceManager(); 1214 if (!SM.isInSystemHeader(D->getLocation())) 1215 return false; 1216 1217 // Process C/ObjC functions. 1218 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 1219 // White list the system functions whose arguments escape. 1220 const IdentifierInfo *II = FD->getIdentifier(); 1221 if (!II) 1222 return true; 1223 StringRef FName = II->getName(); 1224 1225 // White list thread local storage. 1226 if (FName.equals("pthread_setspecific")) 1227 return false; 1228 1229 // White list the 'XXXNoCopy' ObjC functions. 1230 if (FName.endswith("NoCopy")) { 1231 // Look for the deallocator argument. We know that the memory ownership 1232 // is not transfered only if the deallocator argument is 1233 // 'kCFAllocatorNull'. 1234 for (unsigned i = 1; i < Call->getNumArgs(); ++i) { 1235 const Expr *ArgE = Call->getArg(i)->IgnoreParenCasts(); 1236 if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) { 1237 StringRef DeallocatorName = DE->getFoundDecl()->getName(); 1238 if (DeallocatorName == "kCFAllocatorNull") 1239 return true; 1240 } 1241 } 1242 return false; 1243 } 1244 1245 // PR12101 1246 // Many CoreFoundation and CoreGraphics might allow a tracked object 1247 // to escape. 1248 if (Call->isCFCGAllowingEscape(FName)) 1249 return false; 1250 1251 // Associating streams with malloced buffers. The pointer can escape if 1252 // 'closefn' is specified (and if that function does free memory). 1253 // Currently, we do not inspect the 'closefn' function (PR12101). 1254 if (FName == "funopen") 1255 if (Call->getNumArgs() >= 4 && !Call->getArgSVal(4).isConstant(0)) 1256 return false; 1257 1258 // Do not warn on pointers passed to 'setbuf' when used with std streams, 1259 // these leaks might be intentional when setting the buffer for stdio. 1260 // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer 1261 if (FName == "setbuf" || FName =="setbuffer" || 1262 FName == "setlinebuf" || FName == "setvbuf") { 1263 if (Call->getNumArgs() >= 1) 1264 if (const DeclRefExpr *Arg = 1265 dyn_cast<DeclRefExpr>(Call->getArg(0)->IgnoreParenCasts())) 1266 if (const VarDecl *D = dyn_cast<VarDecl>(Arg->getDecl())) 1267 if (D->getCanonicalDecl()->getName().find("std") 1268 != StringRef::npos) 1269 return false; 1270 } 1271 1272 // A bunch of other functions, which take ownership of a pointer (See retain 1273 // release checker). Not all the parameters here are invalidated, but the 1274 // Malloc checker cannot differentiate between them. The right way of doing 1275 // this would be to implement a pointer escapes callback. 1276 if (FName == "CVPixelBufferCreateWithBytes" || 1277 FName == "CGBitmapContextCreateWithData" || 1278 FName == "CVPixelBufferCreateWithPlanarBytes" || 1279 FName == "OSAtomicEnqueue") { 1280 return false; 1281 } 1282 1283 // Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can 1284 // be deallocated by NSMapRemove. 1285 if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos)) 1286 return false; 1287 1288 // If the call has a callback as an argument, assume the memory 1289 // can be freed. 1290 if (Call->hasNonZeroCallbackArg()) 1291 return false; 1292 1293 // Otherwise, assume that the function does not free memory. 1294 // Most system calls, do not free the memory. 1295 return true; 1296 1297 // Process ObjC functions. 1298 } else if (const ObjCMethodDecl * ObjCD = dyn_cast<ObjCMethodDecl>(D)) { 1299 Selector S = ObjCD->getSelector(); 1300 1301 // White list the ObjC functions which do free memory. 1302 // - Anything containing 'freeWhenDone' param set to 1. 1303 // Ex: dataWithBytesNoCopy:length:freeWhenDone. 1304 for (unsigned i = 1; i < S.getNumArgs(); ++i) { 1305 if (S.getNameForSlot(i).equals("freeWhenDone")) { 1306 if (Call->getArgSVal(i).isConstant(1)) 1307 return false; 1308 else 1309 return true; 1310 } 1311 } 1312 1313 // If the first selector ends with NoCopy, assume that the ownership is 1314 // transfered as well. 1315 // Ex: [NSData dataWithBytesNoCopy:bytes length:10]; 1316 if (S.getNameForSlot(0).endswith("NoCopy")) { 1317 return false; 1318 } 1319 1320 // If the call has a callback as an argument, assume the memory 1321 // can be freed. 1322 if (Call->hasNonZeroCallbackArg()) 1323 return false; 1324 1325 // Otherwise, assume that the function does not free memory. 1326 // Most system calls, do not free the memory. 1327 return true; 1328 } 1329 1330 // Otherwise, assume that the function can free memory. 1331 return false; 1332 1333} 1334 1335// If the symbol we are tracking is invalidated, but not explicitly (ex: the &p 1336// escapes, when we are tracking p), do not track the symbol as we cannot reason 1337// about it anymore. 1338ProgramStateRef 1339MallocChecker::checkRegionChanges(ProgramStateRef State, 1340 const StoreManager::InvalidatedSymbols *invalidated, 1341 ArrayRef<const MemRegion *> ExplicitRegions, 1342 ArrayRef<const MemRegion *> Regions, 1343 const CallOrObjCMessage *Call) const { 1344 if (!invalidated || invalidated->empty()) 1345 return State; 1346 llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols; 1347 1348 // If it's a call which might free or reallocate memory, we assume that all 1349 // regions (explicit and implicit) escaped. 1350 1351 // Otherwise, whitelist explicit pointers; we still can track them. 1352 if (!Call || doesNotFreeMemory(Call, State)) { 1353 for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(), 1354 E = ExplicitRegions.end(); I != E; ++I) { 1355 if (const SymbolicRegion *R = (*I)->StripCasts()->getAs<SymbolicRegion>()) 1356 WhitelistedSymbols.insert(R->getSymbol()); 1357 } 1358 } 1359 1360 for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(), 1361 E = invalidated->end(); I!=E; ++I) { 1362 SymbolRef sym = *I; 1363 if (WhitelistedSymbols.count(sym)) 1364 continue; 1365 // The symbol escaped. 1366 if (const RefState *RS = State->get<RegionState>(sym)) 1367 State = State->set<RegionState>(sym, RefState::getEscaped(RS->getStmt())); 1368 } 1369 return State; 1370} 1371 1372static SymbolRef findFailedReallocSymbol(ProgramStateRef currState, 1373 ProgramStateRef prevState) { 1374 ReallocMap currMap = currState->get<ReallocPairs>(); 1375 ReallocMap prevMap = prevState->get<ReallocPairs>(); 1376 1377 for (ReallocMap::iterator I = prevMap.begin(), E = prevMap.end(); 1378 I != E; ++I) { 1379 SymbolRef sym = I.getKey(); 1380 if (!currMap.lookup(sym)) 1381 return sym; 1382 } 1383 1384 return NULL; 1385} 1386 1387PathDiagnosticPiece * 1388MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N, 1389 const ExplodedNode *PrevN, 1390 BugReporterContext &BRC, 1391 BugReport &BR) { 1392 ProgramStateRef state = N->getState(); 1393 ProgramStateRef statePrev = PrevN->getState(); 1394 1395 const RefState *RS = state->get<RegionState>(Sym); 1396 const RefState *RSPrev = statePrev->get<RegionState>(Sym); 1397 if (!RS && !RSPrev) 1398 return 0; 1399 1400 const Stmt *S = 0; 1401 const char *Msg = 0; 1402 StackHintGeneratorForSymbol *StackHint = 0; 1403 1404 // Retrieve the associated statement. 1405 ProgramPoint ProgLoc = N->getLocation(); 1406 if (isa<StmtPoint>(ProgLoc)) 1407 S = cast<StmtPoint>(ProgLoc).getStmt(); 1408 // If an assumption was made on a branch, it should be caught 1409 // here by looking at the state transition. 1410 if (isa<BlockEdge>(ProgLoc)) { 1411 const CFGBlock *srcBlk = cast<BlockEdge>(ProgLoc).getSrc(); 1412 S = srcBlk->getTerminator(); 1413 } 1414 if (!S) 1415 return 0; 1416 1417 // Find out if this is an interesting point and what is the kind. 1418 if (Mode == Normal) { 1419 if (isAllocated(RS, RSPrev, S)) { 1420 Msg = "Memory is allocated"; 1421 StackHint = new StackHintGeneratorForSymbol(Sym, 1422 "Returned allocated memory"); 1423 } else if (isReleased(RS, RSPrev, S)) { 1424 Msg = "Memory is released"; 1425 StackHint = new StackHintGeneratorForSymbol(Sym, 1426 "Returned released memory"); 1427 } else if (isReallocFailedCheck(RS, RSPrev, S)) { 1428 Mode = ReallocationFailed; 1429 Msg = "Reallocation failed"; 1430 StackHint = new StackHintGeneratorForReallocationFailed(Sym, 1431 "Reallocation failed"); 1432 1433 if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) { 1434 // Is it possible to fail two reallocs WITHOUT testing in between? 1435 assert((!FailedReallocSymbol || FailedReallocSymbol == sym) && 1436 "We only support one failed realloc at a time."); 1437 BR.markInteresting(sym); 1438 FailedReallocSymbol = sym; 1439 } 1440 } 1441 1442 // We are in a special mode if a reallocation failed later in the path. 1443 } else if (Mode == ReallocationFailed) { 1444 assert(FailedReallocSymbol && "No symbol to look for."); 1445 1446 // Is this is the first appearance of the reallocated symbol? 1447 if (!statePrev->get<RegionState>(FailedReallocSymbol)) { 1448 // If we ever hit this assert, that means BugReporter has decided to skip 1449 // node pairs or visit them out of order. 1450 assert(state->get<RegionState>(FailedReallocSymbol) && 1451 "Missed the reallocation point"); 1452 1453 // We're at the reallocation point. 1454 Msg = "Attempt to reallocate memory"; 1455 StackHint = new StackHintGeneratorForSymbol(Sym, 1456 "Returned reallocated memory"); 1457 FailedReallocSymbol = NULL; 1458 Mode = Normal; 1459 } 1460 } 1461 1462 if (!Msg) 1463 return 0; 1464 assert(StackHint); 1465 1466 // Generate the extra diagnostic. 1467 PathDiagnosticLocation Pos(S, BRC.getSourceManager(), 1468 N->getLocationContext()); 1469 return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint); 1470} 1471 1472void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State, 1473 const char *NL, const char *Sep) const { 1474 1475 RegionStateTy RS = State->get<RegionState>(); 1476 1477 if (!RS.isEmpty()) 1478 Out << "Has Malloc data" << NL; 1479} 1480 1481#define REGISTER_CHECKER(name) \ 1482void ento::register##name(CheckerManager &mgr) {\ 1483 registerCStringCheckerBasic(mgr); \ 1484 mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\ 1485} 1486 1487REGISTER_CHECKER(MallocPessimistic) 1488REGISTER_CHECKER(MallocOptimistic) 1489