clang API Documentation

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