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 "clang/StaticAnalyzer/Core/Checker.h" 17 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 18 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 19 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 20 #include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" 21 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 22 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" 23 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 24 #include "clang/Basic/SourceManager.h" 25 #include "llvm/ADT/ImmutableMap.h" 26 #include "llvm/ADT/SmallString.h" 27 #include "llvm/ADT/STLExtras.h" 28 using namespace clang; 29 using namespace ento; 30 31 namespace { 32 33 class RefState { 34 enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped, 35 Relinquished } K; 36 const Stmt *S; 37 38 public: 39 RefState(Kind k, const Stmt *s) : K(k), S(s) {} 40 41 bool isAllocated() const { return K == AllocateUnchecked; } 42 //bool isFailed() const { return K == AllocateFailed; } 43 bool isReleased() const { return K == Released; } 44 //bool isEscaped() const { return K == Escaped; } 45 //bool isRelinquished() const { return K == Relinquished; } 46 const Stmt *getStmt() const { return S; } 47 48 bool operator==(const RefState &X) const { 49 return K == X.K && S == X.S; 50 } 51 52 static RefState getAllocateUnchecked(const Stmt *s) { 53 return RefState(AllocateUnchecked, s); 54 } 55 static RefState getAllocateFailed() { 56 return RefState(AllocateFailed, 0); 57 } 58 static RefState getReleased(const Stmt *s) { return RefState(Released, s); } 59 static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); } 60 static RefState getRelinquished(const Stmt *s) { 61 return RefState(Relinquished, s); 62 } 63 64 void Profile(llvm::FoldingSetNodeID &ID) const { 65 ID.AddInteger(K); 66 ID.AddPointer(S); 67 } 68 }; 69 70 class MallocChecker : public Checker<check::DeadSymbols, 71 check::EndPath, 72 check::PreStmt<ReturnStmt>, 73 check::PreStmt<CallExpr>, 74 check::PostStmt<CallExpr>, 75 check::Location, 76 check::Bind, 77 eval::Assume, 78 check::RegionChanges> 79 { 80 mutable OwningPtr<BuiltinBug> BT_DoubleFree; 81 mutable OwningPtr<BuiltinBug> BT_Leak; 82 mutable OwningPtr<BuiltinBug> BT_UseFree; 83 mutable OwningPtr<BuiltinBug> BT_UseRelinquished; 84 mutable OwningPtr<BuiltinBug> BT_BadFree; 85 mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc; 86 87 public: 88 MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {} 89 90 /// In pessimistic mode, the checker assumes that it does not know which 91 /// functions might free the memory. 92 struct ChecksFilter { 93 DefaultBool CMallocPessimistic; 94 DefaultBool CMallocOptimistic; 95 }; 96 97 ChecksFilter Filter; 98 99 void checkPreStmt(const CallExpr *S, CheckerContext &C) const; 100 void checkPostStmt(const CallExpr *CE, CheckerContext &C) const; 101 void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; 102 void checkEndPath(CheckerContext &C) const; 103 void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const; 104 ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond, 105 bool Assumption) const; 106 void checkLocation(SVal l, bool isLoad, const Stmt *S, 107 CheckerContext &C) const; 108 void checkBind(SVal location, SVal val, const Stmt*S, 109 CheckerContext &C) const; 110 ProgramStateRef 111 checkRegionChanges(ProgramStateRef state, 112 const StoreManager::InvalidatedSymbols *invalidated, 113 ArrayRef<const MemRegion *> ExplicitRegions, 114 ArrayRef<const MemRegion *> Regions, 115 const CallOrObjCMessage *Call) const; 116 bool wantsRegionChangeUpdate(ProgramStateRef state) const { 117 return true; 118 } 119 120 private: 121 void initIdentifierInfo(ASTContext &C) const; 122 123 /// Check if this is one of the functions which can allocate/reallocate memory 124 /// pointed to by one of its arguments. 125 bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const; 126 127 static void MallocMem(CheckerContext &C, const CallExpr *CE); 128 static void MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, 129 const OwnershipAttr* Att); 130 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, 131 const Expr *SizeEx, SVal Init, 132 ProgramStateRef state) { 133 return MallocMemAux(C, CE, 134 state->getSVal(SizeEx, C.getLocationContext()), 135 Init, state); 136 } 137 static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE, 138 SVal SizeEx, SVal Init, 139 ProgramStateRef state); 140 141 void FreeMem(CheckerContext &C, const CallExpr *CE) const; 142 void FreeMemAttr(CheckerContext &C, const CallExpr *CE, 143 const OwnershipAttr* Att) const; 144 ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE, 145 ProgramStateRef state, unsigned Num, 146 bool Hold) const; 147 148 void ReallocMem(CheckerContext &C, const CallExpr *CE) const; 149 static void CallocMem(CheckerContext &C, const CallExpr *CE); 150 151 bool checkEscape(SymbolRef Sym, const Stmt *S, CheckerContext &C) const; 152 bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, 153 const Stmt *S = 0) const; 154 155 /// Check if the function is not known to us. So, for example, we could 156 /// conservatively assume it can free/reallocate it's pointer arguments. 157 bool hasUnknownBehavior(const FunctionDecl *FD, ProgramStateRef State) const; 158 159 static bool SummarizeValue(raw_ostream &os, SVal V); 160 static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR); 161 void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const; 162 163 void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const; 164 165 /// The bug visitor which allows us to print extra diagnostics along the 166 /// BugReport path. For example, showing the allocation site of the leaked 167 /// region. 168 class MallocBugVisitor : public BugReporterVisitor { 169 protected: 170 // The allocated region symbol tracked by the main analysis. 171 SymbolRef Sym; 172 173 public: 174 MallocBugVisitor(SymbolRef S) : Sym(S) {} 175 virtual ~MallocBugVisitor() {} 176 177 void Profile(llvm::FoldingSetNodeID &ID) const { 178 static int X = 0; 179 ID.AddPointer(&X); 180 ID.AddPointer(Sym); 181 } 182 183 inline bool isAllocated(const RefState *S, const RefState *SPrev) { 184 // Did not track -> allocated. Other state (released) -> allocated. 185 return ((S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated())); 186 } 187 188 inline bool isReleased(const RefState *S, const RefState *SPrev) { 189 // Did not track -> released. Other state (allocated) -> released. 190 return ((S && S->isReleased()) && (!SPrev || !SPrev->isReleased())); 191 } 192 193 PathDiagnosticPiece *VisitNode(const ExplodedNode *N, 194 const ExplodedNode *PrevN, 195 BugReporterContext &BRC, 196 BugReport &BR); 197 }; 198 }; 199 } // end anonymous namespace 200 201 typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy; 202 typedef llvm::ImmutableMap<SymbolRef, SymbolRef> SymRefToSymRefTy; 203 class RegionState {}; 204 class ReallocPairs {}; 205 namespace clang { 206 namespace ento { 207 template <> 208 struct ProgramStateTrait<RegionState> 209 : public ProgramStatePartialTrait<RegionStateTy> { 210 static void *GDMIndex() { static int x; return &x; } 211 }; 212 213 template <> 214 struct ProgramStateTrait<ReallocPairs> 215 : public ProgramStatePartialTrait<SymRefToSymRefTy> { 216 static void *GDMIndex() { static int x; return &x; } 217 }; 218 } 219 } 220 221 namespace { 222 class StopTrackingCallback : public SymbolVisitor { 223 ProgramStateRef state; 224 public: 225 StopTrackingCallback(ProgramStateRef st) : state(st) {} 226 ProgramStateRef getState() const { return state; } 227 228 bool VisitSymbol(SymbolRef sym) { 229 state = state->remove<RegionState>(sym); 230 return true; 231 } 232 }; 233 } // end anonymous namespace 234 235 void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const { 236 if (!II_malloc) 237 II_malloc = &Ctx.Idents.get("malloc"); 238 if (!II_free) 239 II_free = &Ctx.Idents.get("free"); 240 if (!II_realloc) 241 II_realloc = &Ctx.Idents.get("realloc"); 242 if (!II_calloc) 243 II_calloc = &Ctx.Idents.get("calloc"); 244 } 245 246 bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const { 247 initIdentifierInfo(C); 248 IdentifierInfo *FunI = FD->getIdentifier(); 249 if (!FunI) 250 return false; 251 252 // TODO: Add more here : ex: reallocf! 253 if (FunI == II_malloc || FunI == II_free || 254 FunI == II_realloc || FunI == II_calloc) 255 return true; 256 257 if (Filter.CMallocOptimistic && FD->hasAttrs() && 258 FD->specific_attr_begin<OwnershipAttr>() != 259 FD->specific_attr_end<OwnershipAttr>()) 260 return true; 261 262 263 return false; 264 } 265 266 void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const { 267 const FunctionDecl *FD = C.getCalleeDecl(CE); 268 if (!FD) 269 return; 270 initIdentifierInfo(C.getASTContext()); 271 272 if (FD->getIdentifier() == II_malloc) { 273 MallocMem(C, CE); 274 return; 275 } 276 if (FD->getIdentifier() == II_realloc) { 277 ReallocMem(C, CE); 278 return; 279 } 280 281 if (FD->getIdentifier() == II_calloc) { 282 CallocMem(C, CE); 283 return; 284 } 285 286 if (FD->getIdentifier() == II_free) { 287 FreeMem(C, CE); 288 return; 289 } 290 291 if (Filter.CMallocOptimistic) 292 // Check all the attributes, if there are any. 293 // There can be multiple of these attributes. 294 if (FD->hasAttrs()) { 295 for (specific_attr_iterator<OwnershipAttr> 296 i = FD->specific_attr_begin<OwnershipAttr>(), 297 e = FD->specific_attr_end<OwnershipAttr>(); 298 i != e; ++i) { 299 switch ((*i)->getOwnKind()) { 300 case OwnershipAttr::Returns: { 301 MallocMemReturnsAttr(C, CE, *i); 302 return; 303 } 304 case OwnershipAttr::Takes: 305 case OwnershipAttr::Holds: { 306 FreeMemAttr(C, CE, *i); 307 return; 308 } 309 } 310 } 311 } 312 } 313 314 void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) { 315 ProgramStateRef state = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), 316 C.getState()); 317 C.addTransition(state); 318 } 319 320 void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, 321 const OwnershipAttr* Att) { 322 if (Att->getModule() != "malloc") 323 return; 324 325 OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); 326 if (I != E) { 327 ProgramStateRef state = 328 MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState()); 329 C.addTransition(state); 330 return; 331 } 332 ProgramStateRef state = MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), 333 C.getState()); 334 C.addTransition(state); 335 } 336 337 ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C, 338 const CallExpr *CE, 339 SVal Size, SVal Init, 340 ProgramStateRef state) { 341 SValBuilder &svalBuilder = C.getSValBuilder(); 342 343 // Get the return value. 344 SVal retVal = state->getSVal(CE, C.getLocationContext()); 345 346 // Fill the region with the initialization value. 347 state = state->bindDefault(retVal, Init); 348 349 // Set the region's extent equal to the Size parameter. 350 const SymbolicRegion *R = 351 dyn_cast_or_null<SymbolicRegion>(retVal.getAsRegion()); 352 if (!R || !isa<DefinedOrUnknownSVal>(Size)) 353 return 0; 354 355 DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder); 356 DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size); 357 DefinedOrUnknownSVal extentMatchesSize = 358 svalBuilder.evalEQ(state, Extent, DefinedSize); 359 360 state = state->assume(extentMatchesSize, true); 361 assert(state); 362 363 SymbolRef Sym = retVal.getAsLocSymbol(); 364 assert(Sym); 365 366 // Set the symbol's state to Allocated. 367 return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE)); 368 } 369 370 void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) const { 371 ProgramStateRef state = FreeMemAux(C, CE, C.getState(), 0, false); 372 373 if (state) 374 C.addTransition(state); 375 } 376 377 void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE, 378 const OwnershipAttr* Att) const { 379 if (Att->getModule() != "malloc") 380 return; 381 382 for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); 383 I != E; ++I) { 384 ProgramStateRef state = 385 FreeMemAux(C, CE, C.getState(), *I, 386 Att->getOwnKind() == OwnershipAttr::Holds); 387 if (state) 388 C.addTransition(state); 389 } 390 } 391 392 ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C, 393 const CallExpr *CE, 394 ProgramStateRef state, 395 unsigned Num, 396 bool Hold) const { 397 const Expr *ArgExpr = CE->getArg(Num); 398 SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext()); 399 if (!isa<DefinedOrUnknownSVal>(ArgVal)) 400 return 0; 401 DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal); 402 403 // Check for null dereferences. 404 if (!isa<Loc>(location)) 405 return 0; 406 407 // The explicit NULL case, no operation is performed. 408 ProgramStateRef notNullState, nullState; 409 llvm::tie(notNullState, nullState) = state->assume(location); 410 if (nullState && !notNullState) 411 return 0; 412 413 // Unknown values could easily be okay 414 // Undefined values are handled elsewhere 415 if (ArgVal.isUnknownOrUndef()) 416 return 0; 417 418 const MemRegion *R = ArgVal.getAsRegion(); 419 420 // Nonlocs can't be freed, of course. 421 // Non-region locations (labels and fixed addresses) also shouldn't be freed. 422 if (!R) { 423 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange()); 424 return 0; 425 } 426 427 R = R->StripCasts(); 428 429 // Blocks might show up as heap data, but should not be free()d 430 if (isa<BlockDataRegion>(R)) { 431 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange()); 432 return 0; 433 } 434 435 const MemSpaceRegion *MS = R->getMemorySpace(); 436 437 // Parameters, locals, statics, and globals shouldn't be freed. 438 if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) { 439 // FIXME: at the time this code was written, malloc() regions were 440 // represented by conjured symbols, which are all in UnknownSpaceRegion. 441 // This means that there isn't actually anything from HeapSpaceRegion 442 // that should be freed, even though we allow it here. 443 // Of course, free() can work on memory allocated outside the current 444 // function, so UnknownSpaceRegion is always a possibility. 445 // False negatives are better than false positives. 446 447 ReportBadFree(C, ArgVal, ArgExpr->getSourceRange()); 448 return 0; 449 } 450 451 const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R); 452 // Various cases could lead to non-symbol values here. 453 // For now, ignore them. 454 if (!SR) 455 return 0; 456 457 SymbolRef Sym = SR->getSymbol(); 458 const RefState *RS = state->get<RegionState>(Sym); 459 460 // If the symbol has not been tracked, return. This is possible when free() is 461 // called on a pointer that does not get its pointee directly from malloc(). 462 // Full support of this requires inter-procedural analysis. 463 if (!RS) 464 return 0; 465 466 // Check double free. 467 if (RS->isReleased()) { 468 if (ExplodedNode *N = C.generateSink()) { 469 if (!BT_DoubleFree) 470 BT_DoubleFree.reset( 471 new BuiltinBug("Double free", 472 "Try to free a memory block that has been released")); 473 BugReport *R = new BugReport(*BT_DoubleFree, 474 BT_DoubleFree->getDescription(), N); 475 R->addVisitor(new MallocBugVisitor(Sym)); 476 C.EmitReport(R); 477 } 478 return 0; 479 } 480 481 // Normal free. 482 if (Hold) 483 return state->set<RegionState>(Sym, RefState::getRelinquished(CE)); 484 return state->set<RegionState>(Sym, RefState::getReleased(CE)); 485 } 486 487 bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) { 488 if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V)) 489 os << "an integer (" << IntVal->getValue() << ")"; 490 else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V)) 491 os << "a constant address (" << ConstAddr->getValue() << ")"; 492 else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V)) 493 os << "the address of the label '" << Label->getLabel()->getName() << "'"; 494 else 495 return false; 496 497 return true; 498 } 499 500 bool MallocChecker::SummarizeRegion(raw_ostream &os, 501 const MemRegion *MR) { 502 switch (MR->getKind()) { 503 case MemRegion::FunctionTextRegionKind: { 504 const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl(); 505 if (FD) 506 os << "the address of the function '" << *FD << '\''; 507 else 508 os << "the address of a function"; 509 return true; 510 } 511 case MemRegion::BlockTextRegionKind: 512 os << "block text"; 513 return true; 514 case MemRegion::BlockDataRegionKind: 515 // FIXME: where the block came from? 516 os << "a block"; 517 return true; 518 default: { 519 const MemSpaceRegion *MS = MR->getMemorySpace(); 520 521 if (isa<StackLocalsSpaceRegion>(MS)) { 522 const VarRegion *VR = dyn_cast<VarRegion>(MR); 523 const VarDecl *VD; 524 if (VR) 525 VD = VR->getDecl(); 526 else 527 VD = NULL; 528 529 if (VD) 530 os << "the address of the local variable '" << VD->getName() << "'"; 531 else 532 os << "the address of a local stack variable"; 533 return true; 534 } 535 536 if (isa<StackArgumentsSpaceRegion>(MS)) { 537 const VarRegion *VR = dyn_cast<VarRegion>(MR); 538 const VarDecl *VD; 539 if (VR) 540 VD = VR->getDecl(); 541 else 542 VD = NULL; 543 544 if (VD) 545 os << "the address of the parameter '" << VD->getName() << "'"; 546 else 547 os << "the address of a parameter"; 548 return true; 549 } 550 551 if (isa<GlobalsSpaceRegion>(MS)) { 552 const VarRegion *VR = dyn_cast<VarRegion>(MR); 553 const VarDecl *VD; 554 if (VR) 555 VD = VR->getDecl(); 556 else 557 VD = NULL; 558 559 if (VD) { 560 if (VD->isStaticLocal()) 561 os << "the address of the static variable '" << VD->getName() << "'"; 562 else 563 os << "the address of the global variable '" << VD->getName() << "'"; 564 } else 565 os << "the address of a global variable"; 566 return true; 567 } 568 569 return false; 570 } 571 } 572 } 573 574 void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal, 575 SourceRange range) const { 576 if (ExplodedNode *N = C.generateSink()) { 577 if (!BT_BadFree) 578 BT_BadFree.reset(new BuiltinBug("Bad free")); 579 580 SmallString<100> buf; 581 llvm::raw_svector_ostream os(buf); 582 583 const MemRegion *MR = ArgVal.getAsRegion(); 584 if (MR) { 585 while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR)) 586 MR = ER->getSuperRegion(); 587 588 // Special case for alloca() 589 if (isa<AllocaRegion>(MR)) 590 os << "Argument to free() was allocated by alloca(), not malloc()"; 591 else { 592 os << "Argument to free() is "; 593 if (SummarizeRegion(os, MR)) 594 os << ", which is not memory allocated by malloc()"; 595 else 596 os << "not memory allocated by malloc()"; 597 } 598 } else { 599 os << "Argument to free() is "; 600 if (SummarizeValue(os, ArgVal)) 601 os << ", which is not memory allocated by malloc()"; 602 else 603 os << "not memory allocated by malloc()"; 604 } 605 606 BugReport *R = new BugReport(*BT_BadFree, os.str(), N); 607 R->addRange(range); 608 C.EmitReport(R); 609 } 610 } 611 612 void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const { 613 ProgramStateRef state = C.getState(); 614 const Expr *arg0Expr = CE->getArg(0); 615 const LocationContext *LCtx = C.getLocationContext(); 616 SVal Arg0Val = state->getSVal(arg0Expr, LCtx); 617 if (!isa<DefinedOrUnknownSVal>(Arg0Val)) 618 return; 619 DefinedOrUnknownSVal arg0Val = cast<DefinedOrUnknownSVal>(Arg0Val); 620 621 SValBuilder &svalBuilder = C.getSValBuilder(); 622 623 DefinedOrUnknownSVal PtrEQ = 624 svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull()); 625 626 // Get the size argument. If there is no size arg then give up. 627 const Expr *Arg1 = CE->getArg(1); 628 if (!Arg1) 629 return; 630 631 // Get the value of the size argument. 632 SVal Arg1ValG = state->getSVal(Arg1, LCtx); 633 if (!isa<DefinedOrUnknownSVal>(Arg1ValG)) 634 return; 635 DefinedOrUnknownSVal Arg1Val = cast<DefinedOrUnknownSVal>(Arg1ValG); 636 637 // Compare the size argument to 0. 638 DefinedOrUnknownSVal SizeZero = 639 svalBuilder.evalEQ(state, Arg1Val, 640 svalBuilder.makeIntValWithPtrWidth(0, false)); 641 642 ProgramStateRef StatePtrIsNull, StatePtrNotNull; 643 llvm::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ); 644 ProgramStateRef StateSizeIsZero, StateSizeNotZero; 645 llvm::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero); 646 // We only assume exceptional states if they are definitely true; if the 647 // state is under-constrained, assume regular realloc behavior. 648 bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull; 649 bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero; 650 651 // If the ptr is NULL and the size is not 0, the call is equivalent to 652 // malloc(size). 653 if ( PrtIsNull && !SizeIsZero) { 654 ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1), 655 UndefinedVal(), StatePtrIsNull); 656 C.addTransition(stateMalloc); 657 return; 658 } 659 660 if (PrtIsNull && SizeIsZero) 661 return; 662 663 // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size). 664 assert(!PrtIsNull); 665 SymbolRef FromPtr = arg0Val.getAsSymbol(); 666 SVal RetVal = state->getSVal(CE, LCtx); 667 SymbolRef ToPtr = RetVal.getAsSymbol(); 668 if (!FromPtr || !ToPtr) 669 return; 670 671 // If the size is 0, free the memory. 672 if (SizeIsZero) 673 if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero,0,false)){ 674 // The semantics of the return value are: 675 // If size was equal to 0, either NULL or a pointer suitable to be passed 676 // to free() is returned. 677 stateFree = stateFree->set<ReallocPairs>(ToPtr, FromPtr); 678 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr); 679 C.addTransition(stateFree); 680 return; 681 } 682 683 // Default behavior. 684 if (ProgramStateRef stateFree = FreeMemAux(C, CE, state, 0, false)) { 685 // FIXME: We should copy the content of the original buffer. 686 ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1), 687 UnknownVal(), stateFree); 688 if (!stateRealloc) 689 return; 690 stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr, FromPtr); 691 C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr); 692 C.addTransition(stateRealloc); 693 return; 694 } 695 } 696 697 void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) { 698 ProgramStateRef state = C.getState(); 699 SValBuilder &svalBuilder = C.getSValBuilder(); 700 const LocationContext *LCtx = C.getLocationContext(); 701 SVal count = state->getSVal(CE->getArg(0), LCtx); 702 SVal elementSize = state->getSVal(CE->getArg(1), LCtx); 703 SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize, 704 svalBuilder.getContext().getSizeType()); 705 SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); 706 707 C.addTransition(MallocMemAux(C, CE, TotalSize, zeroVal, state)); 708 } 709 710 void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N, 711 CheckerContext &C) const { 712 assert(N); 713 if (!BT_Leak) { 714 BT_Leak.reset(new BuiltinBug("Memory leak", 715 "Allocated memory never released. Potential memory leak.")); 716 // Leaks should not be reported if they are post-dominated by a sink: 717 // (1) Sinks are higher importance bugs. 718 // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending 719 // with __noreturn functions such as assert() or exit(). We choose not 720 // to report leaks on such paths. 721 BT_Leak->setSuppressOnSink(true); 722 } 723 724 BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N); 725 R->addVisitor(new MallocBugVisitor(Sym)); 726 C.EmitReport(R); 727 } 728 729 void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper, 730 CheckerContext &C) const 731 { 732 if (!SymReaper.hasDeadSymbols()) 733 return; 734 735 ProgramStateRef state = C.getState(); 736 RegionStateTy RS = state->get<RegionState>(); 737 RegionStateTy::Factory &F = state->get_context<RegionState>(); 738 739 bool generateReport = false; 740 llvm::SmallVector<SymbolRef, 2> Errors; 741 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { 742 if (SymReaper.isDead(I->first)) { 743 if (I->second.isAllocated()) { 744 generateReport = true; 745 Errors.push_back(I->first); 746 } 747 // Remove the dead symbol from the map. 748 RS = F.remove(RS, I->first); 749 750 } 751 } 752 753 // Cleanup the Realloc Pairs Map. 754 SymRefToSymRefTy RP = state->get<ReallocPairs>(); 755 for (SymRefToSymRefTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) { 756 if (SymReaper.isDead(I->first) || SymReaper.isDead(I->second)) { 757 state = state->remove<ReallocPairs>(I->first); 758 } 759 } 760 761 ExplodedNode *N = C.addTransition(state->set<RegionState>(RS)); 762 763 if (N && generateReport) { 764 for (llvm::SmallVector<SymbolRef, 2>::iterator 765 I = Errors.begin(), E = Errors.end(); I != E; ++I) { 766 reportLeak(*I, N, C); 767 } 768 } 769 } 770 771 void MallocChecker::checkEndPath(CheckerContext &C) const { 772 ProgramStateRef state = C.getState(); 773 RegionStateTy M = state->get<RegionState>(); 774 775 for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) { 776 RefState RS = I->second; 777 if (RS.isAllocated()) { 778 ExplodedNode *N = C.addTransition(state); 779 if (N) 780 reportLeak(I->first, N, C); 781 } 782 } 783 } 784 785 bool MallocChecker::checkEscape(SymbolRef Sym, const Stmt *S, 786 CheckerContext &C) const { 787 ProgramStateRef state = C.getState(); 788 const RefState *RS = state->get<RegionState>(Sym); 789 if (!RS) 790 return false; 791 792 if (RS->isAllocated()) { 793 state = state->set<RegionState>(Sym, RefState::getEscaped(S)); 794 C.addTransition(state); 795 return true; 796 } 797 return false; 798 } 799 800 void MallocChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const { 801 if (isMemFunction(C.getCalleeDecl(CE), C.getASTContext())) 802 return; 803 804 // Check use after free, when a freed pointer is passed to a call. 805 ProgramStateRef State = C.getState(); 806 for (CallExpr::const_arg_iterator I = CE->arg_begin(), 807 E = CE->arg_end(); I != E; ++I) { 808 const Expr *A = *I; 809 if (A->getType().getTypePtr()->isAnyPointerType()) { 810 SymbolRef Sym = State->getSVal(A, C.getLocationContext()).getAsSymbol(); 811 if (!Sym) 812 continue; 813 if (checkUseAfterFree(Sym, C, A)) 814 return; 815 } 816 } 817 } 818 819 void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const { 820 const Expr *E = S->getRetValue(); 821 if (!E) 822 return; 823 824 // Check if we are returning a symbol. 825 SymbolRef Sym = C.getState()->getSVal(E, C.getLocationContext()).getAsSymbol(); 826 if (!Sym) 827 return; 828 829 // Check if we are returning freed memory. 830 if (checkUseAfterFree(Sym, C, S)) 831 return; 832 833 // Check if the symbol is escaping. 834 checkEscape(Sym, S, C); 835 } 836 837 bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C, 838 const Stmt *S) const { 839 assert(Sym); 840 const RefState *RS = C.getState()->get<RegionState>(Sym); 841 if (RS && RS->isReleased()) { 842 if (ExplodedNode *N = C.generateSink()) { 843 if (!BT_UseFree) 844 BT_UseFree.reset(new BuiltinBug("Use of dynamically allocated memory " 845 "after it is freed.")); 846 847 BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),N); 848 if (S) 849 R->addRange(S->getSourceRange()); 850 R->addVisitor(new MallocBugVisitor(Sym)); 851 C.EmitReport(R); 852 return true; 853 } 854 } 855 return false; 856 } 857 858 // Check if the location is a freed symbolic region. 859 void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S, 860 CheckerContext &C) const { 861 SymbolRef Sym = l.getLocSymbolInBase(); 862 if (Sym) 863 checkUseAfterFree(Sym, C); 864 } 865 866 //===----------------------------------------------------------------------===// 867 // Check various ways a symbol can be invalidated. 868 // TODO: This logic (the next 3 functions) is copied/similar to the 869 // RetainRelease checker. We might want to factor this out. 870 //===----------------------------------------------------------------------===// 871 872 // Stop tracking symbols when a value escapes as a result of checkBind. 873 // A value escapes in three possible cases: 874 // (1) we are binding to something that is not a memory region. 875 // (2) we are binding to a memregion that does not have stack storage 876 // (3) we are binding to a memregion with stack storage that the store 877 // does not understand. 878 void MallocChecker::checkBind(SVal loc, SVal val, const Stmt *S, 879 CheckerContext &C) const { 880 // Are we storing to something that causes the value to "escape"? 881 bool escapes = true; 882 ProgramStateRef state = C.getState(); 883 884 if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) { 885 escapes = !regionLoc->getRegion()->hasStackStorage(); 886 887 if (!escapes) { 888 // To test (3), generate a new state with the binding added. If it is 889 // the same state, then it escapes (since the store cannot represent 890 // the binding). 891 escapes = (state == (state->bindLoc(*regionLoc, val))); 892 } 893 } 894 895 // If our store can represent the binding and we aren't storing to something 896 // that doesn't have local storage then just return and have the simulation 897 // state continue as is. 898 if (!escapes) 899 return; 900 901 // Otherwise, find all symbols referenced by 'val' that we are tracking 902 // and stop tracking them. 903 state = state->scanReachableSymbols<StopTrackingCallback>(val).getState(); 904 C.addTransition(state); 905 } 906 907 // If a symbolic region is assumed to NULL (or another constant), stop tracking 908 // it - assuming that allocation failed on this path. 909 ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state, 910 SVal Cond, 911 bool Assumption) const { 912 RegionStateTy RS = state->get<RegionState>(); 913 for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { 914 // If the symbol is assumed to NULL or another constant, this will 915 // return an APSInt*. 916 if (state->getSymVal(I.getKey())) 917 state = state->remove<RegionState>(I.getKey()); 918 } 919 920 // Realloc returns 0 when reallocation fails, which means that we should 921 // restore the state of the pointer being reallocated. 922 SymRefToSymRefTy RP = state->get<ReallocPairs>(); 923 for (SymRefToSymRefTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) { 924 // If the symbol is assumed to NULL or another constant, this will 925 // return an APSInt*. 926 if (state->getSymVal(I.getKey())) { 927 const RefState *RS = state->get<RegionState>(I.getData()); 928 if (RS) { 929 if (RS->isReleased()) 930 state = state->set<RegionState>(I.getData(), 931 RefState::getAllocateUnchecked(RS->getStmt())); 932 else if (RS->isAllocated()) 933 state = state->set<RegionState>(I.getData(), 934 RefState::getReleased(RS->getStmt())); 935 } 936 state = state->remove<ReallocPairs>(I.getKey()); 937 } 938 } 939 940 return state; 941 } 942 943 // Check if the function is not known to us. So, for example, we could 944 // conservatively assume it can free/reallocate it's pointer arguments. 945 // (We assume that the pointers cannot escape through calls to system 946 // functions not handled by this checker.) 947 bool MallocChecker::hasUnknownBehavior(const FunctionDecl *FD, 948 ProgramStateRef State) const { 949 ASTContext &ASTC = State->getStateManager().getContext(); 950 951 // If it's one of the allocation functions we can reason about, we model it's 952 // behavior explicitly. 953 if (isMemFunction(FD, ASTC)) { 954 return false; 955 } 956 957 // If it's a system call, we know it does not free the memory. 958 SourceManager &SM = ASTC.getSourceManager(); 959 if (SM.isInSystemHeader(FD->getLocation())) { 960 return false; 961 } 962 963 // Otherwise, assume that the function can free memory. 964 return true; 965 } 966 967 // If the symbol we are tracking is invalidated, but not explicitly (ex: the &p 968 // escapes, when we are tracking p), do not track the symbol as we cannot reason 969 // about it anymore. 970 ProgramStateRef 971 MallocChecker::checkRegionChanges(ProgramStateRef State, 972 const StoreManager::InvalidatedSymbols *invalidated, 973 ArrayRef<const MemRegion *> ExplicitRegions, 974 ArrayRef<const MemRegion *> Regions, 975 const CallOrObjCMessage *Call) const { 976 if (!invalidated) 977 return State; 978 llvm::SmallPtrSet<SymbolRef, 8> WhitelistedSymbols; 979 980 const FunctionDecl *FD = (Call ? dyn_cast<FunctionDecl>(Call->getDecl()) : 0); 981 982 // If it's a call which might free or reallocate memory, we assume that all 983 // regions (explicit and implicit) escaped. Otherwise, whitelist explicit 984 // pointers; we still can track them. 985 if (!(FD && hasUnknownBehavior(FD, State))) { 986 for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(), 987 E = ExplicitRegions.end(); I != E; ++I) { 988 if (const SymbolicRegion *R = (*I)->StripCasts()->getAs<SymbolicRegion>()) 989 WhitelistedSymbols.insert(R->getSymbol()); 990 } 991 } 992 993 for (StoreManager::InvalidatedSymbols::const_iterator I=invalidated->begin(), 994 E = invalidated->end(); I!=E; ++I) { 995 SymbolRef sym = *I; 996 if (WhitelistedSymbols.count(sym)) 997 continue; 998 // The symbol escaped. 999 if (const RefState *RS = State->get<RegionState>(sym)) 1000 State = State->set<RegionState>(sym, RefState::getEscaped(RS->getStmt())); 1001 } 1002 return State; 1003 } 1004 1005 PathDiagnosticPiece * 1006 MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N, 1007 const ExplodedNode *PrevN, 1008 BugReporterContext &BRC, 1009 BugReport &BR) { 1010 const RefState *RS = N->getState()->get<RegionState>(Sym); 1011 const RefState *RSPrev = PrevN->getState()->get<RegionState>(Sym); 1012 if (!RS && !RSPrev) 1013 return 0; 1014 1015 // We expect the interesting locations be StmtPoints corresponding to call 1016 // expressions. We do not support indirect function calls as of now. 1017 const CallExpr *CE = 0; 1018 if (isa<StmtPoint>(N->getLocation())) 1019 CE = dyn_cast<CallExpr>(cast<StmtPoint>(N->getLocation()).getStmt()); 1020 if (!CE) 1021 return 0; 1022 const FunctionDecl *funDecl = CE->getDirectCallee(); 1023 if (!funDecl) 1024 return 0; 1025 1026 // Find out if this is an interesting point and what is the kind. 1027 const char *Msg = 0; 1028 if (isAllocated(RS, RSPrev)) 1029 Msg = "Memory is allocated here"; 1030 else if (isReleased(RS, RSPrev)) 1031 Msg = "Memory is released here"; 1032 if (!Msg) 1033 return 0; 1034 1035 // Generate the extra diagnostic. 1036 PathDiagnosticLocation Pos(CE, BRC.getSourceManager(), 1037 N->getLocationContext()); 1038 return new PathDiagnosticEventPiece(Pos, Msg); 1039 } 1040 1041 1042 #define REGISTER_CHECKER(name) \ 1043 void ento::register##name(CheckerManager &mgr) {\ 1044 mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\ 1045 } 1046 1047 REGISTER_CHECKER(MallocPessimistic) 1048 REGISTER_CHECKER(MallocOptimistic) 1049