1 //=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines malloc/free checker, which checks for potential memory
11 // leaks, double free, and use-after-free problems.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "ClangSACheckers.h"
16 #include "InterCheckerAPI.h"
17 #include "clang/AST/Attr.h"
18 #include "clang/AST/ParentMap.h"
19 #include "clang/Basic/SourceManager.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
22 #include "clang/StaticAnalyzer/Core/Checker.h"
23 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
24 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
25 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
26 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
27 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
28 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
29 #include "llvm/ADT/ImmutableMap.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/ADT/StringExtras.h"
33 #include <climits>
34 
35 using namespace clang;
36 using namespace ento;
37 
38 namespace {
39 
40 // Used to check correspondence between allocators and deallocators.
41 enum AllocationFamily {
42   AF_None,
43   AF_Malloc,
44   AF_CXXNew,
45   AF_CXXNewArray,
46   AF_IfNameIndex
47 };
48 
49 class RefState {
50   enum Kind { // Reference to allocated memory.
51               Allocated,
52               // Reference to released/freed memory.
53               Released,
54               // The responsibility for freeing resources has transferred from
55               // this reference. A relinquished symbol should not be freed.
56               Relinquished,
57               // We are no longer guaranteed to have observed all manipulations
58               // of this pointer/memory. For example, it could have been
59               // passed as a parameter to an opaque function.
60               Escaped
61   };
62 
63   const Stmt *S;
64   unsigned K : 2; // Kind enum, but stored as a bitfield.
65   unsigned Family : 30; // Rest of 32-bit word, currently just an allocation
66                         // family.
67 
RefState(Kind k,const Stmt * s,unsigned family)68   RefState(Kind k, const Stmt *s, unsigned family)
69     : S(s), K(k), Family(family) {
70     assert(family != AF_None);
71   }
72 public:
isAllocated() const73   bool isAllocated() const { return K == Allocated; }
isReleased() const74   bool isReleased() const { return K == Released; }
isRelinquished() const75   bool isRelinquished() const { return K == Relinquished; }
isEscaped() const76   bool isEscaped() const { return K == Escaped; }
getAllocationFamily() const77   AllocationFamily getAllocationFamily() const {
78     return (AllocationFamily)Family;
79   }
getStmt() const80   const Stmt *getStmt() const { return S; }
81 
operator ==(const RefState & X) const82   bool operator==(const RefState &X) const {
83     return K == X.K && S == X.S && Family == X.Family;
84   }
85 
getAllocated(unsigned family,const Stmt * s)86   static RefState getAllocated(unsigned family, const Stmt *s) {
87     return RefState(Allocated, s, family);
88   }
getReleased(unsigned family,const Stmt * s)89   static RefState getReleased(unsigned family, const Stmt *s) {
90     return RefState(Released, s, family);
91   }
getRelinquished(unsigned family,const Stmt * s)92   static RefState getRelinquished(unsigned family, const Stmt *s) {
93     return RefState(Relinquished, s, family);
94   }
getEscaped(const RefState * RS)95   static RefState getEscaped(const RefState *RS) {
96     return RefState(Escaped, RS->getStmt(), RS->getAllocationFamily());
97   }
98 
Profile(llvm::FoldingSetNodeID & ID) const99   void Profile(llvm::FoldingSetNodeID &ID) const {
100     ID.AddInteger(K);
101     ID.AddPointer(S);
102     ID.AddInteger(Family);
103   }
104 
dump(raw_ostream & OS) const105   void dump(raw_ostream &OS) const {
106     switch (static_cast<Kind>(K)) {
107 #define CASE(ID) case ID: OS << #ID; break;
108     CASE(Allocated)
109     CASE(Released)
110     CASE(Relinquished)
111     CASE(Escaped)
112     }
113   }
114 
dump() const115   LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
116 };
117 
118 enum ReallocPairKind {
119   RPToBeFreedAfterFailure,
120   // The symbol has been freed when reallocation failed.
121   RPIsFreeOnFailure,
122   // The symbol does not need to be freed after reallocation fails.
123   RPDoNotTrackAfterFailure
124 };
125 
126 /// \class ReallocPair
127 /// \brief Stores information about the symbol being reallocated by a call to
128 /// 'realloc' to allow modeling failed reallocation later in the path.
129 struct ReallocPair {
130   // \brief The symbol which realloc reallocated.
131   SymbolRef ReallocatedSym;
132   ReallocPairKind Kind;
133 
ReallocPair__anon34ae87c60111::ReallocPair134   ReallocPair(SymbolRef S, ReallocPairKind K) :
135     ReallocatedSym(S), Kind(K) {}
Profile__anon34ae87c60111::ReallocPair136   void Profile(llvm::FoldingSetNodeID &ID) const {
137     ID.AddInteger(Kind);
138     ID.AddPointer(ReallocatedSym);
139   }
operator ==__anon34ae87c60111::ReallocPair140   bool operator==(const ReallocPair &X) const {
141     return ReallocatedSym == X.ReallocatedSym &&
142            Kind == X.Kind;
143   }
144 };
145 
146 typedef std::pair<const ExplodedNode*, const MemRegion*> LeakInfo;
147 
148 class MallocChecker : public Checker<check::DeadSymbols,
149                                      check::PointerEscape,
150                                      check::ConstPointerEscape,
151                                      check::PreStmt<ReturnStmt>,
152                                      check::PreCall,
153                                      check::PostStmt<CallExpr>,
154                                      check::PostStmt<CXXNewExpr>,
155                                      check::PreStmt<CXXDeleteExpr>,
156                                      check::PostStmt<BlockExpr>,
157                                      check::PostObjCMessage,
158                                      check::Location,
159                                      eval::Assume>
160 {
161 public:
MallocChecker()162   MallocChecker()
163       : II_malloc(nullptr), II_free(nullptr), II_realloc(nullptr),
164         II_calloc(nullptr), II_valloc(nullptr), II_reallocf(nullptr),
165         II_strndup(nullptr), II_strdup(nullptr), II_kmalloc(nullptr),
166         II_if_nameindex(nullptr), II_if_freenameindex(nullptr) {}
167 
168   /// In pessimistic mode, the checker assumes that it does not know which
169   /// functions might free the memory.
170   enum CheckKind {
171     CK_MallocPessimistic,
172     CK_MallocOptimistic,
173     CK_NewDeleteChecker,
174     CK_NewDeleteLeaksChecker,
175     CK_MismatchedDeallocatorChecker,
176     CK_NumCheckKinds
177   };
178 
179   enum class MemoryOperationKind {
180     MOK_Allocate,
181     MOK_Free,
182     MOK_Any
183   };
184 
185   DefaultBool ChecksEnabled[CK_NumCheckKinds];
186   CheckName CheckNames[CK_NumCheckKinds];
187 
188   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
189   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
190   void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const;
191   void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
192   void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
193   void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
194   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
195   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
196   ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
197                             bool Assumption) const;
198   void checkLocation(SVal l, bool isLoad, const Stmt *S,
199                      CheckerContext &C) const;
200 
201   ProgramStateRef checkPointerEscape(ProgramStateRef State,
202                                     const InvalidatedSymbols &Escaped,
203                                     const CallEvent *Call,
204                                     PointerEscapeKind Kind) const;
205   ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
206                                           const InvalidatedSymbols &Escaped,
207                                           const CallEvent *Call,
208                                           PointerEscapeKind Kind) const;
209 
210   void printState(raw_ostream &Out, ProgramStateRef State,
211                   const char *NL, const char *Sep) const override;
212 
213 private:
214   mutable std::unique_ptr<BugType> BT_DoubleFree[CK_NumCheckKinds];
215   mutable std::unique_ptr<BugType> BT_DoubleDelete;
216   mutable std::unique_ptr<BugType> BT_Leak[CK_NumCheckKinds];
217   mutable std::unique_ptr<BugType> BT_UseFree[CK_NumCheckKinds];
218   mutable std::unique_ptr<BugType> BT_BadFree[CK_NumCheckKinds];
219   mutable std::unique_ptr<BugType> BT_MismatchedDealloc;
220   mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds];
221   mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc,
222                          *II_valloc, *II_reallocf, *II_strndup, *II_strdup,
223                          *II_kmalloc, *II_if_nameindex, *II_if_freenameindex;
224   mutable Optional<uint64_t> KernelZeroFlagVal;
225 
226   void initIdentifierInfo(ASTContext &C) const;
227 
228   /// \brief Determine family of a deallocation expression.
229   AllocationFamily getAllocationFamily(CheckerContext &C, const Stmt *S) const;
230 
231   /// \brief Print names of allocators and deallocators.
232   ///
233   /// \returns true on success.
234   bool printAllocDeallocName(raw_ostream &os, CheckerContext &C,
235                              const Expr *E) const;
236 
237   /// \brief Print expected name of an allocator based on the deallocator's
238   /// family derived from the DeallocExpr.
239   void printExpectedAllocName(raw_ostream &os, CheckerContext &C,
240                               const Expr *DeallocExpr) const;
241   /// \brief Print expected name of a deallocator based on the allocator's
242   /// family.
243   void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) const;
244 
245   ///@{
246   /// Check if this is one of the functions which can allocate/reallocate memory
247   /// pointed to by one of its arguments.
248   bool isMemFunction(const FunctionDecl *FD, ASTContext &C) const;
249   bool isCMemFunction(const FunctionDecl *FD,
250                       ASTContext &C,
251                       AllocationFamily Family,
252                       MemoryOperationKind MemKind) const;
253   bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const;
254   ///@}
255   ProgramStateRef MallocMemReturnsAttr(CheckerContext &C,
256                                        const CallExpr *CE,
257                                        const OwnershipAttr* Att) const;
MallocMemAux(CheckerContext & C,const CallExpr * CE,const Expr * SizeEx,SVal Init,ProgramStateRef State,AllocationFamily Family=AF_Malloc)258   static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
259                                      const Expr *SizeEx, SVal Init,
260                                      ProgramStateRef State,
261                                      AllocationFamily Family = AF_Malloc) {
262     return MallocMemAux(C, CE,
263                         State->getSVal(SizeEx, C.getLocationContext()),
264                         Init, State, Family);
265   }
266 
267   static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
268                                      SVal SizeEx, SVal Init,
269                                      ProgramStateRef State,
270                                      AllocationFamily Family = AF_Malloc);
271 
272   // Check if this malloc() for special flags. At present that means M_ZERO or
273   // __GFP_ZERO (in which case, treat it like calloc).
274   llvm::Optional<ProgramStateRef>
275   performKernelMalloc(const CallExpr *CE, CheckerContext &C,
276                       const ProgramStateRef &State) const;
277 
278   /// Update the RefState to reflect the new memory allocation.
279   static ProgramStateRef
280   MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State,
281                        AllocationFamily Family = AF_Malloc);
282 
283   ProgramStateRef FreeMemAttr(CheckerContext &C, const CallExpr *CE,
284                               const OwnershipAttr* Att) const;
285   ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
286                              ProgramStateRef state, unsigned Num,
287                              bool Hold,
288                              bool &ReleasedAllocated,
289                              bool ReturnsNullOnFailure = false) const;
290   ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *Arg,
291                              const Expr *ParentExpr,
292                              ProgramStateRef State,
293                              bool Hold,
294                              bool &ReleasedAllocated,
295                              bool ReturnsNullOnFailure = false) const;
296 
297   ProgramStateRef ReallocMem(CheckerContext &C, const CallExpr *CE,
298                              bool FreesMemOnFailure) const;
299   static ProgramStateRef CallocMem(CheckerContext &C, const CallExpr *CE);
300 
301   ///\brief Check if the memory associated with this symbol was released.
302   bool isReleased(SymbolRef Sym, CheckerContext &C) const;
303 
304   bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
305 
306   bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const;
307 
308   /// Check if the function is known free memory, or if it is
309   /// "interesting" and should be modeled explicitly.
310   ///
311   /// \param [out] EscapingSymbol A function might not free memory in general,
312   ///   but could be known to free a particular symbol. In this case, false is
313   ///   returned and the single escaping symbol is returned through the out
314   ///   parameter.
315   ///
316   /// We assume that pointers do not escape through calls to system functions
317   /// not handled by this checker.
318   bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call,
319                                    ProgramStateRef State,
320                                    SymbolRef &EscapingSymbol) const;
321 
322   // Implementation of the checkPointerEscape callabcks.
323   ProgramStateRef checkPointerEscapeAux(ProgramStateRef State,
324                                   const InvalidatedSymbols &Escaped,
325                                   const CallEvent *Call,
326                                   PointerEscapeKind Kind,
327                                   bool(*CheckRefState)(const RefState*)) const;
328 
329   ///@{
330   /// Tells if a given family/call/symbol is tracked by the current checker.
331   /// Sets CheckKind to the kind of the checker responsible for this
332   /// family/call/symbol.
333   Optional<CheckKind> getCheckIfTracked(AllocationFamily Family) const;
334   Optional<CheckKind> getCheckIfTracked(CheckerContext &C,
335                                         const Stmt *AllocDeallocStmt) const;
336   Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym) const;
337   ///@}
338   static bool SummarizeValue(raw_ostream &os, SVal V);
339   static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
340   void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
341                      const Expr *DeallocExpr) const;
342   void ReportMismatchedDealloc(CheckerContext &C, SourceRange Range,
343                                const Expr *DeallocExpr, const RefState *RS,
344                                SymbolRef Sym, bool OwnershipTransferred) const;
345   void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
346                         const Expr *DeallocExpr,
347                         const Expr *AllocExpr = nullptr) const;
348   void ReportUseAfterFree(CheckerContext &C, SourceRange Range,
349                           SymbolRef Sym) const;
350   void ReportDoubleFree(CheckerContext &C, SourceRange Range, bool Released,
351                         SymbolRef Sym, SymbolRef PrevSym) const;
352 
353   void ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const;
354 
355   /// Find the location of the allocation for Sym on the path leading to the
356   /// exploded node N.
357   LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
358                              CheckerContext &C) const;
359 
360   void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
361 
362   /// The bug visitor which allows us to print extra diagnostics along the
363   /// BugReport path. For example, showing the allocation site of the leaked
364   /// region.
365   class MallocBugVisitor : public BugReporterVisitorImpl<MallocBugVisitor> {
366   protected:
367     enum NotificationMode {
368       Normal,
369       ReallocationFailed
370     };
371 
372     // The allocated region symbol tracked by the main analysis.
373     SymbolRef Sym;
374 
375     // The mode we are in, i.e. what kind of diagnostics will be emitted.
376     NotificationMode Mode;
377 
378     // A symbol from when the primary region should have been reallocated.
379     SymbolRef FailedReallocSymbol;
380 
381     bool IsLeak;
382 
383   public:
MallocBugVisitor(SymbolRef S,bool isLeak=false)384     MallocBugVisitor(SymbolRef S, bool isLeak = false)
385        : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), IsLeak(isLeak) {}
386 
~MallocBugVisitor()387     virtual ~MallocBugVisitor() {}
388 
Profile(llvm::FoldingSetNodeID & ID) const389     void Profile(llvm::FoldingSetNodeID &ID) const override {
390       static int X = 0;
391       ID.AddPointer(&X);
392       ID.AddPointer(Sym);
393     }
394 
isAllocated(const RefState * S,const RefState * SPrev,const Stmt * Stmt)395     inline bool isAllocated(const RefState *S, const RefState *SPrev,
396                             const Stmt *Stmt) {
397       // Did not track -> allocated. Other state (released) -> allocated.
398       return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) &&
399               (S && S->isAllocated()) && (!SPrev || !SPrev->isAllocated()));
400     }
401 
isReleased(const RefState * S,const RefState * SPrev,const Stmt * Stmt)402     inline bool isReleased(const RefState *S, const RefState *SPrev,
403                            const Stmt *Stmt) {
404       // Did not track -> released. Other state (allocated) -> released.
405       return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt)) &&
406               (S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
407     }
408 
isRelinquished(const RefState * S,const RefState * SPrev,const Stmt * Stmt)409     inline bool isRelinquished(const RefState *S, const RefState *SPrev,
410                                const Stmt *Stmt) {
411       // Did not track -> relinquished. Other state (allocated) -> relinquished.
412       return (Stmt && (isa<CallExpr>(Stmt) || isa<ObjCMessageExpr>(Stmt) ||
413                                               isa<ObjCPropertyRefExpr>(Stmt)) &&
414               (S && S->isRelinquished()) &&
415               (!SPrev || !SPrev->isRelinquished()));
416     }
417 
isReallocFailedCheck(const RefState * S,const RefState * SPrev,const Stmt * Stmt)418     inline bool isReallocFailedCheck(const RefState *S, const RefState *SPrev,
419                                      const Stmt *Stmt) {
420       // If the expression is not a call, and the state change is
421       // released -> allocated, it must be the realloc return value
422       // check. If we have to handle more cases here, it might be cleaner just
423       // to track this extra bit in the state itself.
424       return ((!Stmt || !isa<CallExpr>(Stmt)) &&
425               (S && S->isAllocated()) && (SPrev && !SPrev->isAllocated()));
426     }
427 
428     PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
429                                    const ExplodedNode *PrevN,
430                                    BugReporterContext &BRC,
431                                    BugReport &BR) override;
432 
433     std::unique_ptr<PathDiagnosticPiece>
getEndPath(BugReporterContext & BRC,const ExplodedNode * EndPathNode,BugReport & BR)434     getEndPath(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
435                BugReport &BR) override {
436       if (!IsLeak)
437         return nullptr;
438 
439       PathDiagnosticLocation L =
440         PathDiagnosticLocation::createEndOfPath(EndPathNode,
441                                                 BRC.getSourceManager());
442       // Do not add the statement itself as a range in case of leak.
443       return llvm::make_unique<PathDiagnosticEventPiece>(L, BR.getDescription(),
444                                                          false);
445     }
446 
447   private:
448     class StackHintGeneratorForReallocationFailed
449         : public StackHintGeneratorForSymbol {
450     public:
StackHintGeneratorForReallocationFailed(SymbolRef S,StringRef M)451       StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
452         : StackHintGeneratorForSymbol(S, M) {}
453 
getMessageForArg(const Expr * ArgE,unsigned ArgIndex)454       std::string getMessageForArg(const Expr *ArgE,
455                                    unsigned ArgIndex) override {
456         // Printed parameters start at 1, not 0.
457         ++ArgIndex;
458 
459         SmallString<200> buf;
460         llvm::raw_svector_ostream os(buf);
461 
462         os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
463            << " parameter failed";
464 
465         return os.str();
466       }
467 
getMessageForReturn(const CallExpr * CallExpr)468       std::string getMessageForReturn(const CallExpr *CallExpr) override {
469         return "Reallocation of returned value failed";
470       }
471     };
472   };
473 };
474 } // end anonymous namespace
475 
476 REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
477 REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
478 
479 // A map from the freed symbol to the symbol representing the return value of
480 // the free function.
481 REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef)
482 
483 namespace {
484 class StopTrackingCallback : public SymbolVisitor {
485   ProgramStateRef state;
486 public:
StopTrackingCallback(ProgramStateRef st)487   StopTrackingCallback(ProgramStateRef st) : state(st) {}
getState() const488   ProgramStateRef getState() const { return state; }
489 
VisitSymbol(SymbolRef sym)490   bool VisitSymbol(SymbolRef sym) override {
491     state = state->remove<RegionState>(sym);
492     return true;
493   }
494 };
495 } // end anonymous namespace
496 
initIdentifierInfo(ASTContext & Ctx) const497 void MallocChecker::initIdentifierInfo(ASTContext &Ctx) const {
498   if (II_malloc)
499     return;
500   II_malloc = &Ctx.Idents.get("malloc");
501   II_free = &Ctx.Idents.get("free");
502   II_realloc = &Ctx.Idents.get("realloc");
503   II_reallocf = &Ctx.Idents.get("reallocf");
504   II_calloc = &Ctx.Idents.get("calloc");
505   II_valloc = &Ctx.Idents.get("valloc");
506   II_strdup = &Ctx.Idents.get("strdup");
507   II_strndup = &Ctx.Idents.get("strndup");
508   II_kmalloc = &Ctx.Idents.get("kmalloc");
509   II_if_nameindex = &Ctx.Idents.get("if_nameindex");
510   II_if_freenameindex = &Ctx.Idents.get("if_freenameindex");
511 }
512 
isMemFunction(const FunctionDecl * FD,ASTContext & C) const513 bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
514   if (isCMemFunction(FD, C, AF_Malloc, MemoryOperationKind::MOK_Any))
515     return true;
516 
517   if (isCMemFunction(FD, C, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
518     return true;
519 
520   if (isStandardNewDelete(FD, C))
521     return true;
522 
523   return false;
524 }
525 
isCMemFunction(const FunctionDecl * FD,ASTContext & C,AllocationFamily Family,MemoryOperationKind MemKind) const526 bool MallocChecker::isCMemFunction(const FunctionDecl *FD,
527                                    ASTContext &C,
528                                    AllocationFamily Family,
529                                    MemoryOperationKind MemKind) const {
530   if (!FD)
531     return false;
532 
533   bool CheckFree = (MemKind == MemoryOperationKind::MOK_Any ||
534                     MemKind == MemoryOperationKind::MOK_Free);
535   bool CheckAlloc = (MemKind == MemoryOperationKind::MOK_Any ||
536                      MemKind == MemoryOperationKind::MOK_Allocate);
537 
538   if (FD->getKind() == Decl::Function) {
539     const IdentifierInfo *FunI = FD->getIdentifier();
540     initIdentifierInfo(C);
541 
542     if (Family == AF_Malloc && CheckFree) {
543       if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf)
544         return true;
545     }
546 
547     if (Family == AF_Malloc && CheckAlloc) {
548       if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf ||
549           FunI == II_calloc || FunI == II_valloc || FunI == II_strdup ||
550           FunI == II_strndup || FunI == II_kmalloc)
551         return true;
552     }
553 
554     if (Family == AF_IfNameIndex && CheckFree) {
555       if (FunI == II_if_freenameindex)
556         return true;
557     }
558 
559     if (Family == AF_IfNameIndex && CheckAlloc) {
560       if (FunI == II_if_nameindex)
561         return true;
562     }
563   }
564 
565   if (Family != AF_Malloc)
566     return false;
567 
568   if (ChecksEnabled[CK_MallocOptimistic] && FD->hasAttrs()) {
569     for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
570       OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
571       if(OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds) {
572         if (CheckFree)
573           return true;
574       } else if (OwnKind == OwnershipAttr::Returns) {
575         if (CheckAlloc)
576           return true;
577       }
578     }
579   }
580 
581   return false;
582 }
583 
584 // Tells if the callee is one of the following:
585 // 1) A global non-placement new/delete operator function.
586 // 2) A global placement operator function with the single placement argument
587 //    of type std::nothrow_t.
isStandardNewDelete(const FunctionDecl * FD,ASTContext & C) const588 bool MallocChecker::isStandardNewDelete(const FunctionDecl *FD,
589                                         ASTContext &C) const {
590   if (!FD)
591     return false;
592 
593   OverloadedOperatorKind Kind = FD->getOverloadedOperator();
594   if (Kind != OO_New && Kind != OO_Array_New &&
595       Kind != OO_Delete && Kind != OO_Array_Delete)
596     return false;
597 
598   // Skip all operator new/delete methods.
599   if (isa<CXXMethodDecl>(FD))
600     return false;
601 
602   // Return true if tested operator is a standard placement nothrow operator.
603   if (FD->getNumParams() == 2) {
604     QualType T = FD->getParamDecl(1)->getType();
605     if (const IdentifierInfo *II = T.getBaseTypeIdentifier())
606       return II->getName().equals("nothrow_t");
607   }
608 
609   // Skip placement operators.
610   if (FD->getNumParams() != 1 || FD->isVariadic())
611     return false;
612 
613   // One of the standard new/new[]/delete/delete[] non-placement operators.
614   return true;
615 }
616 
performKernelMalloc(const CallExpr * CE,CheckerContext & C,const ProgramStateRef & State) const617 llvm::Optional<ProgramStateRef> MallocChecker::performKernelMalloc(
618   const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const {
619   // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels:
620   //
621   // void *malloc(unsigned long size, struct malloc_type *mtp, int flags);
622   //
623   // One of the possible flags is M_ZERO, which means 'give me back an
624   // allocation which is already zeroed', like calloc.
625 
626   // 2-argument kmalloc(), as used in the Linux kernel:
627   //
628   // void *kmalloc(size_t size, gfp_t flags);
629   //
630   // Has the similar flag value __GFP_ZERO.
631 
632   // This logic is largely cloned from O_CREAT in UnixAPIChecker, maybe some
633   // code could be shared.
634 
635   ASTContext &Ctx = C.getASTContext();
636   llvm::Triple::OSType OS = Ctx.getTargetInfo().getTriple().getOS();
637 
638   if (!KernelZeroFlagVal.hasValue()) {
639     if (OS == llvm::Triple::FreeBSD)
640       KernelZeroFlagVal = 0x0100;
641     else if (OS == llvm::Triple::NetBSD)
642       KernelZeroFlagVal = 0x0002;
643     else if (OS == llvm::Triple::OpenBSD)
644       KernelZeroFlagVal = 0x0008;
645     else if (OS == llvm::Triple::Linux)
646       // __GFP_ZERO
647       KernelZeroFlagVal = 0x8000;
648     else
649       // FIXME: We need a more general way of getting the M_ZERO value.
650       // See also: O_CREAT in UnixAPIChecker.cpp.
651 
652       // Fall back to normal malloc behavior on platforms where we don't
653       // know M_ZERO.
654       return None;
655   }
656 
657   // We treat the last argument as the flags argument, and callers fall-back to
658   // normal malloc on a None return. This works for the FreeBSD kernel malloc
659   // as well as Linux kmalloc.
660   if (CE->getNumArgs() < 2)
661     return None;
662 
663   const Expr *FlagsEx = CE->getArg(CE->getNumArgs() - 1);
664   const SVal V = State->getSVal(FlagsEx, C.getLocationContext());
665   if (!V.getAs<NonLoc>()) {
666     // The case where 'V' can be a location can only be due to a bad header,
667     // so in this case bail out.
668     return None;
669   }
670 
671   NonLoc Flags = V.castAs<NonLoc>();
672   NonLoc ZeroFlag = C.getSValBuilder()
673       .makeIntVal(KernelZeroFlagVal.getValue(), FlagsEx->getType())
674       .castAs<NonLoc>();
675   SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN(State, BO_And,
676                                                       Flags, ZeroFlag,
677                                                       FlagsEx->getType());
678   if (MaskedFlagsUC.isUnknownOrUndef())
679     return None;
680   DefinedSVal MaskedFlags = MaskedFlagsUC.castAs<DefinedSVal>();
681 
682   // Check if maskedFlags is non-zero.
683   ProgramStateRef TrueState, FalseState;
684   std::tie(TrueState, FalseState) = State->assume(MaskedFlags);
685 
686   // If M_ZERO is set, treat this like calloc (initialized).
687   if (TrueState && !FalseState) {
688     SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy);
689     return MallocMemAux(C, CE, CE->getArg(0), ZeroVal, TrueState);
690   }
691 
692   return None;
693 }
694 
checkPostStmt(const CallExpr * CE,CheckerContext & C) const695 void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
696   if (C.wasInlined)
697     return;
698 
699   const FunctionDecl *FD = C.getCalleeDecl(CE);
700   if (!FD)
701     return;
702 
703   ProgramStateRef State = C.getState();
704   bool ReleasedAllocatedMemory = false;
705 
706   if (FD->getKind() == Decl::Function) {
707     initIdentifierInfo(C.getASTContext());
708     IdentifierInfo *FunI = FD->getIdentifier();
709 
710     if (FunI == II_malloc) {
711       if (CE->getNumArgs() < 1)
712         return;
713       if (CE->getNumArgs() < 3) {
714         State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
715       } else if (CE->getNumArgs() == 3) {
716         llvm::Optional<ProgramStateRef> MaybeState =
717           performKernelMalloc(CE, C, State);
718         if (MaybeState.hasValue())
719           State = MaybeState.getValue();
720         else
721           State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
722       }
723     } else if (FunI == II_kmalloc) {
724       llvm::Optional<ProgramStateRef> MaybeState =
725         performKernelMalloc(CE, C, State);
726       if (MaybeState.hasValue())
727         State = MaybeState.getValue();
728       else
729         State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
730     } else if (FunI == II_valloc) {
731       if (CE->getNumArgs() < 1)
732         return;
733       State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
734     } else if (FunI == II_realloc) {
735       State = ReallocMem(C, CE, false);
736     } else if (FunI == II_reallocf) {
737       State = ReallocMem(C, CE, true);
738     } else if (FunI == II_calloc) {
739       State = CallocMem(C, CE);
740     } else if (FunI == II_free) {
741       State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
742     } else if (FunI == II_strdup) {
743       State = MallocUpdateRefState(C, CE, State);
744     } else if (FunI == II_strndup) {
745       State = MallocUpdateRefState(C, CE, State);
746     }
747     else if (isStandardNewDelete(FD, C.getASTContext())) {
748       // Process direct calls to operator new/new[]/delete/delete[] functions
749       // as distinct from new/new[]/delete/delete[] expressions that are
750       // processed by the checkPostStmt callbacks for CXXNewExpr and
751       // CXXDeleteExpr.
752       OverloadedOperatorKind K = FD->getOverloadedOperator();
753       if (K == OO_New)
754         State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
755                              AF_CXXNew);
756       else if (K == OO_Array_New)
757         State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State,
758                              AF_CXXNewArray);
759       else if (K == OO_Delete || K == OO_Array_Delete)
760         State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
761       else
762         llvm_unreachable("not a new/delete operator");
763     } else if (FunI == II_if_nameindex) {
764       // Should we model this differently? We can allocate a fixed number of
765       // elements with zeros in the last one.
766       State = MallocMemAux(C, CE, UnknownVal(), UnknownVal(), State,
767                            AF_IfNameIndex);
768     } else if (FunI == II_if_freenameindex) {
769       State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
770     }
771   }
772 
773   if (ChecksEnabled[CK_MallocOptimistic] ||
774       ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
775     // Check all the attributes, if there are any.
776     // There can be multiple of these attributes.
777     if (FD->hasAttrs())
778       for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
779         switch (I->getOwnKind()) {
780         case OwnershipAttr::Returns:
781           State = MallocMemReturnsAttr(C, CE, I);
782           break;
783         case OwnershipAttr::Takes:
784         case OwnershipAttr::Holds:
785           State = FreeMemAttr(C, CE, I);
786           break;
787         }
788       }
789   }
790   C.addTransition(State);
791 }
792 
getDeepPointeeType(QualType T)793 static QualType getDeepPointeeType(QualType T) {
794   QualType Result = T, PointeeType = T->getPointeeType();
795   while (!PointeeType.isNull()) {
796     Result = PointeeType;
797     PointeeType = PointeeType->getPointeeType();
798   }
799   return Result;
800 }
801 
treatUnusedNewEscaped(const CXXNewExpr * NE)802 static bool treatUnusedNewEscaped(const CXXNewExpr *NE) {
803 
804   const CXXConstructExpr *ConstructE = NE->getConstructExpr();
805   if (!ConstructE)
806     return false;
807 
808   if (!NE->getAllocatedType()->getAsCXXRecordDecl())
809     return false;
810 
811   const CXXConstructorDecl *CtorD = ConstructE->getConstructor();
812 
813   // Iterate over the constructor parameters.
814   for (const auto *CtorParam : CtorD->params()) {
815 
816     QualType CtorParamPointeeT = CtorParam->getType()->getPointeeType();
817     if (CtorParamPointeeT.isNull())
818       continue;
819 
820     CtorParamPointeeT = getDeepPointeeType(CtorParamPointeeT);
821 
822     if (CtorParamPointeeT->getAsCXXRecordDecl())
823       return true;
824   }
825 
826   return false;
827 }
828 
checkPostStmt(const CXXNewExpr * NE,CheckerContext & C) const829 void MallocChecker::checkPostStmt(const CXXNewExpr *NE,
830                                   CheckerContext &C) const {
831 
832   if (NE->getNumPlacementArgs())
833     for (CXXNewExpr::const_arg_iterator I = NE->placement_arg_begin(),
834          E = NE->placement_arg_end(); I != E; ++I)
835       if (SymbolRef Sym = C.getSVal(*I).getAsSymbol())
836         checkUseAfterFree(Sym, C, *I);
837 
838   if (!isStandardNewDelete(NE->getOperatorNew(), C.getASTContext()))
839     return;
840 
841   ParentMap &PM = C.getLocationContext()->getParentMap();
842   if (!PM.isConsumedExpr(NE) && treatUnusedNewEscaped(NE))
843     return;
844 
845   ProgramStateRef State = C.getState();
846   // The return value from operator new is bound to a specified initialization
847   // value (if any) and we don't want to loose this value. So we call
848   // MallocUpdateRefState() instead of MallocMemAux() which breakes the
849   // existing binding.
850   State = MallocUpdateRefState(C, NE, State, NE->isArray() ? AF_CXXNewArray
851                                                            : AF_CXXNew);
852   C.addTransition(State);
853 }
854 
checkPreStmt(const CXXDeleteExpr * DE,CheckerContext & C) const855 void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE,
856                                  CheckerContext &C) const {
857 
858   if (!ChecksEnabled[CK_NewDeleteChecker])
859     if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
860       checkUseAfterFree(Sym, C, DE->getArgument());
861 
862   if (!isStandardNewDelete(DE->getOperatorDelete(), C.getASTContext()))
863     return;
864 
865   ProgramStateRef State = C.getState();
866   bool ReleasedAllocated;
867   State = FreeMemAux(C, DE->getArgument(), DE, State,
868                      /*Hold*/false, ReleasedAllocated);
869 
870   C.addTransition(State);
871 }
872 
isKnownDeallocObjCMethodName(const ObjCMethodCall & Call)873 static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call) {
874   // If the first selector piece is one of the names below, assume that the
875   // object takes ownership of the memory, promising to eventually deallocate it
876   // with free().
877   // Ex:  [NSData dataWithBytesNoCopy:bytes length:10];
878   // (...unless a 'freeWhenDone' parameter is false, but that's checked later.)
879   StringRef FirstSlot = Call.getSelector().getNameForSlot(0);
880   if (FirstSlot == "dataWithBytesNoCopy" ||
881       FirstSlot == "initWithBytesNoCopy" ||
882       FirstSlot == "initWithCharactersNoCopy")
883     return true;
884 
885   return false;
886 }
887 
getFreeWhenDoneArg(const ObjCMethodCall & Call)888 static Optional<bool> getFreeWhenDoneArg(const ObjCMethodCall &Call) {
889   Selector S = Call.getSelector();
890 
891   // FIXME: We should not rely on fully-constrained symbols being folded.
892   for (unsigned i = 1; i < S.getNumArgs(); ++i)
893     if (S.getNameForSlot(i).equals("freeWhenDone"))
894       return !Call.getArgSVal(i).isZeroConstant();
895 
896   return None;
897 }
898 
checkPostObjCMessage(const ObjCMethodCall & Call,CheckerContext & C) const899 void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
900                                          CheckerContext &C) const {
901   if (C.wasInlined)
902     return;
903 
904   if (!isKnownDeallocObjCMethodName(Call))
905     return;
906 
907   if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(Call))
908     if (!*FreeWhenDone)
909       return;
910 
911   bool ReleasedAllocatedMemory;
912   ProgramStateRef State = FreeMemAux(C, Call.getArgExpr(0),
913                                      Call.getOriginExpr(), C.getState(),
914                                      /*Hold=*/true, ReleasedAllocatedMemory,
915                                      /*RetNullOnFailure=*/true);
916 
917   C.addTransition(State);
918 }
919 
920 ProgramStateRef
MallocMemReturnsAttr(CheckerContext & C,const CallExpr * CE,const OwnershipAttr * Att) const921 MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
922                                     const OwnershipAttr *Att) const {
923   if (Att->getModule() != II_malloc)
924     return nullptr;
925 
926   OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
927   if (I != E) {
928     return MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
929   }
930   return MallocMemAux(C, CE, UnknownVal(), UndefinedVal(), C.getState());
931 }
932 
MallocMemAux(CheckerContext & C,const CallExpr * CE,SVal Size,SVal Init,ProgramStateRef State,AllocationFamily Family)933 ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
934                                            const CallExpr *CE,
935                                            SVal Size, SVal Init,
936                                            ProgramStateRef State,
937                                            AllocationFamily Family) {
938 
939   // We expect the malloc functions to return a pointer.
940   if (!Loc::isLocType(CE->getType()))
941     return nullptr;
942 
943   // Bind the return value to the symbolic value from the heap region.
944   // TODO: We could rewrite post visit to eval call; 'malloc' does not have
945   // side effects other than what we model here.
946   unsigned Count = C.blockCount();
947   SValBuilder &svalBuilder = C.getSValBuilder();
948   const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
949   DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
950       .castAs<DefinedSVal>();
951   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
952 
953   // Fill the region with the initialization value.
954   State = State->bindDefault(RetVal, Init);
955 
956   // Set the region's extent equal to the Size parameter.
957   const SymbolicRegion *R =
958       dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
959   if (!R)
960     return nullptr;
961   if (Optional<DefinedOrUnknownSVal> DefinedSize =
962           Size.getAs<DefinedOrUnknownSVal>()) {
963     SValBuilder &svalBuilder = C.getSValBuilder();
964     DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
965     DefinedOrUnknownSVal extentMatchesSize =
966         svalBuilder.evalEQ(State, Extent, *DefinedSize);
967 
968     State = State->assume(extentMatchesSize, true);
969     assert(State);
970   }
971 
972   return MallocUpdateRefState(C, CE, State, Family);
973 }
974 
MallocUpdateRefState(CheckerContext & C,const Expr * E,ProgramStateRef State,AllocationFamily Family)975 ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
976                                                     const Expr *E,
977                                                     ProgramStateRef State,
978                                                     AllocationFamily Family) {
979   // Get the return value.
980   SVal retVal = State->getSVal(E, C.getLocationContext());
981 
982   // We expect the malloc functions to return a pointer.
983   if (!retVal.getAs<Loc>())
984     return nullptr;
985 
986   SymbolRef Sym = retVal.getAsLocSymbol();
987   assert(Sym);
988 
989   // Set the symbol's state to Allocated.
990   return State->set<RegionState>(Sym, RefState::getAllocated(Family, E));
991 }
992 
FreeMemAttr(CheckerContext & C,const CallExpr * CE,const OwnershipAttr * Att) const993 ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
994                                            const CallExpr *CE,
995                                            const OwnershipAttr *Att) const {
996   if (Att->getModule() != II_malloc)
997     return nullptr;
998 
999   ProgramStateRef State = C.getState();
1000   bool ReleasedAllocated = false;
1001 
1002   for (const auto &Arg : Att->args()) {
1003     ProgramStateRef StateI = FreeMemAux(C, CE, State, Arg,
1004                                Att->getOwnKind() == OwnershipAttr::Holds,
1005                                ReleasedAllocated);
1006     if (StateI)
1007       State = StateI;
1008   }
1009   return State;
1010 }
1011 
FreeMemAux(CheckerContext & C,const CallExpr * CE,ProgramStateRef state,unsigned Num,bool Hold,bool & ReleasedAllocated,bool ReturnsNullOnFailure) const1012 ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
1013                                           const CallExpr *CE,
1014                                           ProgramStateRef state,
1015                                           unsigned Num,
1016                                           bool Hold,
1017                                           bool &ReleasedAllocated,
1018                                           bool ReturnsNullOnFailure) const {
1019   if (CE->getNumArgs() < (Num + 1))
1020     return nullptr;
1021 
1022   return FreeMemAux(C, CE->getArg(Num), CE, state, Hold,
1023                     ReleasedAllocated, ReturnsNullOnFailure);
1024 }
1025 
1026 /// Checks if the previous call to free on the given symbol failed - if free
1027 /// failed, returns true. Also, returns the corresponding return value symbol.
didPreviousFreeFail(ProgramStateRef State,SymbolRef Sym,SymbolRef & RetStatusSymbol)1028 static bool didPreviousFreeFail(ProgramStateRef State,
1029                                 SymbolRef Sym, SymbolRef &RetStatusSymbol) {
1030   const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
1031   if (Ret) {
1032     assert(*Ret && "We should not store the null return symbol");
1033     ConstraintManager &CMgr = State->getConstraintManager();
1034     ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret);
1035     RetStatusSymbol = *Ret;
1036     return FreeFailed.isConstrainedTrue();
1037   }
1038   return false;
1039 }
1040 
getAllocationFamily(CheckerContext & C,const Stmt * S) const1041 AllocationFamily MallocChecker::getAllocationFamily(CheckerContext &C,
1042                                                     const Stmt *S) const {
1043   if (!S)
1044     return AF_None;
1045 
1046   if (const CallExpr *CE = dyn_cast<CallExpr>(S)) {
1047     const FunctionDecl *FD = C.getCalleeDecl(CE);
1048 
1049     if (!FD)
1050       FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1051 
1052     ASTContext &Ctx = C.getASTContext();
1053 
1054     if (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Any))
1055       return AF_Malloc;
1056 
1057     if (isStandardNewDelete(FD, Ctx)) {
1058       OverloadedOperatorKind Kind = FD->getOverloadedOperator();
1059       if (Kind == OO_New || Kind == OO_Delete)
1060         return AF_CXXNew;
1061       else if (Kind == OO_Array_New || Kind == OO_Array_Delete)
1062         return AF_CXXNewArray;
1063     }
1064 
1065     if (isCMemFunction(FD, Ctx, AF_IfNameIndex, MemoryOperationKind::MOK_Any))
1066       return AF_IfNameIndex;
1067 
1068     return AF_None;
1069   }
1070 
1071   if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(S))
1072     return NE->isArray() ? AF_CXXNewArray : AF_CXXNew;
1073 
1074   if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(S))
1075     return DE->isArrayForm() ? AF_CXXNewArray : AF_CXXNew;
1076 
1077   if (isa<ObjCMessageExpr>(S))
1078     return AF_Malloc;
1079 
1080   return AF_None;
1081 }
1082 
printAllocDeallocName(raw_ostream & os,CheckerContext & C,const Expr * E) const1083 bool MallocChecker::printAllocDeallocName(raw_ostream &os, CheckerContext &C,
1084                                           const Expr *E) const {
1085   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1086     // FIXME: This doesn't handle indirect calls.
1087     const FunctionDecl *FD = CE->getDirectCallee();
1088     if (!FD)
1089       return false;
1090 
1091     os << *FD;
1092     if (!FD->isOverloadedOperator())
1093       os << "()";
1094     return true;
1095   }
1096 
1097   if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) {
1098     if (Msg->isInstanceMessage())
1099       os << "-";
1100     else
1101       os << "+";
1102     Msg->getSelector().print(os);
1103     return true;
1104   }
1105 
1106   if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
1107     os << "'"
1108        << getOperatorSpelling(NE->getOperatorNew()->getOverloadedOperator())
1109        << "'";
1110     return true;
1111   }
1112 
1113   if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(E)) {
1114     os << "'"
1115        << getOperatorSpelling(DE->getOperatorDelete()->getOverloadedOperator())
1116        << "'";
1117     return true;
1118   }
1119 
1120   return false;
1121 }
1122 
printExpectedAllocName(raw_ostream & os,CheckerContext & C,const Expr * E) const1123 void MallocChecker::printExpectedAllocName(raw_ostream &os, CheckerContext &C,
1124                                            const Expr *E) const {
1125   AllocationFamily Family = getAllocationFamily(C, E);
1126 
1127   switch(Family) {
1128     case AF_Malloc: os << "malloc()"; return;
1129     case AF_CXXNew: os << "'new'"; return;
1130     case AF_CXXNewArray: os << "'new[]'"; return;
1131     case AF_IfNameIndex: os << "'if_nameindex()'"; return;
1132     case AF_None: llvm_unreachable("not a deallocation expression");
1133   }
1134 }
1135 
printExpectedDeallocName(raw_ostream & os,AllocationFamily Family) const1136 void MallocChecker::printExpectedDeallocName(raw_ostream &os,
1137                                              AllocationFamily Family) const {
1138   switch(Family) {
1139     case AF_Malloc: os << "free()"; return;
1140     case AF_CXXNew: os << "'delete'"; return;
1141     case AF_CXXNewArray: os << "'delete[]'"; return;
1142     case AF_IfNameIndex: os << "'if_freenameindex()'"; return;
1143     case AF_None: llvm_unreachable("suspicious AF_None argument");
1144   }
1145 }
1146 
FreeMemAux(CheckerContext & C,const Expr * ArgExpr,const Expr * ParentExpr,ProgramStateRef State,bool Hold,bool & ReleasedAllocated,bool ReturnsNullOnFailure) const1147 ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
1148                                           const Expr *ArgExpr,
1149                                           const Expr *ParentExpr,
1150                                           ProgramStateRef State,
1151                                           bool Hold,
1152                                           bool &ReleasedAllocated,
1153                                           bool ReturnsNullOnFailure) const {
1154 
1155   SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext());
1156   if (!ArgVal.getAs<DefinedOrUnknownSVal>())
1157     return nullptr;
1158   DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
1159 
1160   // Check for null dereferences.
1161   if (!location.getAs<Loc>())
1162     return nullptr;
1163 
1164   // The explicit NULL case, no operation is performed.
1165   ProgramStateRef notNullState, nullState;
1166   std::tie(notNullState, nullState) = State->assume(location);
1167   if (nullState && !notNullState)
1168     return nullptr;
1169 
1170   // Unknown values could easily be okay
1171   // Undefined values are handled elsewhere
1172   if (ArgVal.isUnknownOrUndef())
1173     return nullptr;
1174 
1175   const MemRegion *R = ArgVal.getAsRegion();
1176 
1177   // Nonlocs can't be freed, of course.
1178   // Non-region locations (labels and fixed addresses) also shouldn't be freed.
1179   if (!R) {
1180     ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1181     return nullptr;
1182   }
1183 
1184   R = R->StripCasts();
1185 
1186   // Blocks might show up as heap data, but should not be free()d
1187   if (isa<BlockDataRegion>(R)) {
1188     ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1189     return nullptr;
1190   }
1191 
1192   const MemSpaceRegion *MS = R->getMemorySpace();
1193 
1194   // Parameters, locals, statics, globals, and memory returned by alloca()
1195   // shouldn't be freed.
1196   if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
1197     // FIXME: at the time this code was written, malloc() regions were
1198     // represented by conjured symbols, which are all in UnknownSpaceRegion.
1199     // This means that there isn't actually anything from HeapSpaceRegion
1200     // that should be freed, even though we allow it here.
1201     // Of course, free() can work on memory allocated outside the current
1202     // function, so UnknownSpaceRegion is always a possibility.
1203     // False negatives are better than false positives.
1204 
1205     ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
1206     return nullptr;
1207   }
1208 
1209   const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion());
1210   // Various cases could lead to non-symbol values here.
1211   // For now, ignore them.
1212   if (!SrBase)
1213     return nullptr;
1214 
1215   SymbolRef SymBase = SrBase->getSymbol();
1216   const RefState *RsBase = State->get<RegionState>(SymBase);
1217   SymbolRef PreviousRetStatusSymbol = nullptr;
1218 
1219   if (RsBase) {
1220 
1221     // Check for double free first.
1222     if ((RsBase->isReleased() || RsBase->isRelinquished()) &&
1223         !didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)) {
1224       ReportDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
1225                        SymBase, PreviousRetStatusSymbol);
1226       return nullptr;
1227 
1228     // If the pointer is allocated or escaped, but we are now trying to free it,
1229     // check that the call to free is proper.
1230     } else if (RsBase->isAllocated() || RsBase->isEscaped()) {
1231 
1232       // Check if an expected deallocation function matches the real one.
1233       bool DeallocMatchesAlloc =
1234         RsBase->getAllocationFamily() == getAllocationFamily(C, ParentExpr);
1235       if (!DeallocMatchesAlloc) {
1236         ReportMismatchedDealloc(C, ArgExpr->getSourceRange(),
1237                                 ParentExpr, RsBase, SymBase, Hold);
1238         return nullptr;
1239       }
1240 
1241       // Check if the memory location being freed is the actual location
1242       // allocated, or an offset.
1243       RegionOffset Offset = R->getAsOffset();
1244       if (Offset.isValid() &&
1245           !Offset.hasSymbolicOffset() &&
1246           Offset.getOffset() != 0) {
1247         const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
1248         ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1249                          AllocExpr);
1250         return nullptr;
1251       }
1252     }
1253   }
1254 
1255   ReleasedAllocated = (RsBase != nullptr) && RsBase->isAllocated();
1256 
1257   // Clean out the info on previous call to free return info.
1258   State = State->remove<FreeReturnValue>(SymBase);
1259 
1260   // Keep track of the return value. If it is NULL, we will know that free
1261   // failed.
1262   if (ReturnsNullOnFailure) {
1263     SVal RetVal = C.getSVal(ParentExpr);
1264     SymbolRef RetStatusSymbol = RetVal.getAsSymbol();
1265     if (RetStatusSymbol) {
1266       C.getSymbolManager().addSymbolDependency(SymBase, RetStatusSymbol);
1267       State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol);
1268     }
1269   }
1270 
1271   AllocationFamily Family = RsBase ? RsBase->getAllocationFamily()
1272                                    : getAllocationFamily(C, ParentExpr);
1273   // Normal free.
1274   if (Hold)
1275     return State->set<RegionState>(SymBase,
1276                                    RefState::getRelinquished(Family,
1277                                                              ParentExpr));
1278 
1279   return State->set<RegionState>(SymBase,
1280                                  RefState::getReleased(Family, ParentExpr));
1281 }
1282 
1283 Optional<MallocChecker::CheckKind>
getCheckIfTracked(AllocationFamily Family) const1284 MallocChecker::getCheckIfTracked(AllocationFamily Family) const {
1285   switch (Family) {
1286   case AF_Malloc:
1287   case AF_IfNameIndex: {
1288     if (ChecksEnabled[CK_MallocOptimistic]) {
1289       return CK_MallocOptimistic;
1290     } else if (ChecksEnabled[CK_MallocPessimistic]) {
1291       return CK_MallocPessimistic;
1292     }
1293     return Optional<MallocChecker::CheckKind>();
1294   }
1295   case AF_CXXNew:
1296   case AF_CXXNewArray: {
1297     if (ChecksEnabled[CK_NewDeleteChecker]) {
1298       return CK_NewDeleteChecker;
1299     }
1300     return Optional<MallocChecker::CheckKind>();
1301   }
1302   case AF_None: {
1303     llvm_unreachable("no family");
1304   }
1305   }
1306   llvm_unreachable("unhandled family");
1307 }
1308 
1309 Optional<MallocChecker::CheckKind>
getCheckIfTracked(CheckerContext & C,const Stmt * AllocDeallocStmt) const1310 MallocChecker::getCheckIfTracked(CheckerContext &C,
1311                                  const Stmt *AllocDeallocStmt) const {
1312   return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt));
1313 }
1314 
1315 Optional<MallocChecker::CheckKind>
getCheckIfTracked(CheckerContext & C,SymbolRef Sym) const1316 MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym) const {
1317 
1318   const RefState *RS = C.getState()->get<RegionState>(Sym);
1319   assert(RS);
1320   return getCheckIfTracked(RS->getAllocationFamily());
1321 }
1322 
SummarizeValue(raw_ostream & os,SVal V)1323 bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
1324   if (Optional<nonloc::ConcreteInt> IntVal = V.getAs<nonloc::ConcreteInt>())
1325     os << "an integer (" << IntVal->getValue() << ")";
1326   else if (Optional<loc::ConcreteInt> ConstAddr = V.getAs<loc::ConcreteInt>())
1327     os << "a constant address (" << ConstAddr->getValue() << ")";
1328   else if (Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
1329     os << "the address of the label '" << Label->getLabel()->getName() << "'";
1330   else
1331     return false;
1332 
1333   return true;
1334 }
1335 
SummarizeRegion(raw_ostream & os,const MemRegion * MR)1336 bool MallocChecker::SummarizeRegion(raw_ostream &os,
1337                                     const MemRegion *MR) {
1338   switch (MR->getKind()) {
1339   case MemRegion::FunctionTextRegionKind: {
1340     const NamedDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
1341     if (FD)
1342       os << "the address of the function '" << *FD << '\'';
1343     else
1344       os << "the address of a function";
1345     return true;
1346   }
1347   case MemRegion::BlockTextRegionKind:
1348     os << "block text";
1349     return true;
1350   case MemRegion::BlockDataRegionKind:
1351     // FIXME: where the block came from?
1352     os << "a block";
1353     return true;
1354   default: {
1355     const MemSpaceRegion *MS = MR->getMemorySpace();
1356 
1357     if (isa<StackLocalsSpaceRegion>(MS)) {
1358       const VarRegion *VR = dyn_cast<VarRegion>(MR);
1359       const VarDecl *VD;
1360       if (VR)
1361         VD = VR->getDecl();
1362       else
1363         VD = nullptr;
1364 
1365       if (VD)
1366         os << "the address of the local variable '" << VD->getName() << "'";
1367       else
1368         os << "the address of a local stack variable";
1369       return true;
1370     }
1371 
1372     if (isa<StackArgumentsSpaceRegion>(MS)) {
1373       const VarRegion *VR = dyn_cast<VarRegion>(MR);
1374       const VarDecl *VD;
1375       if (VR)
1376         VD = VR->getDecl();
1377       else
1378         VD = nullptr;
1379 
1380       if (VD)
1381         os << "the address of the parameter '" << VD->getName() << "'";
1382       else
1383         os << "the address of a parameter";
1384       return true;
1385     }
1386 
1387     if (isa<GlobalsSpaceRegion>(MS)) {
1388       const VarRegion *VR = dyn_cast<VarRegion>(MR);
1389       const VarDecl *VD;
1390       if (VR)
1391         VD = VR->getDecl();
1392       else
1393         VD = nullptr;
1394 
1395       if (VD) {
1396         if (VD->isStaticLocal())
1397           os << "the address of the static variable '" << VD->getName() << "'";
1398         else
1399           os << "the address of the global variable '" << VD->getName() << "'";
1400       } else
1401         os << "the address of a global variable";
1402       return true;
1403     }
1404 
1405     return false;
1406   }
1407   }
1408 }
1409 
ReportBadFree(CheckerContext & C,SVal ArgVal,SourceRange Range,const Expr * DeallocExpr) const1410 void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
1411                                   SourceRange Range,
1412                                   const Expr *DeallocExpr) const {
1413 
1414   if (!ChecksEnabled[CK_MallocOptimistic] &&
1415       !ChecksEnabled[CK_MallocPessimistic] &&
1416       !ChecksEnabled[CK_NewDeleteChecker])
1417     return;
1418 
1419   Optional<MallocChecker::CheckKind> CheckKind =
1420       getCheckIfTracked(C, DeallocExpr);
1421   if (!CheckKind.hasValue())
1422     return;
1423 
1424   if (ExplodedNode *N = C.generateSink()) {
1425     if (!BT_BadFree[*CheckKind])
1426       BT_BadFree[*CheckKind].reset(
1427           new BugType(CheckNames[*CheckKind], "Bad free", "Memory Error"));
1428 
1429     SmallString<100> buf;
1430     llvm::raw_svector_ostream os(buf);
1431 
1432     const MemRegion *MR = ArgVal.getAsRegion();
1433     while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
1434       MR = ER->getSuperRegion();
1435 
1436     if (MR && isa<AllocaRegion>(MR))
1437       os << "Memory allocated by alloca() should not be deallocated";
1438     else {
1439       os << "Argument to ";
1440       if (!printAllocDeallocName(os, C, DeallocExpr))
1441         os << "deallocator";
1442 
1443       os << " is ";
1444       bool Summarized = MR ? SummarizeRegion(os, MR)
1445                            : SummarizeValue(os, ArgVal);
1446       if (Summarized)
1447         os << ", which is not memory allocated by ";
1448       else
1449         os << "not memory allocated by ";
1450 
1451       printExpectedAllocName(os, C, DeallocExpr);
1452     }
1453 
1454     BugReport *R = new BugReport(*BT_BadFree[*CheckKind], os.str(), N);
1455     R->markInteresting(MR);
1456     R->addRange(Range);
1457     C.emitReport(R);
1458   }
1459 }
1460 
ReportMismatchedDealloc(CheckerContext & C,SourceRange Range,const Expr * DeallocExpr,const RefState * RS,SymbolRef Sym,bool OwnershipTransferred) const1461 void MallocChecker::ReportMismatchedDealloc(CheckerContext &C,
1462                                             SourceRange Range,
1463                                             const Expr *DeallocExpr,
1464                                             const RefState *RS,
1465                                             SymbolRef Sym,
1466                                             bool OwnershipTransferred) const {
1467 
1468   if (!ChecksEnabled[CK_MismatchedDeallocatorChecker])
1469     return;
1470 
1471   if (ExplodedNode *N = C.generateSink()) {
1472     if (!BT_MismatchedDealloc)
1473       BT_MismatchedDealloc.reset(
1474           new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
1475                       "Bad deallocator", "Memory Error"));
1476 
1477     SmallString<100> buf;
1478     llvm::raw_svector_ostream os(buf);
1479 
1480     const Expr *AllocExpr = cast<Expr>(RS->getStmt());
1481     SmallString<20> AllocBuf;
1482     llvm::raw_svector_ostream AllocOs(AllocBuf);
1483     SmallString<20> DeallocBuf;
1484     llvm::raw_svector_ostream DeallocOs(DeallocBuf);
1485 
1486     if (OwnershipTransferred) {
1487       if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1488         os << DeallocOs.str() << " cannot";
1489       else
1490         os << "Cannot";
1491 
1492       os << " take ownership of memory";
1493 
1494       if (printAllocDeallocName(AllocOs, C, AllocExpr))
1495         os << " allocated by " << AllocOs.str();
1496     } else {
1497       os << "Memory";
1498       if (printAllocDeallocName(AllocOs, C, AllocExpr))
1499         os << " allocated by " << AllocOs.str();
1500 
1501       os << " should be deallocated by ";
1502         printExpectedDeallocName(os, RS->getAllocationFamily());
1503 
1504       if (printAllocDeallocName(DeallocOs, C, DeallocExpr))
1505         os << ", not " << DeallocOs.str();
1506     }
1507 
1508     BugReport *R = new BugReport(*BT_MismatchedDealloc, os.str(), N);
1509     R->markInteresting(Sym);
1510     R->addRange(Range);
1511     R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1512     C.emitReport(R);
1513   }
1514 }
1515 
ReportOffsetFree(CheckerContext & C,SVal ArgVal,SourceRange Range,const Expr * DeallocExpr,const Expr * AllocExpr) const1516 void MallocChecker::ReportOffsetFree(CheckerContext &C, SVal ArgVal,
1517                                      SourceRange Range, const Expr *DeallocExpr,
1518                                      const Expr *AllocExpr) const {
1519 
1520   if (!ChecksEnabled[CK_MallocOptimistic] &&
1521       !ChecksEnabled[CK_MallocPessimistic] &&
1522       !ChecksEnabled[CK_NewDeleteChecker])
1523     return;
1524 
1525   Optional<MallocChecker::CheckKind> CheckKind =
1526       getCheckIfTracked(C, AllocExpr);
1527   if (!CheckKind.hasValue())
1528     return;
1529 
1530   ExplodedNode *N = C.generateSink();
1531   if (!N)
1532     return;
1533 
1534   if (!BT_OffsetFree[*CheckKind])
1535     BT_OffsetFree[*CheckKind].reset(
1536         new BugType(CheckNames[*CheckKind], "Offset free", "Memory Error"));
1537 
1538   SmallString<100> buf;
1539   llvm::raw_svector_ostream os(buf);
1540   SmallString<20> AllocNameBuf;
1541   llvm::raw_svector_ostream AllocNameOs(AllocNameBuf);
1542 
1543   const MemRegion *MR = ArgVal.getAsRegion();
1544   assert(MR && "Only MemRegion based symbols can have offset free errors");
1545 
1546   RegionOffset Offset = MR->getAsOffset();
1547   assert((Offset.isValid() &&
1548           !Offset.hasSymbolicOffset() &&
1549           Offset.getOffset() != 0) &&
1550          "Only symbols with a valid offset can have offset free errors");
1551 
1552   int offsetBytes = Offset.getOffset() / C.getASTContext().getCharWidth();
1553 
1554   os << "Argument to ";
1555   if (!printAllocDeallocName(os, C, DeallocExpr))
1556     os << "deallocator";
1557   os << " is offset by "
1558      << offsetBytes
1559      << " "
1560      << ((abs(offsetBytes) > 1) ? "bytes" : "byte")
1561      << " from the start of ";
1562   if (AllocExpr && printAllocDeallocName(AllocNameOs, C, AllocExpr))
1563     os << "memory allocated by " << AllocNameOs.str();
1564   else
1565     os << "allocated memory";
1566 
1567   BugReport *R = new BugReport(*BT_OffsetFree[*CheckKind], os.str(), N);
1568   R->markInteresting(MR->getBaseRegion());
1569   R->addRange(Range);
1570   C.emitReport(R);
1571 }
1572 
ReportUseAfterFree(CheckerContext & C,SourceRange Range,SymbolRef Sym) const1573 void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
1574                                        SymbolRef Sym) const {
1575 
1576   if (!ChecksEnabled[CK_MallocOptimistic] &&
1577       !ChecksEnabled[CK_MallocPessimistic] &&
1578       !ChecksEnabled[CK_NewDeleteChecker])
1579     return;
1580 
1581   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1582   if (!CheckKind.hasValue())
1583     return;
1584 
1585   if (ExplodedNode *N = C.generateSink()) {
1586     if (!BT_UseFree[*CheckKind])
1587       BT_UseFree[*CheckKind].reset(new BugType(
1588           CheckNames[*CheckKind], "Use-after-free", "Memory Error"));
1589 
1590     BugReport *R = new BugReport(*BT_UseFree[*CheckKind],
1591                                  "Use of memory after it is freed", N);
1592 
1593     R->markInteresting(Sym);
1594     R->addRange(Range);
1595     R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1596     C.emitReport(R);
1597   }
1598 }
1599 
ReportDoubleFree(CheckerContext & C,SourceRange Range,bool Released,SymbolRef Sym,SymbolRef PrevSym) const1600 void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range,
1601                                      bool Released, SymbolRef Sym,
1602                                      SymbolRef PrevSym) const {
1603 
1604   if (!ChecksEnabled[CK_MallocOptimistic] &&
1605       !ChecksEnabled[CK_MallocPessimistic] &&
1606       !ChecksEnabled[CK_NewDeleteChecker])
1607     return;
1608 
1609   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1610   if (!CheckKind.hasValue())
1611     return;
1612 
1613   if (ExplodedNode *N = C.generateSink()) {
1614     if (!BT_DoubleFree[*CheckKind])
1615       BT_DoubleFree[*CheckKind].reset(
1616           new BugType(CheckNames[*CheckKind], "Double free", "Memory Error"));
1617 
1618     BugReport *R =
1619         new BugReport(*BT_DoubleFree[*CheckKind],
1620                       (Released ? "Attempt to free released memory"
1621                                 : "Attempt to free non-owned memory"),
1622                       N);
1623     R->addRange(Range);
1624     R->markInteresting(Sym);
1625     if (PrevSym)
1626       R->markInteresting(PrevSym);
1627     R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1628     C.emitReport(R);
1629   }
1630 }
1631 
ReportDoubleDelete(CheckerContext & C,SymbolRef Sym) const1632 void MallocChecker::ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
1633 
1634   if (!ChecksEnabled[CK_NewDeleteChecker])
1635     return;
1636 
1637   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
1638   if (!CheckKind.hasValue())
1639     return;
1640   assert(*CheckKind == CK_NewDeleteChecker && "invalid check kind");
1641 
1642   if (ExplodedNode *N = C.generateSink()) {
1643     if (!BT_DoubleDelete)
1644       BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker],
1645                                         "Double delete", "Memory Error"));
1646 
1647     BugReport *R = new BugReport(*BT_DoubleDelete,
1648                                  "Attempt to delete released memory", N);
1649 
1650     R->markInteresting(Sym);
1651     R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
1652     C.emitReport(R);
1653   }
1654 }
1655 
ReallocMem(CheckerContext & C,const CallExpr * CE,bool FreesOnFail) const1656 ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
1657                                           const CallExpr *CE,
1658                                           bool FreesOnFail) const {
1659   if (CE->getNumArgs() < 2)
1660     return nullptr;
1661 
1662   ProgramStateRef state = C.getState();
1663   const Expr *arg0Expr = CE->getArg(0);
1664   const LocationContext *LCtx = C.getLocationContext();
1665   SVal Arg0Val = state->getSVal(arg0Expr, LCtx);
1666   if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
1667     return nullptr;
1668   DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
1669 
1670   SValBuilder &svalBuilder = C.getSValBuilder();
1671 
1672   DefinedOrUnknownSVal PtrEQ =
1673     svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull());
1674 
1675   // Get the size argument. If there is no size arg then give up.
1676   const Expr *Arg1 = CE->getArg(1);
1677   if (!Arg1)
1678     return nullptr;
1679 
1680   // Get the value of the size argument.
1681   SVal Arg1ValG = state->getSVal(Arg1, LCtx);
1682   if (!Arg1ValG.getAs<DefinedOrUnknownSVal>())
1683     return nullptr;
1684   DefinedOrUnknownSVal Arg1Val = Arg1ValG.castAs<DefinedOrUnknownSVal>();
1685 
1686   // Compare the size argument to 0.
1687   DefinedOrUnknownSVal SizeZero =
1688     svalBuilder.evalEQ(state, Arg1Val,
1689                        svalBuilder.makeIntValWithPtrWidth(0, false));
1690 
1691   ProgramStateRef StatePtrIsNull, StatePtrNotNull;
1692   std::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ);
1693   ProgramStateRef StateSizeIsZero, StateSizeNotZero;
1694   std::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero);
1695   // We only assume exceptional states if they are definitely true; if the
1696   // state is under-constrained, assume regular realloc behavior.
1697   bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
1698   bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
1699 
1700   // If the ptr is NULL and the size is not 0, the call is equivalent to
1701   // malloc(size).
1702   if ( PrtIsNull && !SizeIsZero) {
1703     ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
1704                                                UndefinedVal(), StatePtrIsNull);
1705     return stateMalloc;
1706   }
1707 
1708   if (PrtIsNull && SizeIsZero)
1709     return nullptr;
1710 
1711   // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
1712   assert(!PrtIsNull);
1713   SymbolRef FromPtr = arg0Val.getAsSymbol();
1714   SVal RetVal = state->getSVal(CE, LCtx);
1715   SymbolRef ToPtr = RetVal.getAsSymbol();
1716   if (!FromPtr || !ToPtr)
1717     return nullptr;
1718 
1719   bool ReleasedAllocated = false;
1720 
1721   // If the size is 0, free the memory.
1722   if (SizeIsZero)
1723     if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero, 0,
1724                                                false, ReleasedAllocated)){
1725       // The semantics of the return value are:
1726       // If size was equal to 0, either NULL or a pointer suitable to be passed
1727       // to free() is returned. We just free the input pointer and do not add
1728       // any constrains on the output pointer.
1729       return stateFree;
1730     }
1731 
1732   // Default behavior.
1733   if (ProgramStateRef stateFree =
1734         FreeMemAux(C, CE, state, 0, false, ReleasedAllocated)) {
1735 
1736     ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
1737                                                 UnknownVal(), stateFree);
1738     if (!stateRealloc)
1739       return nullptr;
1740 
1741     ReallocPairKind Kind = RPToBeFreedAfterFailure;
1742     if (FreesOnFail)
1743       Kind = RPIsFreeOnFailure;
1744     else if (!ReleasedAllocated)
1745       Kind = RPDoNotTrackAfterFailure;
1746 
1747     // Record the info about the reallocated symbol so that we could properly
1748     // process failed reallocation.
1749     stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
1750                                                    ReallocPair(FromPtr, Kind));
1751     // The reallocated symbol should stay alive for as long as the new symbol.
1752     C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
1753     return stateRealloc;
1754   }
1755   return nullptr;
1756 }
1757 
CallocMem(CheckerContext & C,const CallExpr * CE)1758 ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){
1759   if (CE->getNumArgs() < 2)
1760     return nullptr;
1761 
1762   ProgramStateRef state = C.getState();
1763   SValBuilder &svalBuilder = C.getSValBuilder();
1764   const LocationContext *LCtx = C.getLocationContext();
1765   SVal count = state->getSVal(CE->getArg(0), LCtx);
1766   SVal elementSize = state->getSVal(CE->getArg(1), LCtx);
1767   SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize,
1768                                         svalBuilder.getContext().getSizeType());
1769   SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
1770 
1771   return MallocMemAux(C, CE, TotalSize, zeroVal, state);
1772 }
1773 
1774 LeakInfo
getAllocationSite(const ExplodedNode * N,SymbolRef Sym,CheckerContext & C) const1775 MallocChecker::getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
1776                                  CheckerContext &C) const {
1777   const LocationContext *LeakContext = N->getLocationContext();
1778   // Walk the ExplodedGraph backwards and find the first node that referred to
1779   // the tracked symbol.
1780   const ExplodedNode *AllocNode = N;
1781   const MemRegion *ReferenceRegion = nullptr;
1782 
1783   while (N) {
1784     ProgramStateRef State = N->getState();
1785     if (!State->get<RegionState>(Sym))
1786       break;
1787 
1788     // Find the most recent expression bound to the symbol in the current
1789     // context.
1790       if (!ReferenceRegion) {
1791         if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
1792           SVal Val = State->getSVal(MR);
1793           if (Val.getAsLocSymbol() == Sym) {
1794             const VarRegion* VR = MR->getBaseRegion()->getAs<VarRegion>();
1795             // Do not show local variables belonging to a function other than
1796             // where the error is reported.
1797             if (!VR ||
1798                 (VR->getStackFrame() == LeakContext->getCurrentStackFrame()))
1799               ReferenceRegion = MR;
1800           }
1801         }
1802       }
1803 
1804     // Allocation node, is the last node in the current context in which the
1805     // symbol was tracked.
1806     if (N->getLocationContext() == LeakContext)
1807       AllocNode = N;
1808     N = N->pred_empty() ? nullptr : *(N->pred_begin());
1809   }
1810 
1811   return LeakInfo(AllocNode, ReferenceRegion);
1812 }
1813 
reportLeak(SymbolRef Sym,ExplodedNode * N,CheckerContext & C) const1814 void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
1815                                CheckerContext &C) const {
1816 
1817   if (!ChecksEnabled[CK_MallocOptimistic] &&
1818       !ChecksEnabled[CK_MallocPessimistic] &&
1819       !ChecksEnabled[CK_NewDeleteLeaksChecker])
1820     return;
1821 
1822   const RefState *RS = C.getState()->get<RegionState>(Sym);
1823   assert(RS && "cannot leak an untracked symbol");
1824   AllocationFamily Family = RS->getAllocationFamily();
1825   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
1826   if (!CheckKind.hasValue())
1827     return;
1828 
1829   // Special case for new and new[]; these are controlled by a separate checker
1830   // flag so that they can be selectively disabled.
1831   if (Family == AF_CXXNew || Family == AF_CXXNewArray)
1832     if (!ChecksEnabled[CK_NewDeleteLeaksChecker])
1833       return;
1834 
1835   assert(N);
1836   if (!BT_Leak[*CheckKind]) {
1837     BT_Leak[*CheckKind].reset(
1838         new BugType(CheckNames[*CheckKind], "Memory leak", "Memory Error"));
1839     // Leaks should not be reported if they are post-dominated by a sink:
1840     // (1) Sinks are higher importance bugs.
1841     // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
1842     //     with __noreturn functions such as assert() or exit(). We choose not
1843     //     to report leaks on such paths.
1844     BT_Leak[*CheckKind]->setSuppressOnSink(true);
1845   }
1846 
1847   // Most bug reports are cached at the location where they occurred.
1848   // With leaks, we want to unique them by the location where they were
1849   // allocated, and only report a single path.
1850   PathDiagnosticLocation LocUsedForUniqueing;
1851   const ExplodedNode *AllocNode = nullptr;
1852   const MemRegion *Region = nullptr;
1853   std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
1854 
1855   ProgramPoint P = AllocNode->getLocation();
1856   const Stmt *AllocationStmt = nullptr;
1857   if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
1858     AllocationStmt = Exit->getCalleeContext()->getCallSite();
1859   else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
1860     AllocationStmt = SP->getStmt();
1861   if (AllocationStmt)
1862     LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
1863                                               C.getSourceManager(),
1864                                               AllocNode->getLocationContext());
1865 
1866   SmallString<200> buf;
1867   llvm::raw_svector_ostream os(buf);
1868   if (Region && Region->canPrintPretty()) {
1869     os << "Potential leak of memory pointed to by ";
1870     Region->printPretty(os);
1871   } else {
1872     os << "Potential memory leak";
1873   }
1874 
1875   BugReport *R =
1876       new BugReport(*BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
1877                     AllocNode->getLocationContext()->getDecl());
1878   R->markInteresting(Sym);
1879   R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym, true));
1880   C.emitReport(R);
1881 }
1882 
checkDeadSymbols(SymbolReaper & SymReaper,CheckerContext & C) const1883 void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
1884                                      CheckerContext &C) const
1885 {
1886   if (!SymReaper.hasDeadSymbols())
1887     return;
1888 
1889   ProgramStateRef state = C.getState();
1890   RegionStateTy RS = state->get<RegionState>();
1891   RegionStateTy::Factory &F = state->get_context<RegionState>();
1892 
1893   SmallVector<SymbolRef, 2> Errors;
1894   for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
1895     if (SymReaper.isDead(I->first)) {
1896       if (I->second.isAllocated())
1897         Errors.push_back(I->first);
1898       // Remove the dead symbol from the map.
1899       RS = F.remove(RS, I->first);
1900 
1901     }
1902   }
1903 
1904   // Cleanup the Realloc Pairs Map.
1905   ReallocPairsTy RP = state->get<ReallocPairs>();
1906   for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
1907     if (SymReaper.isDead(I->first) ||
1908         SymReaper.isDead(I->second.ReallocatedSym)) {
1909       state = state->remove<ReallocPairs>(I->first);
1910     }
1911   }
1912 
1913   // Cleanup the FreeReturnValue Map.
1914   FreeReturnValueTy FR = state->get<FreeReturnValue>();
1915   for (FreeReturnValueTy::iterator I = FR.begin(), E = FR.end(); I != E; ++I) {
1916     if (SymReaper.isDead(I->first) ||
1917         SymReaper.isDead(I->second)) {
1918       state = state->remove<FreeReturnValue>(I->first);
1919     }
1920   }
1921 
1922   // Generate leak node.
1923   ExplodedNode *N = C.getPredecessor();
1924   if (!Errors.empty()) {
1925     static CheckerProgramPointTag Tag("MallocChecker", "DeadSymbolsLeak");
1926     N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
1927     for (SmallVectorImpl<SymbolRef>::iterator
1928            I = Errors.begin(), E = Errors.end(); I != E; ++I) {
1929       reportLeak(*I, N, C);
1930     }
1931   }
1932 
1933   C.addTransition(state->set<RegionState>(RS), N);
1934 }
1935 
checkPreCall(const CallEvent & Call,CheckerContext & C) const1936 void MallocChecker::checkPreCall(const CallEvent &Call,
1937                                  CheckerContext &C) const {
1938 
1939   if (const CXXDestructorCall *DC = dyn_cast<CXXDestructorCall>(&Call)) {
1940     SymbolRef Sym = DC->getCXXThisVal().getAsSymbol();
1941     if (!Sym || checkDoubleDelete(Sym, C))
1942       return;
1943   }
1944 
1945   // We will check for double free in the post visit.
1946   if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
1947     const FunctionDecl *FD = FC->getDecl();
1948     if (!FD)
1949       return;
1950 
1951     ASTContext &Ctx = C.getASTContext();
1952     if ((ChecksEnabled[CK_MallocOptimistic] ||
1953          ChecksEnabled[CK_MallocPessimistic]) &&
1954         (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Free) ||
1955          isCMemFunction(FD, Ctx, AF_IfNameIndex,
1956                         MemoryOperationKind::MOK_Free)))
1957       return;
1958 
1959     if (ChecksEnabled[CK_NewDeleteChecker] &&
1960         isStandardNewDelete(FD, Ctx))
1961       return;
1962   }
1963 
1964   // Check if the callee of a method is deleted.
1965   if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
1966     SymbolRef Sym = CC->getCXXThisVal().getAsSymbol();
1967     if (!Sym || checkUseAfterFree(Sym, C, CC->getCXXThisExpr()))
1968       return;
1969   }
1970 
1971   // Check arguments for being used after free.
1972   for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
1973     SVal ArgSVal = Call.getArgSVal(I);
1974     if (ArgSVal.getAs<Loc>()) {
1975       SymbolRef Sym = ArgSVal.getAsSymbol();
1976       if (!Sym)
1977         continue;
1978       if (checkUseAfterFree(Sym, C, Call.getArgExpr(I)))
1979         return;
1980     }
1981   }
1982 }
1983 
checkPreStmt(const ReturnStmt * S,CheckerContext & C) const1984 void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
1985   const Expr *E = S->getRetValue();
1986   if (!E)
1987     return;
1988 
1989   // Check if we are returning a symbol.
1990   ProgramStateRef State = C.getState();
1991   SVal RetVal = State->getSVal(E, C.getLocationContext());
1992   SymbolRef Sym = RetVal.getAsSymbol();
1993   if (!Sym)
1994     // If we are returning a field of the allocated struct or an array element,
1995     // the callee could still free the memory.
1996     // TODO: This logic should be a part of generic symbol escape callback.
1997     if (const MemRegion *MR = RetVal.getAsRegion())
1998       if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
1999         if (const SymbolicRegion *BMR =
2000               dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
2001           Sym = BMR->getSymbol();
2002 
2003   // Check if we are returning freed memory.
2004   if (Sym)
2005     checkUseAfterFree(Sym, C, E);
2006 }
2007 
2008 // TODO: Blocks should be either inlined or should call invalidate regions
2009 // upon invocation. After that's in place, special casing here will not be
2010 // needed.
checkPostStmt(const BlockExpr * BE,CheckerContext & C) const2011 void MallocChecker::checkPostStmt(const BlockExpr *BE,
2012                                   CheckerContext &C) const {
2013 
2014   // Scan the BlockDecRefExprs for any object the retain count checker
2015   // may be tracking.
2016   if (!BE->getBlockDecl()->hasCaptures())
2017     return;
2018 
2019   ProgramStateRef state = C.getState();
2020   const BlockDataRegion *R =
2021     cast<BlockDataRegion>(state->getSVal(BE,
2022                                          C.getLocationContext()).getAsRegion());
2023 
2024   BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
2025                                             E = R->referenced_vars_end();
2026 
2027   if (I == E)
2028     return;
2029 
2030   SmallVector<const MemRegion*, 10> Regions;
2031   const LocationContext *LC = C.getLocationContext();
2032   MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
2033 
2034   for ( ; I != E; ++I) {
2035     const VarRegion *VR = I.getCapturedRegion();
2036     if (VR->getSuperRegion() == R) {
2037       VR = MemMgr.getVarRegion(VR->getDecl(), LC);
2038     }
2039     Regions.push_back(VR);
2040   }
2041 
2042   state =
2043     state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
2044                                     Regions.data() + Regions.size()).getState();
2045   C.addTransition(state);
2046 }
2047 
isReleased(SymbolRef Sym,CheckerContext & C) const2048 bool MallocChecker::isReleased(SymbolRef Sym, CheckerContext &C) const {
2049   assert(Sym);
2050   const RefState *RS = C.getState()->get<RegionState>(Sym);
2051   return (RS && RS->isReleased());
2052 }
2053 
checkUseAfterFree(SymbolRef Sym,CheckerContext & C,const Stmt * S) const2054 bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
2055                                       const Stmt *S) const {
2056 
2057   if (isReleased(Sym, C)) {
2058     ReportUseAfterFree(C, S->getSourceRange(), Sym);
2059     return true;
2060   }
2061 
2062   return false;
2063 }
2064 
checkDoubleDelete(SymbolRef Sym,CheckerContext & C) const2065 bool MallocChecker::checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const {
2066 
2067   if (isReleased(Sym, C)) {
2068     ReportDoubleDelete(C, Sym);
2069     return true;
2070   }
2071   return false;
2072 }
2073 
2074 // Check if the location is a freed symbolic region.
checkLocation(SVal l,bool isLoad,const Stmt * S,CheckerContext & C) const2075 void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
2076                                   CheckerContext &C) const {
2077   SymbolRef Sym = l.getLocSymbolInBase();
2078   if (Sym)
2079     checkUseAfterFree(Sym, C, S);
2080 }
2081 
2082 // If a symbolic region is assumed to NULL (or another constant), stop tracking
2083 // it - assuming that allocation failed on this path.
evalAssume(ProgramStateRef state,SVal Cond,bool Assumption) const2084 ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
2085                                               SVal Cond,
2086                                               bool Assumption) const {
2087   RegionStateTy RS = state->get<RegionState>();
2088   for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2089     // If the symbol is assumed to be NULL, remove it from consideration.
2090     ConstraintManager &CMgr = state->getConstraintManager();
2091     ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
2092     if (AllocFailed.isConstrainedTrue())
2093       state = state->remove<RegionState>(I.getKey());
2094   }
2095 
2096   // Realloc returns 0 when reallocation fails, which means that we should
2097   // restore the state of the pointer being reallocated.
2098   ReallocPairsTy RP = state->get<ReallocPairs>();
2099   for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
2100     // If the symbol is assumed to be NULL, remove it from consideration.
2101     ConstraintManager &CMgr = state->getConstraintManager();
2102     ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
2103     if (!AllocFailed.isConstrainedTrue())
2104       continue;
2105 
2106     SymbolRef ReallocSym = I.getData().ReallocatedSym;
2107     if (const RefState *RS = state->get<RegionState>(ReallocSym)) {
2108       if (RS->isReleased()) {
2109         if (I.getData().Kind == RPToBeFreedAfterFailure)
2110           state = state->set<RegionState>(ReallocSym,
2111               RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt()));
2112         else if (I.getData().Kind == RPDoNotTrackAfterFailure)
2113           state = state->remove<RegionState>(ReallocSym);
2114         else
2115           assert(I.getData().Kind == RPIsFreeOnFailure);
2116       }
2117     }
2118     state = state->remove<ReallocPairs>(I.getKey());
2119   }
2120 
2121   return state;
2122 }
2123 
mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent * Call,ProgramStateRef State,SymbolRef & EscapingSymbol) const2124 bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
2125                                               const CallEvent *Call,
2126                                               ProgramStateRef State,
2127                                               SymbolRef &EscapingSymbol) const {
2128   assert(Call);
2129   EscapingSymbol = nullptr;
2130 
2131   // For now, assume that any C++ or block call can free memory.
2132   // TODO: If we want to be more optimistic here, we'll need to make sure that
2133   // regions escape to C++ containers. They seem to do that even now, but for
2134   // mysterious reasons.
2135   if (!(isa<SimpleFunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
2136     return true;
2137 
2138   // Check Objective-C messages by selector name.
2139   if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
2140     // If it's not a framework call, or if it takes a callback, assume it
2141     // can free memory.
2142     if (!Call->isInSystemHeader() || Call->hasNonZeroCallbackArg())
2143       return true;
2144 
2145     // If it's a method we know about, handle it explicitly post-call.
2146     // This should happen before the "freeWhenDone" check below.
2147     if (isKnownDeallocObjCMethodName(*Msg))
2148       return false;
2149 
2150     // If there's a "freeWhenDone" parameter, but the method isn't one we know
2151     // about, we can't be sure that the object will use free() to deallocate the
2152     // memory, so we can't model it explicitly. The best we can do is use it to
2153     // decide whether the pointer escapes.
2154     if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(*Msg))
2155       return *FreeWhenDone;
2156 
2157     // If the first selector piece ends with "NoCopy", and there is no
2158     // "freeWhenDone" parameter set to zero, we know ownership is being
2159     // transferred. Again, though, we can't be sure that the object will use
2160     // free() to deallocate the memory, so we can't model it explicitly.
2161     StringRef FirstSlot = Msg->getSelector().getNameForSlot(0);
2162     if (FirstSlot.endswith("NoCopy"))
2163       return true;
2164 
2165     // If the first selector starts with addPointer, insertPointer,
2166     // or replacePointer, assume we are dealing with NSPointerArray or similar.
2167     // This is similar to C++ containers (vector); we still might want to check
2168     // that the pointers get freed by following the container itself.
2169     if (FirstSlot.startswith("addPointer") ||
2170         FirstSlot.startswith("insertPointer") ||
2171         FirstSlot.startswith("replacePointer") ||
2172         FirstSlot.equals("valueWithPointer")) {
2173       return true;
2174     }
2175 
2176     // We should escape receiver on call to 'init'. This is especially relevant
2177     // to the receiver, as the corresponding symbol is usually not referenced
2178     // after the call.
2179     if (Msg->getMethodFamily() == OMF_init) {
2180       EscapingSymbol = Msg->getReceiverSVal().getAsSymbol();
2181       return true;
2182     }
2183 
2184     // Otherwise, assume that the method does not free memory.
2185     // Most framework methods do not free memory.
2186     return false;
2187   }
2188 
2189   // At this point the only thing left to handle is straight function calls.
2190   const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl();
2191   if (!FD)
2192     return true;
2193 
2194   ASTContext &ASTC = State->getStateManager().getContext();
2195 
2196   // If it's one of the allocation functions we can reason about, we model
2197   // its behavior explicitly.
2198   if (isMemFunction(FD, ASTC))
2199     return false;
2200 
2201   // If it's not a system call, assume it frees memory.
2202   if (!Call->isInSystemHeader())
2203     return true;
2204 
2205   // White list the system functions whose arguments escape.
2206   const IdentifierInfo *II = FD->getIdentifier();
2207   if (!II)
2208     return true;
2209   StringRef FName = II->getName();
2210 
2211   // White list the 'XXXNoCopy' CoreFoundation functions.
2212   // We specifically check these before
2213   if (FName.endswith("NoCopy")) {
2214     // Look for the deallocator argument. We know that the memory ownership
2215     // is not transferred only if the deallocator argument is
2216     // 'kCFAllocatorNull'.
2217     for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
2218       const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts();
2219       if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
2220         StringRef DeallocatorName = DE->getFoundDecl()->getName();
2221         if (DeallocatorName == "kCFAllocatorNull")
2222           return false;
2223       }
2224     }
2225     return true;
2226   }
2227 
2228   // Associating streams with malloced buffers. The pointer can escape if
2229   // 'closefn' is specified (and if that function does free memory),
2230   // but it will not if closefn is not specified.
2231   // Currently, we do not inspect the 'closefn' function (PR12101).
2232   if (FName == "funopen")
2233     if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0))
2234       return false;
2235 
2236   // Do not warn on pointers passed to 'setbuf' when used with std streams,
2237   // these leaks might be intentional when setting the buffer for stdio.
2238   // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
2239   if (FName == "setbuf" || FName =="setbuffer" ||
2240       FName == "setlinebuf" || FName == "setvbuf") {
2241     if (Call->getNumArgs() >= 1) {
2242       const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts();
2243       if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
2244         if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
2245           if (D->getCanonicalDecl()->getName().find("std") != StringRef::npos)
2246             return true;
2247     }
2248   }
2249 
2250   // A bunch of other functions which either take ownership of a pointer or
2251   // wrap the result up in a struct or object, meaning it can be freed later.
2252   // (See RetainCountChecker.) Not all the parameters here are invalidated,
2253   // but the Malloc checker cannot differentiate between them. The right way
2254   // of doing this would be to implement a pointer escapes callback.
2255   if (FName == "CGBitmapContextCreate" ||
2256       FName == "CGBitmapContextCreateWithData" ||
2257       FName == "CVPixelBufferCreateWithBytes" ||
2258       FName == "CVPixelBufferCreateWithPlanarBytes" ||
2259       FName == "OSAtomicEnqueue") {
2260     return true;
2261   }
2262 
2263   // Handle cases where we know a buffer's /address/ can escape.
2264   // Note that the above checks handle some special cases where we know that
2265   // even though the address escapes, it's still our responsibility to free the
2266   // buffer.
2267   if (Call->argumentsMayEscape())
2268     return true;
2269 
2270   // Otherwise, assume that the function does not free memory.
2271   // Most system calls do not free the memory.
2272   return false;
2273 }
2274 
retTrue(const RefState * RS)2275 static bool retTrue(const RefState *RS) {
2276   return true;
2277 }
2278 
checkIfNewOrNewArrayFamily(const RefState * RS)2279 static bool checkIfNewOrNewArrayFamily(const RefState *RS) {
2280   return (RS->getAllocationFamily() == AF_CXXNewArray ||
2281           RS->getAllocationFamily() == AF_CXXNew);
2282 }
2283 
checkPointerEscape(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind) const2284 ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
2285                                              const InvalidatedSymbols &Escaped,
2286                                              const CallEvent *Call,
2287                                              PointerEscapeKind Kind) const {
2288   return checkPointerEscapeAux(State, Escaped, Call, Kind, &retTrue);
2289 }
2290 
checkConstPointerEscape(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind) const2291 ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State,
2292                                               const InvalidatedSymbols &Escaped,
2293                                               const CallEvent *Call,
2294                                               PointerEscapeKind Kind) const {
2295   return checkPointerEscapeAux(State, Escaped, Call, Kind,
2296                                &checkIfNewOrNewArrayFamily);
2297 }
2298 
checkPointerEscapeAux(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind,bool (* CheckRefState)(const RefState *)) const2299 ProgramStateRef MallocChecker::checkPointerEscapeAux(ProgramStateRef State,
2300                                               const InvalidatedSymbols &Escaped,
2301                                               const CallEvent *Call,
2302                                               PointerEscapeKind Kind,
2303                                   bool(*CheckRefState)(const RefState*)) const {
2304   // If we know that the call does not free memory, or we want to process the
2305   // call later, keep tracking the top level arguments.
2306   SymbolRef EscapingSymbol = nullptr;
2307   if (Kind == PSK_DirectEscapeOnCall &&
2308       !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State,
2309                                                     EscapingSymbol) &&
2310       !EscapingSymbol) {
2311     return State;
2312   }
2313 
2314   for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
2315        E = Escaped.end();
2316        I != E; ++I) {
2317     SymbolRef sym = *I;
2318 
2319     if (EscapingSymbol && EscapingSymbol != sym)
2320       continue;
2321 
2322     if (const RefState *RS = State->get<RegionState>(sym)) {
2323       if (RS->isAllocated() && CheckRefState(RS)) {
2324         State = State->remove<RegionState>(sym);
2325         State = State->set<RegionState>(sym, RefState::getEscaped(RS));
2326       }
2327     }
2328   }
2329   return State;
2330 }
2331 
findFailedReallocSymbol(ProgramStateRef currState,ProgramStateRef prevState)2332 static SymbolRef findFailedReallocSymbol(ProgramStateRef currState,
2333                                          ProgramStateRef prevState) {
2334   ReallocPairsTy currMap = currState->get<ReallocPairs>();
2335   ReallocPairsTy prevMap = prevState->get<ReallocPairs>();
2336 
2337   for (ReallocPairsTy::iterator I = prevMap.begin(), E = prevMap.end();
2338        I != E; ++I) {
2339     SymbolRef sym = I.getKey();
2340     if (!currMap.lookup(sym))
2341       return sym;
2342   }
2343 
2344   return nullptr;
2345 }
2346 
2347 PathDiagnosticPiece *
VisitNode(const ExplodedNode * N,const ExplodedNode * PrevN,BugReporterContext & BRC,BugReport & BR)2348 MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
2349                                            const ExplodedNode *PrevN,
2350                                            BugReporterContext &BRC,
2351                                            BugReport &BR) {
2352   ProgramStateRef state = N->getState();
2353   ProgramStateRef statePrev = PrevN->getState();
2354 
2355   const RefState *RS = state->get<RegionState>(Sym);
2356   const RefState *RSPrev = statePrev->get<RegionState>(Sym);
2357   if (!RS)
2358     return nullptr;
2359 
2360   const Stmt *S = nullptr;
2361   const char *Msg = nullptr;
2362   StackHintGeneratorForSymbol *StackHint = nullptr;
2363 
2364   // Retrieve the associated statement.
2365   ProgramPoint ProgLoc = N->getLocation();
2366   if (Optional<StmtPoint> SP = ProgLoc.getAs<StmtPoint>()) {
2367     S = SP->getStmt();
2368   } else if (Optional<CallExitEnd> Exit = ProgLoc.getAs<CallExitEnd>()) {
2369     S = Exit->getCalleeContext()->getCallSite();
2370   } else if (Optional<BlockEdge> Edge = ProgLoc.getAs<BlockEdge>()) {
2371     // If an assumption was made on a branch, it should be caught
2372     // here by looking at the state transition.
2373     S = Edge->getSrc()->getTerminator();
2374   }
2375 
2376   if (!S)
2377     return nullptr;
2378 
2379   // FIXME: We will eventually need to handle non-statement-based events
2380   // (__attribute__((cleanup))).
2381 
2382   // Find out if this is an interesting point and what is the kind.
2383   if (Mode == Normal) {
2384     if (isAllocated(RS, RSPrev, S)) {
2385       Msg = "Memory is allocated";
2386       StackHint = new StackHintGeneratorForSymbol(Sym,
2387                                                   "Returned allocated memory");
2388     } else if (isReleased(RS, RSPrev, S)) {
2389       Msg = "Memory is released";
2390       StackHint = new StackHintGeneratorForSymbol(Sym,
2391                                              "Returning; memory was released");
2392     } else if (isRelinquished(RS, RSPrev, S)) {
2393       Msg = "Memory ownership is transferred";
2394       StackHint = new StackHintGeneratorForSymbol(Sym, "");
2395     } else if (isReallocFailedCheck(RS, RSPrev, S)) {
2396       Mode = ReallocationFailed;
2397       Msg = "Reallocation failed";
2398       StackHint = new StackHintGeneratorForReallocationFailed(Sym,
2399                                                        "Reallocation failed");
2400 
2401       if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
2402         // Is it possible to fail two reallocs WITHOUT testing in between?
2403         assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
2404           "We only support one failed realloc at a time.");
2405         BR.markInteresting(sym);
2406         FailedReallocSymbol = sym;
2407       }
2408     }
2409 
2410   // We are in a special mode if a reallocation failed later in the path.
2411   } else if (Mode == ReallocationFailed) {
2412     assert(FailedReallocSymbol && "No symbol to look for.");
2413 
2414     // Is this is the first appearance of the reallocated symbol?
2415     if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
2416       // We're at the reallocation point.
2417       Msg = "Attempt to reallocate memory";
2418       StackHint = new StackHintGeneratorForSymbol(Sym,
2419                                                  "Returned reallocated memory");
2420       FailedReallocSymbol = nullptr;
2421       Mode = Normal;
2422     }
2423   }
2424 
2425   if (!Msg)
2426     return nullptr;
2427   assert(StackHint);
2428 
2429   // Generate the extra diagnostic.
2430   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
2431                              N->getLocationContext());
2432   return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint);
2433 }
2434 
printState(raw_ostream & Out,ProgramStateRef State,const char * NL,const char * Sep) const2435 void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
2436                                const char *NL, const char *Sep) const {
2437 
2438   RegionStateTy RS = State->get<RegionState>();
2439 
2440   if (!RS.isEmpty()) {
2441     Out << Sep << "MallocChecker :" << NL;
2442     for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2443       const RefState *RefS = State->get<RegionState>(I.getKey());
2444       AllocationFamily Family = RefS->getAllocationFamily();
2445       Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
2446 
2447       I.getKey()->dumpToStream(Out);
2448       Out << " : ";
2449       I.getData().dump(Out);
2450       if (CheckKind.hasValue())
2451         Out << " (" << CheckNames[*CheckKind].getName() << ")";
2452       Out << NL;
2453     }
2454   }
2455 }
2456 
registerNewDeleteLeaksChecker(CheckerManager & mgr)2457 void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
2458   registerCStringCheckerBasic(mgr);
2459   MallocChecker *checker = mgr.registerChecker<MallocChecker>();
2460   checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
2461   checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
2462       mgr.getCurrentCheckName();
2463   // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete
2464   // checker.
2465   if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker])
2466     checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;
2467 }
2468 
2469 #define REGISTER_CHECKER(name)                                                 \
2470   void ento::register##name(CheckerManager &mgr) {                             \
2471     registerCStringCheckerBasic(mgr);                                          \
2472     MallocChecker *checker = mgr.registerChecker<MallocChecker>();             \
2473     checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
2474     checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
2475   }
2476 
2477 REGISTER_CHECKER(MallocPessimistic)
2478 REGISTER_CHECKER(MallocOptimistic)
2479 REGISTER_CHECKER(NewDeleteChecker)
2480 REGISTER_CHECKER(MismatchedDeallocatorChecker)
2481