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