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