1 //=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines a variety of memory management related checkers, such as
10 // leak, double free, and use-after-free.
11 //
12 // The following checkers are defined here:
13 //
14 //   * MallocChecker
15 //       Despite its name, it models all sorts of memory allocations and
16 //       de- or reallocation, including but not limited to malloc, free,
17 //       relloc, new, delete. It also reports on a variety of memory misuse
18 //       errors.
19 //       Many other checkers interact very closely with this checker, in fact,
20 //       most are merely options to this one. Other checkers may register
21 //       MallocChecker, but do not enable MallocChecker's reports (more details
22 //       to follow around its field, ChecksEnabled).
23 //       It also has a boolean "Optimistic" checker option, which if set to true
24 //       will cause the checker to model user defined memory management related
25 //       functions annotated via the attribute ownership_takes, ownership_holds
26 //       and ownership_returns.
27 //
28 //   * NewDeleteChecker
29 //       Enables the modeling of new, new[], delete, delete[] in MallocChecker,
30 //       and checks for related double-free and use-after-free errors.
31 //
32 //   * NewDeleteLeaksChecker
33 //       Checks for leaks related to new, new[], delete, delete[].
34 //       Depends on NewDeleteChecker.
35 //
36 //   * MismatchedDeallocatorChecker
37 //       Enables checking whether memory is deallocated with the correspending
38 //       allocation function in MallocChecker, such as malloc() allocated
39 //       regions are only freed by free(), new by delete, new[] by delete[].
40 //
41 //  InnerPointerChecker interacts very closely with MallocChecker, but unlike
42 //  the above checkers, it has it's own file, hence the many InnerPointerChecker
43 //  related headers and non-static functions.
44 //
45 //===----------------------------------------------------------------------===//
46 
47 #include "AllocationState.h"
48 #include "InterCheckerAPI.h"
49 #include "clang/AST/Attr.h"
50 #include "clang/AST/DeclCXX.h"
51 #include "clang/AST/Expr.h"
52 #include "clang/AST/ExprCXX.h"
53 #include "clang/AST/ParentMap.h"
54 #include "clang/Basic/LLVM.h"
55 #include "clang/Basic/SourceManager.h"
56 #include "clang/Basic/TargetInfo.h"
57 #include "clang/Lex/Lexer.h"
58 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
59 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
60 #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
61 #include "clang/StaticAnalyzer/Core/Checker.h"
62 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
63 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
64 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
65 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
66 #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
67 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
68 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
69 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
70 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
71 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
72 #include "llvm/ADT/STLExtras.h"
73 #include "llvm/ADT/SmallString.h"
74 #include "llvm/ADT/StringExtras.h"
75 #include "llvm/Support/Compiler.h"
76 #include "llvm/Support/ErrorHandling.h"
77 #include <climits>
78 #include <functional>
79 #include <utility>
80 
81 using namespace clang;
82 using namespace ento;
83 using namespace std::placeholders;
84 
85 //===----------------------------------------------------------------------===//
86 // The types of allocation we're modeling. This is used to check whether a
87 // dynamically allocated object is deallocated with the correct function, like
88 // not using operator delete on an object created by malloc(), or alloca regions
89 // aren't ever deallocated manually.
90 //===----------------------------------------------------------------------===//
91 
92 namespace {
93 
94 // Used to check correspondence between allocators and deallocators.
95 enum AllocationFamily {
96   AF_None,
97   AF_Malloc,
98   AF_CXXNew,
99   AF_CXXNewArray,
100   AF_IfNameIndex,
101   AF_Alloca,
102   AF_InnerBuffer
103 };
104 
105 } // end of anonymous namespace
106 
107 /// Print names of allocators and deallocators.
108 ///
109 /// \returns true on success.
110 static bool printMemFnName(raw_ostream &os, CheckerContext &C, const Expr *E);
111 
112 /// Print expected name of an allocator based on the deallocator's family
113 /// derived from the DeallocExpr.
114 static void printExpectedAllocName(raw_ostream &os, AllocationFamily Family);
115 
116 /// Print expected name of a deallocator based on the allocator's
117 /// family.
118 static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family);
119 
120 //===----------------------------------------------------------------------===//
121 // The state of a symbol, in terms of memory management.
122 //===----------------------------------------------------------------------===//
123 
124 namespace {
125 
126 class RefState {
127   enum Kind {
128     // Reference to allocated memory.
129     Allocated,
130     // Reference to zero-allocated memory.
131     AllocatedOfSizeZero,
132     // Reference to released/freed memory.
133     Released,
134     // The responsibility for freeing resources has transferred from
135     // this reference. A relinquished symbol should not be freed.
136     Relinquished,
137     // We are no longer guaranteed to have observed all manipulations
138     // of this pointer/memory. For example, it could have been
139     // passed as a parameter to an opaque function.
140     Escaped
141   };
142 
143   const Stmt *S;
144 
145   Kind K;
146   AllocationFamily Family;
147 
RefState(Kind k,const Stmt * s,AllocationFamily family)148   RefState(Kind k, const Stmt *s, AllocationFamily family)
149       : S(s), K(k), Family(family) {
150     assert(family != AF_None);
151   }
152 
153 public:
isAllocated() const154   bool isAllocated() const { return K == Allocated; }
isAllocatedOfSizeZero() const155   bool isAllocatedOfSizeZero() const { return K == AllocatedOfSizeZero; }
isReleased() const156   bool isReleased() const { return K == Released; }
isRelinquished() const157   bool isRelinquished() const { return K == Relinquished; }
isEscaped() const158   bool isEscaped() const { return K == Escaped; }
getAllocationFamily() const159   AllocationFamily getAllocationFamily() const { return Family; }
getStmt() const160   const Stmt *getStmt() const { return S; }
161 
operator ==(const RefState & X) const162   bool operator==(const RefState &X) const {
163     return K == X.K && S == X.S && Family == X.Family;
164   }
165 
getAllocated(AllocationFamily family,const Stmt * s)166   static RefState getAllocated(AllocationFamily family, const Stmt *s) {
167     return RefState(Allocated, s, family);
168   }
getAllocatedOfSizeZero(const RefState * RS)169   static RefState getAllocatedOfSizeZero(const RefState *RS) {
170     return RefState(AllocatedOfSizeZero, RS->getStmt(),
171                     RS->getAllocationFamily());
172   }
getReleased(AllocationFamily family,const Stmt * s)173   static RefState getReleased(AllocationFamily family, const Stmt *s) {
174     return RefState(Released, s, family);
175   }
getRelinquished(AllocationFamily family,const Stmt * s)176   static RefState getRelinquished(AllocationFamily family, const Stmt *s) {
177     return RefState(Relinquished, s, family);
178   }
getEscaped(const RefState * RS)179   static RefState getEscaped(const RefState *RS) {
180     return RefState(Escaped, RS->getStmt(), RS->getAllocationFamily());
181   }
182 
Profile(llvm::FoldingSetNodeID & ID) const183   void Profile(llvm::FoldingSetNodeID &ID) const {
184     ID.AddInteger(K);
185     ID.AddPointer(S);
186     ID.AddInteger(Family);
187   }
188 
dump(raw_ostream & OS) const189   LLVM_DUMP_METHOD void dump(raw_ostream &OS) const {
190     switch (K) {
191 #define CASE(ID) case ID: OS << #ID; break;
192     CASE(Allocated)
193     CASE(AllocatedOfSizeZero)
194     CASE(Released)
195     CASE(Relinquished)
196     CASE(Escaped)
197     }
198   }
199 
dump() const200   LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
201 };
202 
203 } // end of anonymous namespace
204 
205 REGISTER_MAP_WITH_PROGRAMSTATE(RegionState, SymbolRef, RefState)
206 
207 /// Check if the memory associated with this symbol was released.
208 static bool isReleased(SymbolRef Sym, CheckerContext &C);
209 
210 /// Update the RefState to reflect the new memory allocation.
211 /// The optional \p RetVal parameter specifies the newly allocated pointer
212 /// value; if unspecified, the value of expression \p E is used.
213 static ProgramStateRef MallocUpdateRefState(CheckerContext &C, const Expr *E,
214                                             ProgramStateRef State,
215                                             AllocationFamily Family,
216                                             Optional<SVal> RetVal = None);
217 
218 //===----------------------------------------------------------------------===//
219 // The modeling of memory reallocation.
220 //
221 // The terminology 'toPtr' and 'fromPtr' will be used:
222 //   toPtr = realloc(fromPtr, 20);
223 //===----------------------------------------------------------------------===//
224 
225 REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols, SymbolRef)
226 
227 namespace {
228 
229 /// The state of 'fromPtr' after reallocation is known to have failed.
230 enum OwnershipAfterReallocKind {
231   // The symbol needs to be freed (e.g.: realloc)
232   OAR_ToBeFreedAfterFailure,
233   // The symbol has been freed (e.g.: reallocf)
234   OAR_FreeOnFailure,
235   // The symbol doesn't have to freed (e.g.: we aren't sure if, how and where
236   // 'fromPtr' was allocated:
237   //    void Haha(int *ptr) {
238   //      ptr = realloc(ptr, 67);
239   //      // ...
240   //    }
241   // ).
242   OAR_DoNotTrackAfterFailure
243 };
244 
245 /// Stores information about the 'fromPtr' symbol after reallocation.
246 ///
247 /// This is important because realloc may fail, and that needs special modeling.
248 /// Whether reallocation failed or not will not be known until later, so we'll
249 /// store whether upon failure 'fromPtr' will be freed, or needs to be freed
250 /// later, etc.
251 struct ReallocPair {
252 
253   // The 'fromPtr'.
254   SymbolRef ReallocatedSym;
255   OwnershipAfterReallocKind Kind;
256 
ReallocPair__anonaa8fcd210311::ReallocPair257   ReallocPair(SymbolRef S, OwnershipAfterReallocKind K)
258       : ReallocatedSym(S), Kind(K) {}
Profile__anonaa8fcd210311::ReallocPair259   void Profile(llvm::FoldingSetNodeID &ID) const {
260     ID.AddInteger(Kind);
261     ID.AddPointer(ReallocatedSym);
262   }
operator ==__anonaa8fcd210311::ReallocPair263   bool operator==(const ReallocPair &X) const {
264     return ReallocatedSym == X.ReallocatedSym &&
265            Kind == X.Kind;
266   }
267 };
268 
269 } // end of anonymous namespace
270 
271 REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair)
272 
273 /// Tells if the callee is one of the builtin new/delete operators, including
274 /// placement operators and other standard overloads.
275 static bool isStandardNewDelete(const FunctionDecl *FD);
isStandardNewDelete(const CallEvent & Call)276 static bool isStandardNewDelete(const CallEvent &Call) {
277   if (!Call.getDecl() || !isa<FunctionDecl>(Call.getDecl()))
278     return false;
279   return isStandardNewDelete(cast<FunctionDecl>(Call.getDecl()));
280 }
281 
282 //===----------------------------------------------------------------------===//
283 // Definition of the MallocChecker class.
284 //===----------------------------------------------------------------------===//
285 
286 namespace {
287 
288 class MallocChecker
289     : public Checker<check::DeadSymbols, check::PointerEscape,
290                      check::ConstPointerEscape, check::PreStmt<ReturnStmt>,
291                      check::EndFunction, check::PreCall, check::PostCall,
292                      check::NewAllocator, check::PostStmt<BlockExpr>,
293                      check::PostObjCMessage, check::Location, eval::Assume> {
294 public:
295   /// In pessimistic mode, the checker assumes that it does not know which
296   /// functions might free the memory.
297   /// In optimistic mode, the checker assumes that all user-defined functions
298   /// which might free a pointer are annotated.
299   DefaultBool ShouldIncludeOwnershipAnnotatedFunctions;
300 
301   /// Many checkers are essentially built into this one, so enabling them will
302   /// make MallocChecker perform additional modeling and reporting.
303   enum CheckKind {
304     /// When a subchecker is enabled but MallocChecker isn't, model memory
305     /// management but do not emit warnings emitted with MallocChecker only
306     /// enabled.
307     CK_MallocChecker,
308     CK_NewDeleteChecker,
309     CK_NewDeleteLeaksChecker,
310     CK_MismatchedDeallocatorChecker,
311     CK_InnerPointerChecker,
312     CK_NumCheckKinds
313   };
314 
315   using LeakInfo = std::pair<const ExplodedNode *, const MemRegion *>;
316 
317   DefaultBool ChecksEnabled[CK_NumCheckKinds];
318   CheckerNameRef CheckNames[CK_NumCheckKinds];
319 
320   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
321   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
322   void checkNewAllocator(const CXXAllocatorCall &Call, CheckerContext &C) const;
323   void checkPostObjCMessage(const ObjCMethodCall &Call, CheckerContext &C) const;
324   void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
325   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
326   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
327   void checkEndFunction(const ReturnStmt *S, CheckerContext &C) const;
328   ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
329                             bool Assumption) const;
330   void checkLocation(SVal l, bool isLoad, const Stmt *S,
331                      CheckerContext &C) const;
332 
333   ProgramStateRef checkPointerEscape(ProgramStateRef State,
334                                     const InvalidatedSymbols &Escaped,
335                                     const CallEvent *Call,
336                                     PointerEscapeKind Kind) const;
337   ProgramStateRef checkConstPointerEscape(ProgramStateRef State,
338                                           const InvalidatedSymbols &Escaped,
339                                           const CallEvent *Call,
340                                           PointerEscapeKind Kind) const;
341 
342   void printState(raw_ostream &Out, ProgramStateRef State,
343                   const char *NL, const char *Sep) const override;
344 
345 private:
346   mutable std::unique_ptr<BugType> BT_DoubleFree[CK_NumCheckKinds];
347   mutable std::unique_ptr<BugType> BT_DoubleDelete;
348   mutable std::unique_ptr<BugType> BT_Leak[CK_NumCheckKinds];
349   mutable std::unique_ptr<BugType> BT_UseFree[CK_NumCheckKinds];
350   mutable std::unique_ptr<BugType> BT_BadFree[CK_NumCheckKinds];
351   mutable std::unique_ptr<BugType> BT_FreeAlloca[CK_NumCheckKinds];
352   mutable std::unique_ptr<BugType> BT_MismatchedDealloc;
353   mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds];
354   mutable std::unique_ptr<BugType> BT_UseZerroAllocated[CK_NumCheckKinds];
355 
356 #define CHECK_FN(NAME)                                                         \
357   void NAME(const CallEvent &Call, CheckerContext &C) const;
358 
359   CHECK_FN(checkFree)
360   CHECK_FN(checkIfNameIndex)
361   CHECK_FN(checkBasicAlloc)
362   CHECK_FN(checkKernelMalloc)
363   CHECK_FN(checkCalloc)
364   CHECK_FN(checkAlloca)
365   CHECK_FN(checkStrdup)
366   CHECK_FN(checkIfFreeNameIndex)
367   CHECK_FN(checkCXXNewOrCXXDelete)
368   CHECK_FN(checkGMalloc0)
369   CHECK_FN(checkGMemdup)
370   CHECK_FN(checkGMallocN)
371   CHECK_FN(checkGMallocN0)
372   CHECK_FN(checkReallocN)
373   CHECK_FN(checkOwnershipAttr)
374 
375   void checkRealloc(const CallEvent &Call, CheckerContext &C,
376                     bool ShouldFreeOnFail) const;
377 
378   using CheckFn = std::function<void(const MallocChecker *,
379                                      const CallEvent &Call, CheckerContext &C)>;
380 
381   const CallDescriptionMap<CheckFn> FreeingMemFnMap{
382       {{"free", 1}, &MallocChecker::checkFree},
383       {{"if_freenameindex", 1}, &MallocChecker::checkIfFreeNameIndex},
384       {{"kfree", 1}, &MallocChecker::checkFree},
385       {{"g_free", 1}, &MallocChecker::checkFree},
386   };
387 
388   bool isFreeingCall(const CallEvent &Call) const;
389 
390   CallDescriptionMap<CheckFn> AllocatingMemFnMap{
391       {{"alloca", 1}, &MallocChecker::checkAlloca},
392       {{"_alloca", 1}, &MallocChecker::checkAlloca},
393       {{"malloc", 1}, &MallocChecker::checkBasicAlloc},
394       {{"malloc", 3}, &MallocChecker::checkKernelMalloc},
395       {{"calloc", 2}, &MallocChecker::checkCalloc},
396       {{"valloc", 1}, &MallocChecker::checkBasicAlloc},
397       {{CDF_MaybeBuiltin, "strndup", 2}, &MallocChecker::checkStrdup},
398       {{CDF_MaybeBuiltin, "strdup", 1}, &MallocChecker::checkStrdup},
399       {{"_strdup", 1}, &MallocChecker::checkStrdup},
400       {{"kmalloc", 2}, &MallocChecker::checkKernelMalloc},
401       {{"if_nameindex", 1}, &MallocChecker::checkIfNameIndex},
402       {{CDF_MaybeBuiltin, "wcsdup", 1}, &MallocChecker::checkStrdup},
403       {{CDF_MaybeBuiltin, "_wcsdup", 1}, &MallocChecker::checkStrdup},
404       {{"g_malloc", 1}, &MallocChecker::checkBasicAlloc},
405       {{"g_malloc0", 1}, &MallocChecker::checkGMalloc0},
406       {{"g_try_malloc", 1}, &MallocChecker::checkBasicAlloc},
407       {{"g_try_malloc0", 1}, &MallocChecker::checkGMalloc0},
408       {{"g_memdup", 2}, &MallocChecker::checkGMemdup},
409       {{"g_malloc_n", 2}, &MallocChecker::checkGMallocN},
410       {{"g_malloc0_n", 2}, &MallocChecker::checkGMallocN0},
411       {{"g_try_malloc_n", 2}, &MallocChecker::checkGMallocN},
412       {{"g_try_malloc0_n", 2}, &MallocChecker::checkGMallocN0},
413   };
414 
415   CallDescriptionMap<CheckFn> ReallocatingMemFnMap{
416       {{"realloc", 2},
417        std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},
418       {{"reallocf", 2},
419        std::bind(&MallocChecker::checkRealloc, _1, _2, _3, true)},
420       {{"g_realloc", 2},
421        std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},
422       {{"g_try_realloc", 2},
423        std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},
424       {{"g_realloc_n", 3}, &MallocChecker::checkReallocN},
425       {{"g_try_realloc_n", 3}, &MallocChecker::checkReallocN},
426   };
427 
428   bool isMemCall(const CallEvent &Call) const;
429 
430   // TODO: Remove mutable by moving the initializtaion to the registry function.
431   mutable Optional<uint64_t> KernelZeroFlagVal;
432 
433   using KernelZeroSizePtrValueTy = Optional<int>;
434   /// Store the value of macro called `ZERO_SIZE_PTR`.
435   /// The value is initialized at first use, before first use the outer
436   /// Optional is empty, afterwards it contains another Optional that indicates
437   /// if the macro value could be determined, and if yes the value itself.
438   mutable Optional<KernelZeroSizePtrValueTy> KernelZeroSizePtrValue;
439 
440   /// Process C++ operator new()'s allocation, which is the part of C++
441   /// new-expression that goes before the constructor.
442   LLVM_NODISCARD
443   ProgramStateRef processNewAllocation(const CXXAllocatorCall &Call,
444                                        CheckerContext &C,
445                                        AllocationFamily Family) const;
446 
447   /// Perform a zero-allocation check.
448   ///
449   /// \param [in] Call The expression that allocates memory.
450   /// \param [in] IndexOfSizeArg Index of the argument that specifies the size
451   ///   of the memory that needs to be allocated. E.g. for malloc, this would be
452   ///   0.
453   /// \param [in] RetVal Specifies the newly allocated pointer value;
454   ///   if unspecified, the value of expression \p E is used.
455   LLVM_NODISCARD
456   static ProgramStateRef ProcessZeroAllocCheck(const CallEvent &Call,
457                                                const unsigned IndexOfSizeArg,
458                                                ProgramStateRef State,
459                                                Optional<SVal> RetVal = None);
460 
461   /// Model functions with the ownership_returns attribute.
462   ///
463   /// User-defined function may have the ownership_returns attribute, which
464   /// annotates that the function returns with an object that was allocated on
465   /// the heap, and passes the ownertship to the callee.
466   ///
467   ///   void __attribute((ownership_returns(malloc, 1))) *my_malloc(size_t);
468   ///
469   /// It has two parameters:
470   ///   - first: name of the resource (e.g. 'malloc')
471   ///   - (OPTIONAL) second: size of the allocated region
472   ///
473   /// \param [in] Call The expression that allocates memory.
474   /// \param [in] Att The ownership_returns attribute.
475   /// \param [in] State The \c ProgramState right before allocation.
476   /// \returns The ProgramState right after allocation.
477   LLVM_NODISCARD
478   ProgramStateRef MallocMemReturnsAttr(CheckerContext &C, const CallEvent &Call,
479                                        const OwnershipAttr *Att,
480                                        ProgramStateRef State) const;
481 
482   /// Models memory allocation.
483   ///
484   /// \param [in] Call The expression that allocates memory.
485   /// \param [in] SizeEx Size of the memory that needs to be allocated.
486   /// \param [in] Init The value the allocated memory needs to be initialized.
487   /// with. For example, \c calloc initializes the allocated memory to 0,
488   /// malloc leaves it undefined.
489   /// \param [in] State The \c ProgramState right before allocation.
490   /// \returns The ProgramState right after allocation.
491   LLVM_NODISCARD
492   static ProgramStateRef MallocMemAux(CheckerContext &C, const CallEvent &Call,
493                                       const Expr *SizeEx, SVal Init,
494                                       ProgramStateRef State,
495                                       AllocationFamily Family);
496 
497   /// Models memory allocation.
498   ///
499   /// \param [in] Call The expression that allocates memory.
500   /// \param [in] Size Size of the memory that needs to be allocated.
501   /// \param [in] Init The value the allocated memory needs to be initialized.
502   /// with. For example, \c calloc initializes the allocated memory to 0,
503   /// malloc leaves it undefined.
504   /// \param [in] State The \c ProgramState right before allocation.
505   /// \returns The ProgramState right after allocation.
506   LLVM_NODISCARD
507   static ProgramStateRef MallocMemAux(CheckerContext &C, const CallEvent &Call,
508                                       SVal Size, SVal Init,
509                                       ProgramStateRef State,
510                                       AllocationFamily Family);
511 
512   // Check if this malloc() for special flags. At present that means M_ZERO or
513   // __GFP_ZERO (in which case, treat it like calloc).
514   LLVM_NODISCARD
515   llvm::Optional<ProgramStateRef>
516   performKernelMalloc(const CallEvent &Call, CheckerContext &C,
517                       const ProgramStateRef &State) const;
518 
519   /// Model functions with the ownership_takes and ownership_holds attributes.
520   ///
521   /// User-defined function may have the ownership_takes and/or ownership_holds
522   /// attributes, which annotates that the function frees the memory passed as a
523   /// parameter.
524   ///
525   ///   void __attribute((ownership_takes(malloc, 1))) my_free(void *);
526   ///   void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
527   ///
528   /// They have two parameters:
529   ///   - first: name of the resource (e.g. 'malloc')
530   ///   - second: index of the parameter the attribute applies to
531   ///
532   /// \param [in] Call The expression that frees memory.
533   /// \param [in] Att The ownership_takes or ownership_holds attribute.
534   /// \param [in] State The \c ProgramState right before allocation.
535   /// \returns The ProgramState right after deallocation.
536   LLVM_NODISCARD
537   ProgramStateRef FreeMemAttr(CheckerContext &C, const CallEvent &Call,
538                               const OwnershipAttr *Att,
539                               ProgramStateRef State) const;
540 
541   /// Models memory deallocation.
542   ///
543   /// \param [in] Call The expression that frees memory.
544   /// \param [in] State The \c ProgramState right before allocation.
545   /// \param [in] Num Index of the argument that needs to be freed. This is
546   ///   normally 0, but for custom free functions it may be different.
547   /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds
548   ///   attribute.
549   /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known
550   ///   to have been allocated, or in other words, the symbol to be freed was
551   ///   registered as allocated by this checker. In the following case, \c ptr
552   ///   isn't known to be allocated.
553   ///      void Haha(int *ptr) {
554   ///        ptr = realloc(ptr, 67);
555   ///        // ...
556   ///      }
557   /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function
558   ///   we're modeling returns with Null on failure.
559   /// \returns The ProgramState right after deallocation.
560   LLVM_NODISCARD
561   ProgramStateRef FreeMemAux(CheckerContext &C, const CallEvent &Call,
562                              ProgramStateRef State, unsigned Num, bool Hold,
563                              bool &IsKnownToBeAllocated,
564                              AllocationFamily Family,
565                              bool ReturnsNullOnFailure = false) const;
566 
567   /// Models memory deallocation.
568   ///
569   /// \param [in] ArgExpr The variable who's pointee needs to be freed.
570   /// \param [in] Call The expression that frees the memory.
571   /// \param [in] State The \c ProgramState right before allocation.
572   ///   normally 0, but for custom free functions it may be different.
573   /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds
574   ///   attribute.
575   /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known
576   ///   to have been allocated, or in other words, the symbol to be freed was
577   ///   registered as allocated by this checker. In the following case, \c ptr
578   ///   isn't known to be allocated.
579   ///      void Haha(int *ptr) {
580   ///        ptr = realloc(ptr, 67);
581   ///        // ...
582   ///      }
583   /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function
584   ///   we're modeling returns with Null on failure.
585   /// \returns The ProgramState right after deallocation.
586   LLVM_NODISCARD
587   ProgramStateRef FreeMemAux(CheckerContext &C, const Expr *ArgExpr,
588                              const CallEvent &Call, ProgramStateRef State,
589                              bool Hold, bool &IsKnownToBeAllocated,
590                              AllocationFamily Family,
591                              bool ReturnsNullOnFailure = false) const;
592 
593   // TODO: Needs some refactoring, as all other deallocation modeling
594   // functions are suffering from out parameters and messy code due to how
595   // realloc is handled.
596   //
597   /// Models memory reallocation.
598   ///
599   /// \param [in] Call The expression that reallocated memory
600   /// \param [in] ShouldFreeOnFail Whether if reallocation fails, the supplied
601   ///   memory should be freed.
602   /// \param [in] State The \c ProgramState right before reallocation.
603   /// \param [in] SuffixWithN Whether the reallocation function we're modeling
604   ///   has an '_n' suffix, such as g_realloc_n.
605   /// \returns The ProgramState right after reallocation.
606   LLVM_NODISCARD
607   ProgramStateRef ReallocMemAux(CheckerContext &C, const CallEvent &Call,
608                                 bool ShouldFreeOnFail, ProgramStateRef State,
609                                 AllocationFamily Family,
610                                 bool SuffixWithN = false) const;
611 
612   /// Evaluates the buffer size that needs to be allocated.
613   ///
614   /// \param [in] Blocks The amount of blocks that needs to be allocated.
615   /// \param [in] BlockBytes The size of a block.
616   /// \returns The symbolic value of \p Blocks * \p BlockBytes.
617   LLVM_NODISCARD
618   static SVal evalMulForBufferSize(CheckerContext &C, const Expr *Blocks,
619                                    const Expr *BlockBytes);
620 
621   /// Models zero initialized array allocation.
622   ///
623   /// \param [in] Call The expression that reallocated memory
624   /// \param [in] State The \c ProgramState right before reallocation.
625   /// \returns The ProgramState right after allocation.
626   LLVM_NODISCARD
627   static ProgramStateRef CallocMem(CheckerContext &C, const CallEvent &Call,
628                                    ProgramStateRef State);
629 
630   /// See if deallocation happens in a suspicious context. If so, escape the
631   /// pointers that otherwise would have been deallocated and return true.
632   bool suppressDeallocationsInSuspiciousContexts(const CallEvent &Call,
633                                                  CheckerContext &C) const;
634 
635   /// If in \p S  \p Sym is used, check whether \p Sym was already freed.
636   bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
637 
638   /// If in \p S \p Sym is used, check whether \p Sym was allocated as a zero
639   /// sized memory region.
640   void checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
641                              const Stmt *S) const;
642 
643   /// If in \p S \p Sym is being freed, check whether \p Sym was already freed.
644   bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const;
645 
646   /// Check if the function is known to free memory, or if it is
647   /// "interesting" and should be modeled explicitly.
648   ///
649   /// \param [out] EscapingSymbol A function might not free memory in general,
650   ///   but could be known to free a particular symbol. In this case, false is
651   ///   returned and the single escaping symbol is returned through the out
652   ///   parameter.
653   ///
654   /// We assume that pointers do not escape through calls to system functions
655   /// not handled by this checker.
656   bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent *Call,
657                                    ProgramStateRef State,
658                                    SymbolRef &EscapingSymbol) const;
659 
660   /// Implementation of the checkPointerEscape callbacks.
661   LLVM_NODISCARD
662   ProgramStateRef checkPointerEscapeAux(ProgramStateRef State,
663                                         const InvalidatedSymbols &Escaped,
664                                         const CallEvent *Call,
665                                         PointerEscapeKind Kind,
666                                         bool IsConstPointerEscape) const;
667 
668   // Implementation of the checkPreStmt and checkEndFunction callbacks.
669   void checkEscapeOnReturn(const ReturnStmt *S, CheckerContext &C) const;
670 
671   ///@{
672   /// Tells if a given family/call/symbol is tracked by the current checker.
673   /// Sets CheckKind to the kind of the checker responsible for this
674   /// family/call/symbol.
675   Optional<CheckKind> getCheckIfTracked(AllocationFamily Family,
676                                         bool IsALeakCheck = false) const;
677 
678   Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
679                                         bool IsALeakCheck = false) const;
680   ///@}
681   static bool SummarizeValue(raw_ostream &os, SVal V);
682   static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
683 
684   void HandleNonHeapDealloc(CheckerContext &C, SVal ArgVal, SourceRange Range,
685                             const Expr *DeallocExpr,
686                             AllocationFamily Family) const;
687 
688   void HandleFreeAlloca(CheckerContext &C, SVal ArgVal,
689                         SourceRange Range) const;
690 
691   void HandleMismatchedDealloc(CheckerContext &C, SourceRange Range,
692                                const Expr *DeallocExpr, const RefState *RS,
693                                SymbolRef Sym, bool OwnershipTransferred) const;
694 
695   void HandleOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
696                         const Expr *DeallocExpr, AllocationFamily Family,
697                         const Expr *AllocExpr = nullptr) const;
698 
699   void HandleUseAfterFree(CheckerContext &C, SourceRange Range,
700                           SymbolRef Sym) const;
701 
702   void HandleDoubleFree(CheckerContext &C, SourceRange Range, bool Released,
703                         SymbolRef Sym, SymbolRef PrevSym) const;
704 
705   void HandleDoubleDelete(CheckerContext &C, SymbolRef Sym) const;
706 
707   void HandleUseZeroAlloc(CheckerContext &C, SourceRange Range,
708                           SymbolRef Sym) const;
709 
710   void HandleFunctionPtrFree(CheckerContext &C, SVal ArgVal, SourceRange Range,
711                              const Expr *FreeExpr,
712                              AllocationFamily Family) const;
713 
714   /// Find the location of the allocation for Sym on the path leading to the
715   /// exploded node N.
716   static LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
717                                     CheckerContext &C);
718 
719   void HandleLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const;
720 
721   /// Test if value in ArgVal equals to value in macro `ZERO_SIZE_PTR`.
722   bool isArgZERO_SIZE_PTR(ProgramStateRef State, CheckerContext &C,
723                           SVal ArgVal) const;
724 };
725 
726 //===----------------------------------------------------------------------===//
727 // Definition of MallocBugVisitor.
728 //===----------------------------------------------------------------------===//
729 
730 /// The bug visitor which allows us to print extra diagnostics along the
731 /// BugReport path. For example, showing the allocation site of the leaked
732 /// region.
733 class MallocBugVisitor final : public BugReporterVisitor {
734 protected:
735   enum NotificationMode { Normal, ReallocationFailed };
736 
737   // The allocated region symbol tracked by the main analysis.
738   SymbolRef Sym;
739 
740   // The mode we are in, i.e. what kind of diagnostics will be emitted.
741   NotificationMode Mode;
742 
743   // A symbol from when the primary region should have been reallocated.
744   SymbolRef FailedReallocSymbol;
745 
746   // A C++ destructor stack frame in which memory was released. Used for
747   // miscellaneous false positive suppression.
748   const StackFrameContext *ReleaseDestructorLC;
749 
750   bool IsLeak;
751 
752 public:
MallocBugVisitor(SymbolRef S,bool isLeak=false)753   MallocBugVisitor(SymbolRef S, bool isLeak = false)
754       : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr),
755         ReleaseDestructorLC(nullptr), IsLeak(isLeak) {}
756 
getTag()757   static void *getTag() {
758     static int Tag = 0;
759     return &Tag;
760   }
761 
Profile(llvm::FoldingSetNodeID & ID) const762   void Profile(llvm::FoldingSetNodeID &ID) const override {
763     ID.AddPointer(getTag());
764     ID.AddPointer(Sym);
765   }
766 
767   /// Did not track -> allocated. Other state (released) -> allocated.
isAllocated(const RefState * RSCurr,const RefState * RSPrev,const Stmt * Stmt)768   static inline bool isAllocated(const RefState *RSCurr, const RefState *RSPrev,
769                                  const Stmt *Stmt) {
770     return (Stmt && (isa<CallExpr>(Stmt) || isa<CXXNewExpr>(Stmt)) &&
771             (RSCurr &&
772              (RSCurr->isAllocated() || RSCurr->isAllocatedOfSizeZero())) &&
773             (!RSPrev ||
774              !(RSPrev->isAllocated() || RSPrev->isAllocatedOfSizeZero())));
775   }
776 
777   /// Did not track -> released. Other state (allocated) -> released.
778   /// The statement associated with the release might be missing.
isReleased(const RefState * RSCurr,const RefState * RSPrev,const Stmt * Stmt)779   static inline bool isReleased(const RefState *RSCurr, const RefState *RSPrev,
780                                 const Stmt *Stmt) {
781     bool IsReleased =
782         (RSCurr && RSCurr->isReleased()) && (!RSPrev || !RSPrev->isReleased());
783     assert(!IsReleased ||
784            (Stmt && (isa<CallExpr>(Stmt) || isa<CXXDeleteExpr>(Stmt))) ||
785            (!Stmt && RSCurr->getAllocationFamily() == AF_InnerBuffer));
786     return IsReleased;
787   }
788 
789   /// Did not track -> relinquished. Other state (allocated) -> relinquished.
isRelinquished(const RefState * RSCurr,const RefState * RSPrev,const Stmt * Stmt)790   static inline bool isRelinquished(const RefState *RSCurr,
791                                     const RefState *RSPrev, const Stmt *Stmt) {
792     return (Stmt &&
793             (isa<CallExpr>(Stmt) || isa<ObjCMessageExpr>(Stmt) ||
794              isa<ObjCPropertyRefExpr>(Stmt)) &&
795             (RSCurr && RSCurr->isRelinquished()) &&
796             (!RSPrev || !RSPrev->isRelinquished()));
797   }
798 
799   /// If the expression is not a call, and the state change is
800   /// released -> allocated, it must be the realloc return value
801   /// check. If we have to handle more cases here, it might be cleaner just
802   /// to track this extra bit in the state itself.
hasReallocFailed(const RefState * RSCurr,const RefState * RSPrev,const Stmt * Stmt)803   static inline bool hasReallocFailed(const RefState *RSCurr,
804                                       const RefState *RSPrev,
805                                       const Stmt *Stmt) {
806     return ((!Stmt || !isa<CallExpr>(Stmt)) &&
807             (RSCurr &&
808              (RSCurr->isAllocated() || RSCurr->isAllocatedOfSizeZero())) &&
809             (RSPrev &&
810              !(RSPrev->isAllocated() || RSPrev->isAllocatedOfSizeZero())));
811   }
812 
813   PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
814                                    BugReporterContext &BRC,
815                                    PathSensitiveBugReport &BR) override;
816 
getEndPath(BugReporterContext & BRC,const ExplodedNode * EndPathNode,PathSensitiveBugReport & BR)817   PathDiagnosticPieceRef getEndPath(BugReporterContext &BRC,
818                                     const ExplodedNode *EndPathNode,
819                                     PathSensitiveBugReport &BR) override {
820     if (!IsLeak)
821       return nullptr;
822 
823     PathDiagnosticLocation L = BR.getLocation();
824     // Do not add the statement itself as a range in case of leak.
825     return std::make_shared<PathDiagnosticEventPiece>(L, BR.getDescription(),
826                                                       false);
827   }
828 
829 private:
830   class StackHintGeneratorForReallocationFailed
831       : public StackHintGeneratorForSymbol {
832   public:
StackHintGeneratorForReallocationFailed(SymbolRef S,StringRef M)833     StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
834         : StackHintGeneratorForSymbol(S, M) {}
835 
getMessageForArg(const Expr * ArgE,unsigned ArgIndex)836     std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) override {
837       // Printed parameters start at 1, not 0.
838       ++ArgIndex;
839 
840       SmallString<200> buf;
841       llvm::raw_svector_ostream os(buf);
842 
843       os << "Reallocation of " << ArgIndex << llvm::getOrdinalSuffix(ArgIndex)
844          << " parameter failed";
845 
846       return std::string(os.str());
847     }
848 
getMessageForReturn(const CallExpr * CallExpr)849     std::string getMessageForReturn(const CallExpr *CallExpr) override {
850       return "Reallocation of returned value failed";
851     }
852   };
853 };
854 
855 } // end anonymous namespace
856 
857 // A map from the freed symbol to the symbol representing the return value of
858 // the free function.
859 REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue, SymbolRef, SymbolRef)
860 
861 namespace {
862 class StopTrackingCallback final : public SymbolVisitor {
863   ProgramStateRef state;
864 
865 public:
StopTrackingCallback(ProgramStateRef st)866   StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {}
getState() const867   ProgramStateRef getState() const { return state; }
868 
VisitSymbol(SymbolRef sym)869   bool VisitSymbol(SymbolRef sym) override {
870     state = state->remove<RegionState>(sym);
871     return true;
872   }
873 };
874 } // end anonymous namespace
875 
isStandardNewDelete(const FunctionDecl * FD)876 static bool isStandardNewDelete(const FunctionDecl *FD) {
877   if (!FD)
878     return false;
879 
880   OverloadedOperatorKind Kind = FD->getOverloadedOperator();
881   if (Kind != OO_New && Kind != OO_Array_New && Kind != OO_Delete &&
882       Kind != OO_Array_Delete)
883     return false;
884 
885   // This is standard if and only if it's not defined in a user file.
886   SourceLocation L = FD->getLocation();
887   // If the header for operator delete is not included, it's still defined
888   // in an invalid source location. Check to make sure we don't crash.
889   return !L.isValid() ||
890          FD->getASTContext().getSourceManager().isInSystemHeader(L);
891 }
892 
893 //===----------------------------------------------------------------------===//
894 // Methods of MallocChecker and MallocBugVisitor.
895 //===----------------------------------------------------------------------===//
896 
isFreeingCall(const CallEvent & Call) const897 bool MallocChecker::isFreeingCall(const CallEvent &Call) const {
898   if (FreeingMemFnMap.lookup(Call) || ReallocatingMemFnMap.lookup(Call))
899     return true;
900 
901   const auto *Func = dyn_cast<FunctionDecl>(Call.getDecl());
902   if (Func && Func->hasAttrs()) {
903     for (const auto *I : Func->specific_attrs<OwnershipAttr>()) {
904       OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
905       if (OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds)
906         return true;
907     }
908   }
909   return false;
910 }
911 
isMemCall(const CallEvent & Call) const912 bool MallocChecker::isMemCall(const CallEvent &Call) const {
913   if (FreeingMemFnMap.lookup(Call) || AllocatingMemFnMap.lookup(Call) ||
914       ReallocatingMemFnMap.lookup(Call))
915     return true;
916 
917   if (!ShouldIncludeOwnershipAnnotatedFunctions)
918     return false;
919 
920   const auto *Func = dyn_cast<FunctionDecl>(Call.getDecl());
921   return Func && Func->hasAttr<OwnershipAttr>();
922 }
923 
924 llvm::Optional<ProgramStateRef>
performKernelMalloc(const CallEvent & Call,CheckerContext & C,const ProgramStateRef & State) const925 MallocChecker::performKernelMalloc(const CallEvent &Call, CheckerContext &C,
926                                    const ProgramStateRef &State) const {
927   // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels:
928   //
929   // void *malloc(unsigned long size, struct malloc_type *mtp, int flags);
930   //
931   // One of the possible flags is M_ZERO, which means 'give me back an
932   // allocation which is already zeroed', like calloc.
933 
934   // 2-argument kmalloc(), as used in the Linux kernel:
935   //
936   // void *kmalloc(size_t size, gfp_t flags);
937   //
938   // Has the similar flag value __GFP_ZERO.
939 
940   // This logic is largely cloned from O_CREAT in UnixAPIChecker, maybe some
941   // code could be shared.
942 
943   ASTContext &Ctx = C.getASTContext();
944   llvm::Triple::OSType OS = Ctx.getTargetInfo().getTriple().getOS();
945 
946   if (!KernelZeroFlagVal.hasValue()) {
947     if (OS == llvm::Triple::FreeBSD)
948       KernelZeroFlagVal = 0x0100;
949     else if (OS == llvm::Triple::NetBSD)
950       KernelZeroFlagVal = 0x0002;
951     else if (OS == llvm::Triple::OpenBSD)
952       KernelZeroFlagVal = 0x0008;
953     else if (OS == llvm::Triple::Linux)
954       // __GFP_ZERO
955       KernelZeroFlagVal = 0x8000;
956     else
957       // FIXME: We need a more general way of getting the M_ZERO value.
958       // See also: O_CREAT in UnixAPIChecker.cpp.
959 
960       // Fall back to normal malloc behavior on platforms where we don't
961       // know M_ZERO.
962       return None;
963   }
964 
965   // We treat the last argument as the flags argument, and callers fall-back to
966   // normal malloc on a None return. This works for the FreeBSD kernel malloc
967   // as well as Linux kmalloc.
968   if (Call.getNumArgs() < 2)
969     return None;
970 
971   const Expr *FlagsEx = Call.getArgExpr(Call.getNumArgs() - 1);
972   const SVal V = C.getSVal(FlagsEx);
973   if (!V.getAs<NonLoc>()) {
974     // The case where 'V' can be a location can only be due to a bad header,
975     // so in this case bail out.
976     return None;
977   }
978 
979   NonLoc Flags = V.castAs<NonLoc>();
980   NonLoc ZeroFlag = C.getSValBuilder()
981       .makeIntVal(KernelZeroFlagVal.getValue(), FlagsEx->getType())
982       .castAs<NonLoc>();
983   SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN(State, BO_And,
984                                                       Flags, ZeroFlag,
985                                                       FlagsEx->getType());
986   if (MaskedFlagsUC.isUnknownOrUndef())
987     return None;
988   DefinedSVal MaskedFlags = MaskedFlagsUC.castAs<DefinedSVal>();
989 
990   // Check if maskedFlags is non-zero.
991   ProgramStateRef TrueState, FalseState;
992   std::tie(TrueState, FalseState) = State->assume(MaskedFlags);
993 
994   // If M_ZERO is set, treat this like calloc (initialized).
995   if (TrueState && !FalseState) {
996     SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy);
997     return MallocMemAux(C, Call, Call.getArgExpr(0), ZeroVal, TrueState,
998                         AF_Malloc);
999   }
1000 
1001   return None;
1002 }
1003 
evalMulForBufferSize(CheckerContext & C,const Expr * Blocks,const Expr * BlockBytes)1004 SVal MallocChecker::evalMulForBufferSize(CheckerContext &C, const Expr *Blocks,
1005                                          const Expr *BlockBytes) {
1006   SValBuilder &SB = C.getSValBuilder();
1007   SVal BlocksVal = C.getSVal(Blocks);
1008   SVal BlockBytesVal = C.getSVal(BlockBytes);
1009   ProgramStateRef State = C.getState();
1010   SVal TotalSize = SB.evalBinOp(State, BO_Mul, BlocksVal, BlockBytesVal,
1011                                 SB.getContext().getSizeType());
1012   return TotalSize;
1013 }
1014 
checkBasicAlloc(const CallEvent & Call,CheckerContext & C) const1015 void MallocChecker::checkBasicAlloc(const CallEvent &Call,
1016                                     CheckerContext &C) const {
1017   ProgramStateRef State = C.getState();
1018   State = MallocMemAux(C, Call, Call.getArgExpr(0), UndefinedVal(), State,
1019                        AF_Malloc);
1020   State = ProcessZeroAllocCheck(Call, 0, State);
1021   C.addTransition(State);
1022 }
1023 
checkKernelMalloc(const CallEvent & Call,CheckerContext & C) const1024 void MallocChecker::checkKernelMalloc(const CallEvent &Call,
1025                                       CheckerContext &C) const {
1026   ProgramStateRef State = C.getState();
1027   llvm::Optional<ProgramStateRef> MaybeState =
1028       performKernelMalloc(Call, C, State);
1029   if (MaybeState.hasValue())
1030     State = MaybeState.getValue();
1031   else
1032     State = MallocMemAux(C, Call, Call.getArgExpr(0), UndefinedVal(), State,
1033                          AF_Malloc);
1034   C.addTransition(State);
1035 }
1036 
isStandardRealloc(const CallEvent & Call)1037 static bool isStandardRealloc(const CallEvent &Call) {
1038   const FunctionDecl *FD = dyn_cast<FunctionDecl>(Call.getDecl());
1039   assert(FD);
1040   ASTContext &AC = FD->getASTContext();
1041 
1042   if (isa<CXXMethodDecl>(FD))
1043     return false;
1044 
1045   return FD->getDeclaredReturnType().getDesugaredType(AC) == AC.VoidPtrTy &&
1046          FD->getParamDecl(0)->getType().getDesugaredType(AC) == AC.VoidPtrTy &&
1047          FD->getParamDecl(1)->getType().getDesugaredType(AC) ==
1048              AC.getSizeType();
1049 }
1050 
isGRealloc(const CallEvent & Call)1051 static bool isGRealloc(const CallEvent &Call) {
1052   const FunctionDecl *FD = dyn_cast<FunctionDecl>(Call.getDecl());
1053   assert(FD);
1054   ASTContext &AC = FD->getASTContext();
1055 
1056   if (isa<CXXMethodDecl>(FD))
1057     return false;
1058 
1059   return FD->getDeclaredReturnType().getDesugaredType(AC) == AC.VoidPtrTy &&
1060          FD->getParamDecl(0)->getType().getDesugaredType(AC) == AC.VoidPtrTy &&
1061          FD->getParamDecl(1)->getType().getDesugaredType(AC) ==
1062              AC.UnsignedLongTy;
1063 }
1064 
checkRealloc(const CallEvent & Call,CheckerContext & C,bool ShouldFreeOnFail) const1065 void MallocChecker::checkRealloc(const CallEvent &Call, CheckerContext &C,
1066                                  bool ShouldFreeOnFail) const {
1067   // HACK: CallDescription currently recognizes non-standard realloc functions
1068   // as standard because it doesn't check the type, or wether its a non-method
1069   // function. This should be solved by making CallDescription smarter.
1070   // Mind that this came from a bug report, and all other functions suffer from
1071   // this.
1072   // https://bugs.llvm.org/show_bug.cgi?id=46253
1073   if (!isStandardRealloc(Call) && !isGRealloc(Call))
1074     return;
1075   ProgramStateRef State = C.getState();
1076   State = ReallocMemAux(C, Call, ShouldFreeOnFail, State, AF_Malloc);
1077   State = ProcessZeroAllocCheck(Call, 1, State);
1078   C.addTransition(State);
1079 }
1080 
checkCalloc(const CallEvent & Call,CheckerContext & C) const1081 void MallocChecker::checkCalloc(const CallEvent &Call,
1082                                 CheckerContext &C) const {
1083   ProgramStateRef State = C.getState();
1084   State = CallocMem(C, Call, State);
1085   State = ProcessZeroAllocCheck(Call, 0, State);
1086   State = ProcessZeroAllocCheck(Call, 1, State);
1087   C.addTransition(State);
1088 }
1089 
checkFree(const CallEvent & Call,CheckerContext & C) const1090 void MallocChecker::checkFree(const CallEvent &Call, CheckerContext &C) const {
1091   ProgramStateRef State = C.getState();
1092   bool IsKnownToBeAllocatedMemory = false;
1093   if (suppressDeallocationsInSuspiciousContexts(Call, C))
1094     return;
1095   State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory,
1096                      AF_Malloc);
1097   C.addTransition(State);
1098 }
1099 
checkAlloca(const CallEvent & Call,CheckerContext & C) const1100 void MallocChecker::checkAlloca(const CallEvent &Call,
1101                                 CheckerContext &C) const {
1102   ProgramStateRef State = C.getState();
1103   State = MallocMemAux(C, Call, Call.getArgExpr(0), UndefinedVal(), State,
1104                        AF_Alloca);
1105   State = ProcessZeroAllocCheck(Call, 0, State);
1106   C.addTransition(State);
1107 }
1108 
checkStrdup(const CallEvent & Call,CheckerContext & C) const1109 void MallocChecker::checkStrdup(const CallEvent &Call,
1110                                 CheckerContext &C) const {
1111   ProgramStateRef State = C.getState();
1112   const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
1113   if (!CE)
1114     return;
1115   State = MallocUpdateRefState(C, CE, State, AF_Malloc);
1116 
1117   C.addTransition(State);
1118 }
1119 
checkIfNameIndex(const CallEvent & Call,CheckerContext & C) const1120 void MallocChecker::checkIfNameIndex(const CallEvent &Call,
1121                                      CheckerContext &C) const {
1122   ProgramStateRef State = C.getState();
1123   // Should we model this differently? We can allocate a fixed number of
1124   // elements with zeros in the last one.
1125   State =
1126       MallocMemAux(C, Call, UnknownVal(), UnknownVal(), State, AF_IfNameIndex);
1127 
1128   C.addTransition(State);
1129 }
1130 
checkIfFreeNameIndex(const CallEvent & Call,CheckerContext & C) const1131 void MallocChecker::checkIfFreeNameIndex(const CallEvent &Call,
1132                                          CheckerContext &C) const {
1133   ProgramStateRef State = C.getState();
1134   bool IsKnownToBeAllocatedMemory = false;
1135   State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory,
1136                      AF_IfNameIndex);
1137   C.addTransition(State);
1138 }
1139 
checkCXXNewOrCXXDelete(const CallEvent & Call,CheckerContext & C) const1140 void MallocChecker::checkCXXNewOrCXXDelete(const CallEvent &Call,
1141                                            CheckerContext &C) const {
1142   ProgramStateRef State = C.getState();
1143   bool IsKnownToBeAllocatedMemory = false;
1144   const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
1145   if (!CE)
1146     return;
1147 
1148   assert(isStandardNewDelete(Call));
1149 
1150   // Process direct calls to operator new/new[]/delete/delete[] functions
1151   // as distinct from new/new[]/delete/delete[] expressions that are
1152   // processed by the checkPostStmt callbacks for CXXNewExpr and
1153   // CXXDeleteExpr.
1154   const FunctionDecl *FD = C.getCalleeDecl(CE);
1155   switch (FD->getOverloadedOperator()) {
1156   case OO_New:
1157     State =
1158         MallocMemAux(C, Call, CE->getArg(0), UndefinedVal(), State, AF_CXXNew);
1159     State = ProcessZeroAllocCheck(Call, 0, State);
1160     break;
1161   case OO_Array_New:
1162     State = MallocMemAux(C, Call, CE->getArg(0), UndefinedVal(), State,
1163                          AF_CXXNewArray);
1164     State = ProcessZeroAllocCheck(Call, 0, State);
1165     break;
1166   case OO_Delete:
1167     State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory,
1168                        AF_CXXNew);
1169     break;
1170   case OO_Array_Delete:
1171     State = FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocatedMemory,
1172                        AF_CXXNewArray);
1173     break;
1174   default:
1175     llvm_unreachable("not a new/delete operator");
1176   }
1177 
1178   C.addTransition(State);
1179 }
1180 
checkGMalloc0(const CallEvent & Call,CheckerContext & C) const1181 void MallocChecker::checkGMalloc0(const CallEvent &Call,
1182                                   CheckerContext &C) const {
1183   ProgramStateRef State = C.getState();
1184   SValBuilder &svalBuilder = C.getSValBuilder();
1185   SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
1186   State = MallocMemAux(C, Call, Call.getArgExpr(0), zeroVal, State, AF_Malloc);
1187   State = ProcessZeroAllocCheck(Call, 0, State);
1188   C.addTransition(State);
1189 }
1190 
checkGMemdup(const CallEvent & Call,CheckerContext & C) const1191 void MallocChecker::checkGMemdup(const CallEvent &Call,
1192                                  CheckerContext &C) const {
1193   ProgramStateRef State = C.getState();
1194   State = MallocMemAux(C, Call, Call.getArgExpr(1), UndefinedVal(), State,
1195                        AF_Malloc);
1196   State = ProcessZeroAllocCheck(Call, 1, State);
1197   C.addTransition(State);
1198 }
1199 
checkGMallocN(const CallEvent & Call,CheckerContext & C) const1200 void MallocChecker::checkGMallocN(const CallEvent &Call,
1201                                   CheckerContext &C) const {
1202   ProgramStateRef State = C.getState();
1203   SVal Init = UndefinedVal();
1204   SVal TotalSize = evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1));
1205   State = MallocMemAux(C, Call, TotalSize, Init, State, AF_Malloc);
1206   State = ProcessZeroAllocCheck(Call, 0, State);
1207   State = ProcessZeroAllocCheck(Call, 1, State);
1208   C.addTransition(State);
1209 }
1210 
checkGMallocN0(const CallEvent & Call,CheckerContext & C) const1211 void MallocChecker::checkGMallocN0(const CallEvent &Call,
1212                                    CheckerContext &C) const {
1213   ProgramStateRef State = C.getState();
1214   SValBuilder &SB = C.getSValBuilder();
1215   SVal Init = SB.makeZeroVal(SB.getContext().CharTy);
1216   SVal TotalSize = evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1));
1217   State = MallocMemAux(C, Call, TotalSize, Init, State, AF_Malloc);
1218   State = ProcessZeroAllocCheck(Call, 0, State);
1219   State = ProcessZeroAllocCheck(Call, 1, State);
1220   C.addTransition(State);
1221 }
1222 
checkReallocN(const CallEvent & Call,CheckerContext & C) const1223 void MallocChecker::checkReallocN(const CallEvent &Call,
1224                                   CheckerContext &C) const {
1225   ProgramStateRef State = C.getState();
1226   State = ReallocMemAux(C, Call, /*ShouldFreeOnFail=*/false, State, AF_Malloc,
1227                         /*SuffixWithN=*/true);
1228   State = ProcessZeroAllocCheck(Call, 1, State);
1229   State = ProcessZeroAllocCheck(Call, 2, State);
1230   C.addTransition(State);
1231 }
1232 
checkOwnershipAttr(const CallEvent & Call,CheckerContext & C) const1233 void MallocChecker::checkOwnershipAttr(const CallEvent &Call,
1234                                        CheckerContext &C) const {
1235   ProgramStateRef State = C.getState();
1236   const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
1237   if (!CE)
1238     return;
1239   const FunctionDecl *FD = C.getCalleeDecl(CE);
1240   if (!FD)
1241     return;
1242   if (ShouldIncludeOwnershipAnnotatedFunctions ||
1243       ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
1244     // Check all the attributes, if there are any.
1245     // There can be multiple of these attributes.
1246     if (FD->hasAttrs())
1247       for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
1248         switch (I->getOwnKind()) {
1249         case OwnershipAttr::Returns:
1250           State = MallocMemReturnsAttr(C, Call, I, State);
1251           break;
1252         case OwnershipAttr::Takes:
1253         case OwnershipAttr::Holds:
1254           State = FreeMemAttr(C, Call, I, State);
1255           break;
1256         }
1257       }
1258   }
1259   C.addTransition(State);
1260 }
1261 
checkPostCall(const CallEvent & Call,CheckerContext & C) const1262 void MallocChecker::checkPostCall(const CallEvent &Call,
1263                                   CheckerContext &C) const {
1264   if (C.wasInlined)
1265     return;
1266   if (!Call.getOriginExpr())
1267     return;
1268 
1269   ProgramStateRef State = C.getState();
1270 
1271   if (const CheckFn *Callback = FreeingMemFnMap.lookup(Call)) {
1272     (*Callback)(this, Call, C);
1273     return;
1274   }
1275 
1276   if (const CheckFn *Callback = AllocatingMemFnMap.lookup(Call)) {
1277     (*Callback)(this, Call, C);
1278     return;
1279   }
1280 
1281   if (const CheckFn *Callback = ReallocatingMemFnMap.lookup(Call)) {
1282     (*Callback)(this, Call, C);
1283     return;
1284   }
1285 
1286   if (isStandardNewDelete(Call)) {
1287     checkCXXNewOrCXXDelete(Call, C);
1288     return;
1289   }
1290 
1291   checkOwnershipAttr(Call, C);
1292 }
1293 
1294 // Performs a 0-sized allocations check.
ProcessZeroAllocCheck(const CallEvent & Call,const unsigned IndexOfSizeArg,ProgramStateRef State,Optional<SVal> RetVal)1295 ProgramStateRef MallocChecker::ProcessZeroAllocCheck(
1296     const CallEvent &Call, const unsigned IndexOfSizeArg, ProgramStateRef State,
1297     Optional<SVal> RetVal) {
1298   if (!State)
1299     return nullptr;
1300 
1301   if (!RetVal)
1302     RetVal = Call.getReturnValue();
1303 
1304   const Expr *Arg = nullptr;
1305 
1306   if (const CallExpr *CE = dyn_cast<CallExpr>(Call.getOriginExpr())) {
1307     Arg = CE->getArg(IndexOfSizeArg);
1308   } else if (const CXXNewExpr *NE =
1309                  dyn_cast<CXXNewExpr>(Call.getOriginExpr())) {
1310     if (NE->isArray()) {
1311       Arg = *NE->getArraySize();
1312     } else {
1313       return State;
1314     }
1315   } else
1316     llvm_unreachable("not a CallExpr or CXXNewExpr");
1317 
1318   assert(Arg);
1319 
1320   auto DefArgVal =
1321       State->getSVal(Arg, Call.getLocationContext()).getAs<DefinedSVal>();
1322 
1323   if (!DefArgVal)
1324     return State;
1325 
1326   // Check if the allocation size is 0.
1327   ProgramStateRef TrueState, FalseState;
1328   SValBuilder &SvalBuilder = State->getStateManager().getSValBuilder();
1329   DefinedSVal Zero =
1330       SvalBuilder.makeZeroVal(Arg->getType()).castAs<DefinedSVal>();
1331 
1332   std::tie(TrueState, FalseState) =
1333       State->assume(SvalBuilder.evalEQ(State, *DefArgVal, Zero));
1334 
1335   if (TrueState && !FalseState) {
1336     SymbolRef Sym = RetVal->getAsLocSymbol();
1337     if (!Sym)
1338       return State;
1339 
1340     const RefState *RS = State->get<RegionState>(Sym);
1341     if (RS) {
1342       if (RS->isAllocated())
1343         return TrueState->set<RegionState>(Sym,
1344                                           RefState::getAllocatedOfSizeZero(RS));
1345       else
1346         return State;
1347     } else {
1348       // Case of zero-size realloc. Historically 'realloc(ptr, 0)' is treated as
1349       // 'free(ptr)' and the returned value from 'realloc(ptr, 0)' is not
1350       // tracked. Add zero-reallocated Sym to the state to catch references
1351       // to zero-allocated memory.
1352       return TrueState->add<ReallocSizeZeroSymbols>(Sym);
1353     }
1354   }
1355 
1356   // Assume the value is non-zero going forward.
1357   assert(FalseState);
1358   return FalseState;
1359 }
1360 
getDeepPointeeType(QualType T)1361 static QualType getDeepPointeeType(QualType T) {
1362   QualType Result = T, PointeeType = T->getPointeeType();
1363   while (!PointeeType.isNull()) {
1364     Result = PointeeType;
1365     PointeeType = PointeeType->getPointeeType();
1366   }
1367   return Result;
1368 }
1369 
1370 /// \returns true if the constructor invoked by \p NE has an argument of a
1371 /// pointer/reference to a record type.
hasNonTrivialConstructorCall(const CXXNewExpr * NE)1372 static bool hasNonTrivialConstructorCall(const CXXNewExpr *NE) {
1373 
1374   const CXXConstructExpr *ConstructE = NE->getConstructExpr();
1375   if (!ConstructE)
1376     return false;
1377 
1378   if (!NE->getAllocatedType()->getAsCXXRecordDecl())
1379     return false;
1380 
1381   const CXXConstructorDecl *CtorD = ConstructE->getConstructor();
1382 
1383   // Iterate over the constructor parameters.
1384   for (const auto *CtorParam : CtorD->parameters()) {
1385 
1386     QualType CtorParamPointeeT = CtorParam->getType()->getPointeeType();
1387     if (CtorParamPointeeT.isNull())
1388       continue;
1389 
1390     CtorParamPointeeT = getDeepPointeeType(CtorParamPointeeT);
1391 
1392     if (CtorParamPointeeT->getAsCXXRecordDecl())
1393       return true;
1394   }
1395 
1396   return false;
1397 }
1398 
1399 ProgramStateRef
processNewAllocation(const CXXAllocatorCall & Call,CheckerContext & C,AllocationFamily Family) const1400 MallocChecker::processNewAllocation(const CXXAllocatorCall &Call,
1401                                     CheckerContext &C,
1402                                     AllocationFamily Family) const {
1403   if (!isStandardNewDelete(Call))
1404     return nullptr;
1405 
1406   const CXXNewExpr *NE = Call.getOriginExpr();
1407   const ParentMap &PM = C.getLocationContext()->getParentMap();
1408   ProgramStateRef State = C.getState();
1409 
1410   // Non-trivial constructors have a chance to escape 'this', but marking all
1411   // invocations of trivial constructors as escaped would cause too great of
1412   // reduction of true positives, so let's just do that for constructors that
1413   // have an argument of a pointer-to-record type.
1414   if (!PM.isConsumedExpr(NE) && hasNonTrivialConstructorCall(NE))
1415     return State;
1416 
1417   // The return value from operator new is bound to a specified initialization
1418   // value (if any) and we don't want to loose this value. So we call
1419   // MallocUpdateRefState() instead of MallocMemAux() which breaks the
1420   // existing binding.
1421   SVal Target = Call.getObjectUnderConstruction();
1422   State = MallocUpdateRefState(C, NE, State, Family, Target);
1423   State = ProcessZeroAllocCheck(Call, 0, State, Target);
1424   return State;
1425 }
1426 
checkNewAllocator(const CXXAllocatorCall & Call,CheckerContext & C) const1427 void MallocChecker::checkNewAllocator(const CXXAllocatorCall &Call,
1428                                       CheckerContext &C) const {
1429   if (!C.wasInlined) {
1430     ProgramStateRef State = processNewAllocation(
1431         Call, C,
1432         (Call.getOriginExpr()->isArray() ? AF_CXXNewArray : AF_CXXNew));
1433     C.addTransition(State);
1434   }
1435 }
1436 
isKnownDeallocObjCMethodName(const ObjCMethodCall & Call)1437 static bool isKnownDeallocObjCMethodName(const ObjCMethodCall &Call) {
1438   // If the first selector piece is one of the names below, assume that the
1439   // object takes ownership of the memory, promising to eventually deallocate it
1440   // with free().
1441   // Ex:  [NSData dataWithBytesNoCopy:bytes length:10];
1442   // (...unless a 'freeWhenDone' parameter is false, but that's checked later.)
1443   StringRef FirstSlot = Call.getSelector().getNameForSlot(0);
1444   return FirstSlot == "dataWithBytesNoCopy" ||
1445          FirstSlot == "initWithBytesNoCopy" ||
1446          FirstSlot == "initWithCharactersNoCopy";
1447 }
1448 
getFreeWhenDoneArg(const ObjCMethodCall & Call)1449 static Optional<bool> getFreeWhenDoneArg(const ObjCMethodCall &Call) {
1450   Selector S = Call.getSelector();
1451 
1452   // FIXME: We should not rely on fully-constrained symbols being folded.
1453   for (unsigned i = 1; i < S.getNumArgs(); ++i)
1454     if (S.getNameForSlot(i).equals("freeWhenDone"))
1455       return !Call.getArgSVal(i).isZeroConstant();
1456 
1457   return None;
1458 }
1459 
checkPostObjCMessage(const ObjCMethodCall & Call,CheckerContext & C) const1460 void MallocChecker::checkPostObjCMessage(const ObjCMethodCall &Call,
1461                                          CheckerContext &C) const {
1462   if (C.wasInlined)
1463     return;
1464 
1465   if (!isKnownDeallocObjCMethodName(Call))
1466     return;
1467 
1468   if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(Call))
1469     if (!*FreeWhenDone)
1470       return;
1471 
1472   if (Call.hasNonZeroCallbackArg())
1473     return;
1474 
1475   bool IsKnownToBeAllocatedMemory;
1476   ProgramStateRef State =
1477       FreeMemAux(C, Call.getArgExpr(0), Call, C.getState(),
1478                  /*Hold=*/true, IsKnownToBeAllocatedMemory, AF_Malloc,
1479                  /*RetNullOnFailure=*/true);
1480 
1481   C.addTransition(State);
1482 }
1483 
1484 ProgramStateRef
MallocMemReturnsAttr(CheckerContext & C,const CallEvent & Call,const OwnershipAttr * Att,ProgramStateRef State) const1485 MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallEvent &Call,
1486                                     const OwnershipAttr *Att,
1487                                     ProgramStateRef State) const {
1488   if (!State)
1489     return nullptr;
1490 
1491   if (Att->getModule()->getName() != "malloc")
1492     return nullptr;
1493 
1494   OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
1495   if (I != E) {
1496     return MallocMemAux(C, Call, Call.getArgExpr(I->getASTIndex()),
1497                         UndefinedVal(), State, AF_Malloc);
1498   }
1499   return MallocMemAux(C, Call, UnknownVal(), UndefinedVal(), State, AF_Malloc);
1500 }
1501 
MallocMemAux(CheckerContext & C,const CallEvent & Call,const Expr * SizeEx,SVal Init,ProgramStateRef State,AllocationFamily Family)1502 ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
1503                                             const CallEvent &Call,
1504                                             const Expr *SizeEx, SVal Init,
1505                                             ProgramStateRef State,
1506                                             AllocationFamily Family) {
1507   if (!State)
1508     return nullptr;
1509 
1510   assert(SizeEx);
1511   return MallocMemAux(C, Call, C.getSVal(SizeEx), Init, State, Family);
1512 }
1513 
MallocMemAux(CheckerContext & C,const CallEvent & Call,SVal Size,SVal Init,ProgramStateRef State,AllocationFamily Family)1514 ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
1515                                             const CallEvent &Call, SVal Size,
1516                                             SVal Init, ProgramStateRef State,
1517                                             AllocationFamily Family) {
1518   if (!State)
1519     return nullptr;
1520 
1521   const Expr *CE = Call.getOriginExpr();
1522 
1523   // We expect the malloc functions to return a pointer.
1524   if (!Loc::isLocType(CE->getType()))
1525     return nullptr;
1526 
1527   // Bind the return value to the symbolic value from the heap region.
1528   // TODO: We could rewrite post visit to eval call; 'malloc' does not have
1529   // side effects other than what we model here.
1530   unsigned Count = C.blockCount();
1531   SValBuilder &svalBuilder = C.getSValBuilder();
1532   const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
1533   DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
1534       .castAs<DefinedSVal>();
1535   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
1536 
1537   // Fill the region with the initialization value.
1538   State = State->bindDefaultInitial(RetVal, Init, LCtx);
1539 
1540   // Set the region's extent.
1541   State = setDynamicExtent(State, RetVal.getAsRegion(),
1542                            Size.castAs<DefinedOrUnknownSVal>(), svalBuilder);
1543 
1544   return MallocUpdateRefState(C, CE, State, Family);
1545 }
1546 
MallocUpdateRefState(CheckerContext & C,const Expr * E,ProgramStateRef State,AllocationFamily Family,Optional<SVal> RetVal)1547 static ProgramStateRef MallocUpdateRefState(CheckerContext &C, const Expr *E,
1548                                             ProgramStateRef State,
1549                                             AllocationFamily Family,
1550                                             Optional<SVal> RetVal) {
1551   if (!State)
1552     return nullptr;
1553 
1554   // Get the return value.
1555   if (!RetVal)
1556     RetVal = C.getSVal(E);
1557 
1558   // We expect the malloc functions to return a pointer.
1559   if (!RetVal->getAs<Loc>())
1560     return nullptr;
1561 
1562   SymbolRef Sym = RetVal->getAsLocSymbol();
1563   // This is a return value of a function that was not inlined, such as malloc()
1564   // or new(). We've checked that in the caller. Therefore, it must be a symbol.
1565   assert(Sym);
1566 
1567   // Set the symbol's state to Allocated.
1568   return State->set<RegionState>(Sym, RefState::getAllocated(Family, E));
1569 }
1570 
FreeMemAttr(CheckerContext & C,const CallEvent & Call,const OwnershipAttr * Att,ProgramStateRef State) const1571 ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
1572                                            const CallEvent &Call,
1573                                            const OwnershipAttr *Att,
1574                                            ProgramStateRef State) const {
1575   if (!State)
1576     return nullptr;
1577 
1578   if (Att->getModule()->getName() != "malloc")
1579     return nullptr;
1580 
1581   bool IsKnownToBeAllocated = false;
1582 
1583   for (const auto &Arg : Att->args()) {
1584     ProgramStateRef StateI =
1585         FreeMemAux(C, Call, State, Arg.getASTIndex(),
1586                    Att->getOwnKind() == OwnershipAttr::Holds,
1587                    IsKnownToBeAllocated, AF_Malloc);
1588     if (StateI)
1589       State = StateI;
1590   }
1591   return State;
1592 }
1593 
FreeMemAux(CheckerContext & C,const CallEvent & Call,ProgramStateRef State,unsigned Num,bool Hold,bool & IsKnownToBeAllocated,AllocationFamily Family,bool ReturnsNullOnFailure) const1594 ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
1595                                           const CallEvent &Call,
1596                                           ProgramStateRef State, unsigned Num,
1597                                           bool Hold, bool &IsKnownToBeAllocated,
1598                                           AllocationFamily Family,
1599                                           bool ReturnsNullOnFailure) const {
1600   if (!State)
1601     return nullptr;
1602 
1603   if (Call.getNumArgs() < (Num + 1))
1604     return nullptr;
1605 
1606   return FreeMemAux(C, Call.getArgExpr(Num), Call, State, Hold,
1607                     IsKnownToBeAllocated, Family, ReturnsNullOnFailure);
1608 }
1609 
1610 /// Checks if the previous call to free on the given symbol failed - if free
1611 /// failed, returns true. Also, returns the corresponding return value symbol.
didPreviousFreeFail(ProgramStateRef State,SymbolRef Sym,SymbolRef & RetStatusSymbol)1612 static bool didPreviousFreeFail(ProgramStateRef State,
1613                                 SymbolRef Sym, SymbolRef &RetStatusSymbol) {
1614   const SymbolRef *Ret = State->get<FreeReturnValue>(Sym);
1615   if (Ret) {
1616     assert(*Ret && "We should not store the null return symbol");
1617     ConstraintManager &CMgr = State->getConstraintManager();
1618     ConditionTruthVal FreeFailed = CMgr.isNull(State, *Ret);
1619     RetStatusSymbol = *Ret;
1620     return FreeFailed.isConstrainedTrue();
1621   }
1622   return false;
1623 }
1624 
printMemFnName(raw_ostream & os,CheckerContext & C,const Expr * E)1625 static bool printMemFnName(raw_ostream &os, CheckerContext &C, const Expr *E) {
1626   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1627     // FIXME: This doesn't handle indirect calls.
1628     const FunctionDecl *FD = CE->getDirectCallee();
1629     if (!FD)
1630       return false;
1631 
1632     os << *FD;
1633     if (!FD->isOverloadedOperator())
1634       os << "()";
1635     return true;
1636   }
1637 
1638   if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) {
1639     if (Msg->isInstanceMessage())
1640       os << "-";
1641     else
1642       os << "+";
1643     Msg->getSelector().print(os);
1644     return true;
1645   }
1646 
1647   if (const CXXNewExpr *NE = dyn_cast<CXXNewExpr>(E)) {
1648     os << "'"
1649        << getOperatorSpelling(NE->getOperatorNew()->getOverloadedOperator())
1650        << "'";
1651     return true;
1652   }
1653 
1654   if (const CXXDeleteExpr *DE = dyn_cast<CXXDeleteExpr>(E)) {
1655     os << "'"
1656        << getOperatorSpelling(DE->getOperatorDelete()->getOverloadedOperator())
1657        << "'";
1658     return true;
1659   }
1660 
1661   return false;
1662 }
1663 
printExpectedAllocName(raw_ostream & os,AllocationFamily Family)1664 static void printExpectedAllocName(raw_ostream &os, AllocationFamily Family) {
1665 
1666   switch(Family) {
1667     case AF_Malloc: os << "malloc()"; return;
1668     case AF_CXXNew: os << "'new'"; return;
1669     case AF_CXXNewArray: os << "'new[]'"; return;
1670     case AF_IfNameIndex: os << "'if_nameindex()'"; return;
1671     case AF_InnerBuffer: os << "container-specific allocator"; return;
1672     case AF_Alloca:
1673     case AF_None: llvm_unreachable("not a deallocation expression");
1674   }
1675 }
1676 
printExpectedDeallocName(raw_ostream & os,AllocationFamily Family)1677 static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family) {
1678   switch(Family) {
1679     case AF_Malloc: os << "free()"; return;
1680     case AF_CXXNew: os << "'delete'"; return;
1681     case AF_CXXNewArray: os << "'delete[]'"; return;
1682     case AF_IfNameIndex: os << "'if_freenameindex()'"; return;
1683     case AF_InnerBuffer: os << "container-specific deallocator"; return;
1684     case AF_Alloca:
1685     case AF_None: llvm_unreachable("suspicious argument");
1686   }
1687 }
1688 
FreeMemAux(CheckerContext & C,const Expr * ArgExpr,const CallEvent & Call,ProgramStateRef State,bool Hold,bool & IsKnownToBeAllocated,AllocationFamily Family,bool ReturnsNullOnFailure) const1689 ProgramStateRef MallocChecker::FreeMemAux(
1690     CheckerContext &C, const Expr *ArgExpr, const CallEvent &Call,
1691     ProgramStateRef State, bool Hold, bool &IsKnownToBeAllocated,
1692     AllocationFamily Family, bool ReturnsNullOnFailure) const {
1693 
1694   if (!State)
1695     return nullptr;
1696 
1697   SVal ArgVal = C.getSVal(ArgExpr);
1698   if (!ArgVal.getAs<DefinedOrUnknownSVal>())
1699     return nullptr;
1700   DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
1701 
1702   // Check for null dereferences.
1703   if (!location.getAs<Loc>())
1704     return nullptr;
1705 
1706   // The explicit NULL case, no operation is performed.
1707   ProgramStateRef notNullState, nullState;
1708   std::tie(notNullState, nullState) = State->assume(location);
1709   if (nullState && !notNullState)
1710     return nullptr;
1711 
1712   // Unknown values could easily be okay
1713   // Undefined values are handled elsewhere
1714   if (ArgVal.isUnknownOrUndef())
1715     return nullptr;
1716 
1717   const MemRegion *R = ArgVal.getAsRegion();
1718   const Expr *ParentExpr = Call.getOriginExpr();
1719 
1720   // NOTE: We detected a bug, but the checker under whose name we would emit the
1721   // error could be disabled. Generally speaking, the MallocChecker family is an
1722   // integral part of the Static Analyzer, and disabling any part of it should
1723   // only be done under exceptional circumstances, such as frequent false
1724   // positives. If this is the case, we can reasonably believe that there are
1725   // serious faults in our understanding of the source code, and even if we
1726   // don't emit an warning, we should terminate further analysis with a sink
1727   // node.
1728 
1729   // Nonlocs can't be freed, of course.
1730   // Non-region locations (labels and fixed addresses) also shouldn't be freed.
1731   if (!R) {
1732     // Exception:
1733     // If the macro ZERO_SIZE_PTR is defined, this could be a kernel source
1734     // code. In that case, the ZERO_SIZE_PTR defines a special value used for a
1735     // zero-sized memory block which is allowed to be freed, despite not being a
1736     // null pointer.
1737     if (Family != AF_Malloc || !isArgZERO_SIZE_PTR(State, C, ArgVal))
1738       HandleNonHeapDealloc(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1739                            Family);
1740     return nullptr;
1741   }
1742 
1743   R = R->StripCasts();
1744 
1745   // Blocks might show up as heap data, but should not be free()d
1746   if (isa<BlockDataRegion>(R)) {
1747     HandleNonHeapDealloc(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1748                          Family);
1749     return nullptr;
1750   }
1751 
1752   const MemSpaceRegion *MS = R->getMemorySpace();
1753 
1754   // Parameters, locals, statics, globals, and memory returned by
1755   // __builtin_alloca() shouldn't be freed.
1756   if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
1757     // FIXME: at the time this code was written, malloc() regions were
1758     // represented by conjured symbols, which are all in UnknownSpaceRegion.
1759     // This means that there isn't actually anything from HeapSpaceRegion
1760     // that should be freed, even though we allow it here.
1761     // Of course, free() can work on memory allocated outside the current
1762     // function, so UnknownSpaceRegion is always a possibility.
1763     // False negatives are better than false positives.
1764 
1765     if (isa<AllocaRegion>(R))
1766       HandleFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1767     else
1768       HandleNonHeapDealloc(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1769                            Family);
1770 
1771     return nullptr;
1772   }
1773 
1774   const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion());
1775   // Various cases could lead to non-symbol values here.
1776   // For now, ignore them.
1777   if (!SrBase)
1778     return nullptr;
1779 
1780   SymbolRef SymBase = SrBase->getSymbol();
1781   const RefState *RsBase = State->get<RegionState>(SymBase);
1782   SymbolRef PreviousRetStatusSymbol = nullptr;
1783 
1784   IsKnownToBeAllocated =
1785       RsBase && (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero());
1786 
1787   if (RsBase) {
1788 
1789     // Memory returned by alloca() shouldn't be freed.
1790     if (RsBase->getAllocationFamily() == AF_Alloca) {
1791       HandleFreeAlloca(C, ArgVal, ArgExpr->getSourceRange());
1792       return nullptr;
1793     }
1794 
1795     // Check for double free first.
1796     if ((RsBase->isReleased() || RsBase->isRelinquished()) &&
1797         !didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)) {
1798       HandleDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
1799                        SymBase, PreviousRetStatusSymbol);
1800       return nullptr;
1801 
1802     // If the pointer is allocated or escaped, but we are now trying to free it,
1803     // check that the call to free is proper.
1804     } else if (RsBase->isAllocated() || RsBase->isAllocatedOfSizeZero() ||
1805                RsBase->isEscaped()) {
1806 
1807       // Check if an expected deallocation function matches the real one.
1808       bool DeallocMatchesAlloc = RsBase->getAllocationFamily() == Family;
1809       if (!DeallocMatchesAlloc) {
1810         HandleMismatchedDealloc(C, ArgExpr->getSourceRange(), ParentExpr,
1811                                 RsBase, SymBase, Hold);
1812         return nullptr;
1813       }
1814 
1815       // Check if the memory location being freed is the actual location
1816       // allocated, or an offset.
1817       RegionOffset Offset = R->getAsOffset();
1818       if (Offset.isValid() &&
1819           !Offset.hasSymbolicOffset() &&
1820           Offset.getOffset() != 0) {
1821         const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
1822         HandleOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1823                          Family, AllocExpr);
1824         return nullptr;
1825       }
1826     }
1827   }
1828 
1829   if (SymBase->getType()->isFunctionPointerType()) {
1830     HandleFunctionPtrFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr,
1831                           Family);
1832     return nullptr;
1833   }
1834 
1835   // Clean out the info on previous call to free return info.
1836   State = State->remove<FreeReturnValue>(SymBase);
1837 
1838   // Keep track of the return value. If it is NULL, we will know that free
1839   // failed.
1840   if (ReturnsNullOnFailure) {
1841     SVal RetVal = C.getSVal(ParentExpr);
1842     SymbolRef RetStatusSymbol = RetVal.getAsSymbol();
1843     if (RetStatusSymbol) {
1844       C.getSymbolManager().addSymbolDependency(SymBase, RetStatusSymbol);
1845       State = State->set<FreeReturnValue>(SymBase, RetStatusSymbol);
1846     }
1847   }
1848 
1849   // If we don't know anything about this symbol, a free on it may be totally
1850   // valid. If this is the case, lets assume that the allocation family of the
1851   // freeing function is the same as the symbols allocation family, and go with
1852   // that.
1853   assert(!RsBase || (RsBase && RsBase->getAllocationFamily() == Family));
1854 
1855   // Normal free.
1856   if (Hold)
1857     return State->set<RegionState>(SymBase,
1858                                    RefState::getRelinquished(Family,
1859                                                              ParentExpr));
1860 
1861   return State->set<RegionState>(SymBase,
1862                                  RefState::getReleased(Family, ParentExpr));
1863 }
1864 
1865 Optional<MallocChecker::CheckKind>
getCheckIfTracked(AllocationFamily Family,bool IsALeakCheck) const1866 MallocChecker::getCheckIfTracked(AllocationFamily Family,
1867                                  bool IsALeakCheck) const {
1868   switch (Family) {
1869   case AF_Malloc:
1870   case AF_Alloca:
1871   case AF_IfNameIndex: {
1872     if (ChecksEnabled[CK_MallocChecker])
1873       return CK_MallocChecker;
1874     return None;
1875   }
1876   case AF_CXXNew:
1877   case AF_CXXNewArray: {
1878     if (IsALeakCheck) {
1879       if (ChecksEnabled[CK_NewDeleteLeaksChecker])
1880         return CK_NewDeleteLeaksChecker;
1881     }
1882     else {
1883       if (ChecksEnabled[CK_NewDeleteChecker])
1884         return CK_NewDeleteChecker;
1885     }
1886     return None;
1887   }
1888   case AF_InnerBuffer: {
1889     if (ChecksEnabled[CK_InnerPointerChecker])
1890       return CK_InnerPointerChecker;
1891     return None;
1892   }
1893   case AF_None: {
1894     llvm_unreachable("no family");
1895   }
1896   }
1897   llvm_unreachable("unhandled family");
1898 }
1899 
1900 Optional<MallocChecker::CheckKind>
getCheckIfTracked(CheckerContext & C,SymbolRef Sym,bool IsALeakCheck) const1901 MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym,
1902                                  bool IsALeakCheck) const {
1903   if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym))
1904     return CK_MallocChecker;
1905 
1906   const RefState *RS = C.getState()->get<RegionState>(Sym);
1907   assert(RS);
1908   return getCheckIfTracked(RS->getAllocationFamily(), IsALeakCheck);
1909 }
1910 
SummarizeValue(raw_ostream & os,SVal V)1911 bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
1912   if (Optional<nonloc::ConcreteInt> IntVal = V.getAs<nonloc::ConcreteInt>())
1913     os << "an integer (" << IntVal->getValue() << ")";
1914   else if (Optional<loc::ConcreteInt> ConstAddr = V.getAs<loc::ConcreteInt>())
1915     os << "a constant address (" << ConstAddr->getValue() << ")";
1916   else if (Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
1917     os << "the address of the label '" << Label->getLabel()->getName() << "'";
1918   else
1919     return false;
1920 
1921   return true;
1922 }
1923 
SummarizeRegion(raw_ostream & os,const MemRegion * MR)1924 bool MallocChecker::SummarizeRegion(raw_ostream &os,
1925                                     const MemRegion *MR) {
1926   switch (MR->getKind()) {
1927   case MemRegion::FunctionCodeRegionKind: {
1928     const NamedDecl *FD = cast<FunctionCodeRegion>(MR)->getDecl();
1929     if (FD)
1930       os << "the address of the function '" << *FD << '\'';
1931     else
1932       os << "the address of a function";
1933     return true;
1934   }
1935   case MemRegion::BlockCodeRegionKind:
1936     os << "block text";
1937     return true;
1938   case MemRegion::BlockDataRegionKind:
1939     // FIXME: where the block came from?
1940     os << "a block";
1941     return true;
1942   default: {
1943     const MemSpaceRegion *MS = MR->getMemorySpace();
1944 
1945     if (isa<StackLocalsSpaceRegion>(MS)) {
1946       const VarRegion *VR = dyn_cast<VarRegion>(MR);
1947       const VarDecl *VD;
1948       if (VR)
1949         VD = VR->getDecl();
1950       else
1951         VD = nullptr;
1952 
1953       if (VD)
1954         os << "the address of the local variable '" << VD->getName() << "'";
1955       else
1956         os << "the address of a local stack variable";
1957       return true;
1958     }
1959 
1960     if (isa<StackArgumentsSpaceRegion>(MS)) {
1961       const VarRegion *VR = dyn_cast<VarRegion>(MR);
1962       const VarDecl *VD;
1963       if (VR)
1964         VD = VR->getDecl();
1965       else
1966         VD = nullptr;
1967 
1968       if (VD)
1969         os << "the address of the parameter '" << VD->getName() << "'";
1970       else
1971         os << "the address of a parameter";
1972       return true;
1973     }
1974 
1975     if (isa<GlobalsSpaceRegion>(MS)) {
1976       const VarRegion *VR = dyn_cast<VarRegion>(MR);
1977       const VarDecl *VD;
1978       if (VR)
1979         VD = VR->getDecl();
1980       else
1981         VD = nullptr;
1982 
1983       if (VD) {
1984         if (VD->isStaticLocal())
1985           os << "the address of the static variable '" << VD->getName() << "'";
1986         else
1987           os << "the address of the global variable '" << VD->getName() << "'";
1988       } else
1989         os << "the address of a global variable";
1990       return true;
1991     }
1992 
1993     return false;
1994   }
1995   }
1996 }
1997 
HandleNonHeapDealloc(CheckerContext & C,SVal ArgVal,SourceRange Range,const Expr * DeallocExpr,AllocationFamily Family) const1998 void MallocChecker::HandleNonHeapDealloc(CheckerContext &C, SVal ArgVal,
1999                                          SourceRange Range,
2000                                          const Expr *DeallocExpr,
2001                                          AllocationFamily Family) const {
2002 
2003   if (!ChecksEnabled[CK_MallocChecker] && !ChecksEnabled[CK_NewDeleteChecker]) {
2004     C.addSink();
2005     return;
2006   }
2007 
2008   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
2009   if (!CheckKind.hasValue())
2010     return;
2011 
2012   if (ExplodedNode *N = C.generateErrorNode()) {
2013     if (!BT_BadFree[*CheckKind])
2014       BT_BadFree[*CheckKind].reset(new BugType(
2015           CheckNames[*CheckKind], "Bad free", categories::MemoryError));
2016 
2017     SmallString<100> buf;
2018     llvm::raw_svector_ostream os(buf);
2019 
2020     const MemRegion *MR = ArgVal.getAsRegion();
2021     while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
2022       MR = ER->getSuperRegion();
2023 
2024     os << "Argument to ";
2025     if (!printMemFnName(os, C, DeallocExpr))
2026       os << "deallocator";
2027 
2028     os << " is ";
2029     bool Summarized = MR ? SummarizeRegion(os, MR)
2030                          : SummarizeValue(os, ArgVal);
2031     if (Summarized)
2032       os << ", which is not memory allocated by ";
2033     else
2034       os << "not memory allocated by ";
2035 
2036     printExpectedAllocName(os, Family);
2037 
2038     auto R = std::make_unique<PathSensitiveBugReport>(*BT_BadFree[*CheckKind],
2039                                                       os.str(), N);
2040     R->markInteresting(MR);
2041     R->addRange(Range);
2042     C.emitReport(std::move(R));
2043   }
2044 }
2045 
HandleFreeAlloca(CheckerContext & C,SVal ArgVal,SourceRange Range) const2046 void MallocChecker::HandleFreeAlloca(CheckerContext &C, SVal ArgVal,
2047                                      SourceRange Range) const {
2048 
2049   Optional<MallocChecker::CheckKind> CheckKind;
2050 
2051   if (ChecksEnabled[CK_MallocChecker])
2052     CheckKind = CK_MallocChecker;
2053   else if (ChecksEnabled[CK_MismatchedDeallocatorChecker])
2054     CheckKind = CK_MismatchedDeallocatorChecker;
2055   else {
2056     C.addSink();
2057     return;
2058   }
2059 
2060   if (ExplodedNode *N = C.generateErrorNode()) {
2061     if (!BT_FreeAlloca[*CheckKind])
2062       BT_FreeAlloca[*CheckKind].reset(new BugType(
2063           CheckNames[*CheckKind], "Free alloca()", categories::MemoryError));
2064 
2065     auto R = std::make_unique<PathSensitiveBugReport>(
2066         *BT_FreeAlloca[*CheckKind],
2067         "Memory allocated by alloca() should not be deallocated", N);
2068     R->markInteresting(ArgVal.getAsRegion());
2069     R->addRange(Range);
2070     C.emitReport(std::move(R));
2071   }
2072 }
2073 
HandleMismatchedDealloc(CheckerContext & C,SourceRange Range,const Expr * DeallocExpr,const RefState * RS,SymbolRef Sym,bool OwnershipTransferred) const2074 void MallocChecker::HandleMismatchedDealloc(CheckerContext &C,
2075                                             SourceRange Range,
2076                                             const Expr *DeallocExpr,
2077                                             const RefState *RS, SymbolRef Sym,
2078                                             bool OwnershipTransferred) const {
2079 
2080   if (!ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
2081     C.addSink();
2082     return;
2083   }
2084 
2085   if (ExplodedNode *N = C.generateErrorNode()) {
2086     if (!BT_MismatchedDealloc)
2087       BT_MismatchedDealloc.reset(
2088           new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
2089                       "Bad deallocator", categories::MemoryError));
2090 
2091     SmallString<100> buf;
2092     llvm::raw_svector_ostream os(buf);
2093 
2094     const Expr *AllocExpr = cast<Expr>(RS->getStmt());
2095     SmallString<20> AllocBuf;
2096     llvm::raw_svector_ostream AllocOs(AllocBuf);
2097     SmallString<20> DeallocBuf;
2098     llvm::raw_svector_ostream DeallocOs(DeallocBuf);
2099 
2100     if (OwnershipTransferred) {
2101       if (printMemFnName(DeallocOs, C, DeallocExpr))
2102         os << DeallocOs.str() << " cannot";
2103       else
2104         os << "Cannot";
2105 
2106       os << " take ownership of memory";
2107 
2108       if (printMemFnName(AllocOs, C, AllocExpr))
2109         os << " allocated by " << AllocOs.str();
2110     } else {
2111       os << "Memory";
2112       if (printMemFnName(AllocOs, C, AllocExpr))
2113         os << " allocated by " << AllocOs.str();
2114 
2115       os << " should be deallocated by ";
2116         printExpectedDeallocName(os, RS->getAllocationFamily());
2117 
2118         if (printMemFnName(DeallocOs, C, DeallocExpr))
2119           os << ", not " << DeallocOs.str();
2120     }
2121 
2122     auto R = std::make_unique<PathSensitiveBugReport>(*BT_MismatchedDealloc,
2123                                                       os.str(), N);
2124     R->markInteresting(Sym);
2125     R->addRange(Range);
2126     R->addVisitor<MallocBugVisitor>(Sym);
2127     C.emitReport(std::move(R));
2128   }
2129 }
2130 
HandleOffsetFree(CheckerContext & C,SVal ArgVal,SourceRange Range,const Expr * DeallocExpr,AllocationFamily Family,const Expr * AllocExpr) const2131 void MallocChecker::HandleOffsetFree(CheckerContext &C, SVal ArgVal,
2132                                      SourceRange Range, const Expr *DeallocExpr,
2133                                      AllocationFamily Family,
2134                                      const Expr *AllocExpr) const {
2135 
2136   if (!ChecksEnabled[CK_MallocChecker] && !ChecksEnabled[CK_NewDeleteChecker]) {
2137     C.addSink();
2138     return;
2139   }
2140 
2141   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
2142   if (!CheckKind.hasValue())
2143     return;
2144 
2145   ExplodedNode *N = C.generateErrorNode();
2146   if (!N)
2147     return;
2148 
2149   if (!BT_OffsetFree[*CheckKind])
2150     BT_OffsetFree[*CheckKind].reset(new BugType(
2151         CheckNames[*CheckKind], "Offset free", categories::MemoryError));
2152 
2153   SmallString<100> buf;
2154   llvm::raw_svector_ostream os(buf);
2155   SmallString<20> AllocNameBuf;
2156   llvm::raw_svector_ostream AllocNameOs(AllocNameBuf);
2157 
2158   const MemRegion *MR = ArgVal.getAsRegion();
2159   assert(MR && "Only MemRegion based symbols can have offset free errors");
2160 
2161   RegionOffset Offset = MR->getAsOffset();
2162   assert((Offset.isValid() &&
2163           !Offset.hasSymbolicOffset() &&
2164           Offset.getOffset() != 0) &&
2165          "Only symbols with a valid offset can have offset free errors");
2166 
2167   int offsetBytes = Offset.getOffset() / C.getASTContext().getCharWidth();
2168 
2169   os << "Argument to ";
2170   if (!printMemFnName(os, C, DeallocExpr))
2171     os << "deallocator";
2172   os << " is offset by "
2173      << offsetBytes
2174      << " "
2175      << ((abs(offsetBytes) > 1) ? "bytes" : "byte")
2176      << " from the start of ";
2177   if (AllocExpr && printMemFnName(AllocNameOs, C, AllocExpr))
2178     os << "memory allocated by " << AllocNameOs.str();
2179   else
2180     os << "allocated memory";
2181 
2182   auto R = std::make_unique<PathSensitiveBugReport>(*BT_OffsetFree[*CheckKind],
2183                                                     os.str(), N);
2184   R->markInteresting(MR->getBaseRegion());
2185   R->addRange(Range);
2186   C.emitReport(std::move(R));
2187 }
2188 
HandleUseAfterFree(CheckerContext & C,SourceRange Range,SymbolRef Sym) const2189 void MallocChecker::HandleUseAfterFree(CheckerContext &C, SourceRange Range,
2190                                        SymbolRef Sym) const {
2191 
2192   if (!ChecksEnabled[CK_MallocChecker] && !ChecksEnabled[CK_NewDeleteChecker] &&
2193       !ChecksEnabled[CK_InnerPointerChecker]) {
2194     C.addSink();
2195     return;
2196   }
2197 
2198   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2199   if (!CheckKind.hasValue())
2200     return;
2201 
2202   if (ExplodedNode *N = C.generateErrorNode()) {
2203     if (!BT_UseFree[*CheckKind])
2204       BT_UseFree[*CheckKind].reset(new BugType(
2205           CheckNames[*CheckKind], "Use-after-free", categories::MemoryError));
2206 
2207     AllocationFamily AF =
2208         C.getState()->get<RegionState>(Sym)->getAllocationFamily();
2209 
2210     auto R = std::make_unique<PathSensitiveBugReport>(
2211         *BT_UseFree[*CheckKind],
2212         AF == AF_InnerBuffer
2213             ? "Inner pointer of container used after re/deallocation"
2214             : "Use of memory after it is freed",
2215         N);
2216 
2217     R->markInteresting(Sym);
2218     R->addRange(Range);
2219     R->addVisitor<MallocBugVisitor>(Sym);
2220 
2221     if (AF == AF_InnerBuffer)
2222       R->addVisitor(allocation_state::getInnerPointerBRVisitor(Sym));
2223 
2224     C.emitReport(std::move(R));
2225   }
2226 }
2227 
HandleDoubleFree(CheckerContext & C,SourceRange Range,bool Released,SymbolRef Sym,SymbolRef PrevSym) const2228 void MallocChecker::HandleDoubleFree(CheckerContext &C, SourceRange Range,
2229                                      bool Released, SymbolRef Sym,
2230                                      SymbolRef PrevSym) const {
2231 
2232   if (!ChecksEnabled[CK_MallocChecker] && !ChecksEnabled[CK_NewDeleteChecker]) {
2233     C.addSink();
2234     return;
2235   }
2236 
2237   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2238   if (!CheckKind.hasValue())
2239     return;
2240 
2241   if (ExplodedNode *N = C.generateErrorNode()) {
2242     if (!BT_DoubleFree[*CheckKind])
2243       BT_DoubleFree[*CheckKind].reset(new BugType(
2244           CheckNames[*CheckKind], "Double free", categories::MemoryError));
2245 
2246     auto R = std::make_unique<PathSensitiveBugReport>(
2247         *BT_DoubleFree[*CheckKind],
2248         (Released ? "Attempt to free released memory"
2249                   : "Attempt to free non-owned memory"),
2250         N);
2251     R->addRange(Range);
2252     R->markInteresting(Sym);
2253     if (PrevSym)
2254       R->markInteresting(PrevSym);
2255     R->addVisitor<MallocBugVisitor>(Sym);
2256     C.emitReport(std::move(R));
2257   }
2258 }
2259 
HandleDoubleDelete(CheckerContext & C,SymbolRef Sym) const2260 void MallocChecker::HandleDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
2261 
2262   if (!ChecksEnabled[CK_NewDeleteChecker]) {
2263     C.addSink();
2264     return;
2265   }
2266 
2267   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2268   if (!CheckKind.hasValue())
2269     return;
2270 
2271   if (ExplodedNode *N = C.generateErrorNode()) {
2272     if (!BT_DoubleDelete)
2273       BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker],
2274                                         "Double delete",
2275                                         categories::MemoryError));
2276 
2277     auto R = std::make_unique<PathSensitiveBugReport>(
2278         *BT_DoubleDelete, "Attempt to delete released memory", N);
2279 
2280     R->markInteresting(Sym);
2281     R->addVisitor<MallocBugVisitor>(Sym);
2282     C.emitReport(std::move(R));
2283   }
2284 }
2285 
HandleUseZeroAlloc(CheckerContext & C,SourceRange Range,SymbolRef Sym) const2286 void MallocChecker::HandleUseZeroAlloc(CheckerContext &C, SourceRange Range,
2287                                        SymbolRef Sym) const {
2288 
2289   if (!ChecksEnabled[CK_MallocChecker] && !ChecksEnabled[CK_NewDeleteChecker]) {
2290     C.addSink();
2291     return;
2292   }
2293 
2294   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
2295 
2296   if (!CheckKind.hasValue())
2297     return;
2298 
2299   if (ExplodedNode *N = C.generateErrorNode()) {
2300     if (!BT_UseZerroAllocated[*CheckKind])
2301       BT_UseZerroAllocated[*CheckKind].reset(
2302           new BugType(CheckNames[*CheckKind], "Use of zero allocated",
2303                       categories::MemoryError));
2304 
2305     auto R = std::make_unique<PathSensitiveBugReport>(
2306         *BT_UseZerroAllocated[*CheckKind], "Use of zero-allocated memory", N);
2307 
2308     R->addRange(Range);
2309     if (Sym) {
2310       R->markInteresting(Sym);
2311       R->addVisitor<MallocBugVisitor>(Sym);
2312     }
2313     C.emitReport(std::move(R));
2314   }
2315 }
2316 
HandleFunctionPtrFree(CheckerContext & C,SVal ArgVal,SourceRange Range,const Expr * FreeExpr,AllocationFamily Family) const2317 void MallocChecker::HandleFunctionPtrFree(CheckerContext &C, SVal ArgVal,
2318                                           SourceRange Range,
2319                                           const Expr *FreeExpr,
2320                                           AllocationFamily Family) const {
2321   if (!ChecksEnabled[CK_MallocChecker]) {
2322     C.addSink();
2323     return;
2324   }
2325 
2326   Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
2327   if (!CheckKind.hasValue())
2328     return;
2329 
2330   if (ExplodedNode *N = C.generateErrorNode()) {
2331     if (!BT_BadFree[*CheckKind])
2332       BT_BadFree[*CheckKind].reset(new BugType(
2333           CheckNames[*CheckKind], "Bad free", categories::MemoryError));
2334 
2335     SmallString<100> Buf;
2336     llvm::raw_svector_ostream Os(Buf);
2337 
2338     const MemRegion *MR = ArgVal.getAsRegion();
2339     while (const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(MR))
2340       MR = ER->getSuperRegion();
2341 
2342     Os << "Argument to ";
2343     if (!printMemFnName(Os, C, FreeExpr))
2344       Os << "deallocator";
2345 
2346     Os << " is a function pointer";
2347 
2348     auto R = std::make_unique<PathSensitiveBugReport>(*BT_BadFree[*CheckKind],
2349                                                       Os.str(), N);
2350     R->markInteresting(MR);
2351     R->addRange(Range);
2352     C.emitReport(std::move(R));
2353   }
2354 }
2355 
2356 ProgramStateRef
ReallocMemAux(CheckerContext & C,const CallEvent & Call,bool ShouldFreeOnFail,ProgramStateRef State,AllocationFamily Family,bool SuffixWithN) const2357 MallocChecker::ReallocMemAux(CheckerContext &C, const CallEvent &Call,
2358                              bool ShouldFreeOnFail, ProgramStateRef State,
2359                              AllocationFamily Family, bool SuffixWithN) const {
2360   if (!State)
2361     return nullptr;
2362 
2363   const CallExpr *CE = cast<CallExpr>(Call.getOriginExpr());
2364 
2365   if (SuffixWithN && CE->getNumArgs() < 3)
2366     return nullptr;
2367   else if (CE->getNumArgs() < 2)
2368     return nullptr;
2369 
2370   const Expr *arg0Expr = CE->getArg(0);
2371   SVal Arg0Val = C.getSVal(arg0Expr);
2372   if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
2373     return nullptr;
2374   DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
2375 
2376   SValBuilder &svalBuilder = C.getSValBuilder();
2377 
2378   DefinedOrUnknownSVal PtrEQ =
2379     svalBuilder.evalEQ(State, arg0Val, svalBuilder.makeNull());
2380 
2381   // Get the size argument.
2382   const Expr *Arg1 = CE->getArg(1);
2383 
2384   // Get the value of the size argument.
2385   SVal TotalSize = C.getSVal(Arg1);
2386   if (SuffixWithN)
2387     TotalSize = evalMulForBufferSize(C, Arg1, CE->getArg(2));
2388   if (!TotalSize.getAs<DefinedOrUnknownSVal>())
2389     return nullptr;
2390 
2391   // Compare the size argument to 0.
2392   DefinedOrUnknownSVal SizeZero =
2393     svalBuilder.evalEQ(State, TotalSize.castAs<DefinedOrUnknownSVal>(),
2394                        svalBuilder.makeIntValWithPtrWidth(0, false));
2395 
2396   ProgramStateRef StatePtrIsNull, StatePtrNotNull;
2397   std::tie(StatePtrIsNull, StatePtrNotNull) = State->assume(PtrEQ);
2398   ProgramStateRef StateSizeIsZero, StateSizeNotZero;
2399   std::tie(StateSizeIsZero, StateSizeNotZero) = State->assume(SizeZero);
2400   // We only assume exceptional states if they are definitely true; if the
2401   // state is under-constrained, assume regular realloc behavior.
2402   bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
2403   bool SizeIsZero = StateSizeIsZero && !StateSizeNotZero;
2404 
2405   // If the ptr is NULL and the size is not 0, the call is equivalent to
2406   // malloc(size).
2407   if (PrtIsNull && !SizeIsZero) {
2408     ProgramStateRef stateMalloc = MallocMemAux(
2409         C, Call, TotalSize, UndefinedVal(), StatePtrIsNull, Family);
2410     return stateMalloc;
2411   }
2412 
2413   if (PrtIsNull && SizeIsZero)
2414     return State;
2415 
2416   assert(!PrtIsNull);
2417 
2418   bool IsKnownToBeAllocated = false;
2419 
2420   // If the size is 0, free the memory.
2421   if (SizeIsZero)
2422     // The semantics of the return value are:
2423     // If size was equal to 0, either NULL or a pointer suitable to be passed
2424     // to free() is returned. We just free the input pointer and do not add
2425     // any constrains on the output pointer.
2426     if (ProgramStateRef stateFree = FreeMemAux(
2427             C, Call, StateSizeIsZero, 0, false, IsKnownToBeAllocated, Family))
2428       return stateFree;
2429 
2430   // Default behavior.
2431   if (ProgramStateRef stateFree =
2432           FreeMemAux(C, Call, State, 0, false, IsKnownToBeAllocated, Family)) {
2433 
2434     ProgramStateRef stateRealloc =
2435         MallocMemAux(C, Call, TotalSize, UnknownVal(), stateFree, Family);
2436     if (!stateRealloc)
2437       return nullptr;
2438 
2439     OwnershipAfterReallocKind Kind = OAR_ToBeFreedAfterFailure;
2440     if (ShouldFreeOnFail)
2441       Kind = OAR_FreeOnFailure;
2442     else if (!IsKnownToBeAllocated)
2443       Kind = OAR_DoNotTrackAfterFailure;
2444 
2445     // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
2446     SymbolRef FromPtr = arg0Val.getLocSymbolInBase();
2447     SVal RetVal = C.getSVal(CE);
2448     SymbolRef ToPtr = RetVal.getAsSymbol();
2449     assert(FromPtr && ToPtr &&
2450            "By this point, FreeMemAux and MallocMemAux should have checked "
2451            "whether the argument or the return value is symbolic!");
2452 
2453     // Record the info about the reallocated symbol so that we could properly
2454     // process failed reallocation.
2455     stateRealloc = stateRealloc->set<ReallocPairs>(ToPtr,
2456                                                    ReallocPair(FromPtr, Kind));
2457     // The reallocated symbol should stay alive for as long as the new symbol.
2458     C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
2459     return stateRealloc;
2460   }
2461   return nullptr;
2462 }
2463 
CallocMem(CheckerContext & C,const CallEvent & Call,ProgramStateRef State)2464 ProgramStateRef MallocChecker::CallocMem(CheckerContext &C,
2465                                          const CallEvent &Call,
2466                                          ProgramStateRef State) {
2467   if (!State)
2468     return nullptr;
2469 
2470   if (Call.getNumArgs() < 2)
2471     return nullptr;
2472 
2473   SValBuilder &svalBuilder = C.getSValBuilder();
2474   SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
2475   SVal TotalSize =
2476       evalMulForBufferSize(C, Call.getArgExpr(0), Call.getArgExpr(1));
2477 
2478   return MallocMemAux(C, Call, TotalSize, zeroVal, State, AF_Malloc);
2479 }
2480 
getAllocationSite(const ExplodedNode * N,SymbolRef Sym,CheckerContext & C)2481 MallocChecker::LeakInfo MallocChecker::getAllocationSite(const ExplodedNode *N,
2482                                                          SymbolRef Sym,
2483                                                          CheckerContext &C) {
2484   const LocationContext *LeakContext = N->getLocationContext();
2485   // Walk the ExplodedGraph backwards and find the first node that referred to
2486   // the tracked symbol.
2487   const ExplodedNode *AllocNode = N;
2488   const MemRegion *ReferenceRegion = nullptr;
2489 
2490   while (N) {
2491     ProgramStateRef State = N->getState();
2492     if (!State->get<RegionState>(Sym))
2493       break;
2494 
2495     // Find the most recent expression bound to the symbol in the current
2496     // context.
2497     if (!ReferenceRegion) {
2498       if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
2499         SVal Val = State->getSVal(MR);
2500         if (Val.getAsLocSymbol() == Sym) {
2501           const VarRegion *VR = MR->getBaseRegion()->getAs<VarRegion>();
2502           // Do not show local variables belonging to a function other than
2503           // where the error is reported.
2504           if (!VR || (VR->getStackFrame() == LeakContext->getStackFrame()))
2505             ReferenceRegion = MR;
2506         }
2507       }
2508     }
2509 
2510     // Allocation node, is the last node in the current or parent context in
2511     // which the symbol was tracked.
2512     const LocationContext *NContext = N->getLocationContext();
2513     if (NContext == LeakContext ||
2514         NContext->isParentOf(LeakContext))
2515       AllocNode = N;
2516     N = N->pred_empty() ? nullptr : *(N->pred_begin());
2517   }
2518 
2519   return LeakInfo(AllocNode, ReferenceRegion);
2520 }
2521 
HandleLeak(SymbolRef Sym,ExplodedNode * N,CheckerContext & C) const2522 void MallocChecker::HandleLeak(SymbolRef Sym, ExplodedNode *N,
2523                                CheckerContext &C) const {
2524 
2525   if (!ChecksEnabled[CK_MallocChecker] &&
2526       !ChecksEnabled[CK_NewDeleteLeaksChecker])
2527     return;
2528 
2529   const RefState *RS = C.getState()->get<RegionState>(Sym);
2530   assert(RS && "cannot leak an untracked symbol");
2531   AllocationFamily Family = RS->getAllocationFamily();
2532 
2533   if (Family == AF_Alloca)
2534     return;
2535 
2536   Optional<MallocChecker::CheckKind>
2537       CheckKind = getCheckIfTracked(Family, true);
2538 
2539   if (!CheckKind.hasValue())
2540     return;
2541 
2542   assert(N);
2543   if (!BT_Leak[*CheckKind]) {
2544     // Leaks should not be reported if they are post-dominated by a sink:
2545     // (1) Sinks are higher importance bugs.
2546     // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
2547     //     with __noreturn functions such as assert() or exit(). We choose not
2548     //     to report leaks on such paths.
2549     BT_Leak[*CheckKind].reset(new BugType(CheckNames[*CheckKind], "Memory leak",
2550                                           categories::MemoryError,
2551                                           /*SuppressOnSink=*/true));
2552   }
2553 
2554   // Most bug reports are cached at the location where they occurred.
2555   // With leaks, we want to unique them by the location where they were
2556   // allocated, and only report a single path.
2557   PathDiagnosticLocation LocUsedForUniqueing;
2558   const ExplodedNode *AllocNode = nullptr;
2559   const MemRegion *Region = nullptr;
2560   std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
2561 
2562   const Stmt *AllocationStmt = AllocNode->getStmtForDiagnostics();
2563   if (AllocationStmt)
2564     LocUsedForUniqueing = PathDiagnosticLocation::createBegin(AllocationStmt,
2565                                               C.getSourceManager(),
2566                                               AllocNode->getLocationContext());
2567 
2568   SmallString<200> buf;
2569   llvm::raw_svector_ostream os(buf);
2570   if (Region && Region->canPrintPretty()) {
2571     os << "Potential leak of memory pointed to by ";
2572     Region->printPretty(os);
2573   } else {
2574     os << "Potential memory leak";
2575   }
2576 
2577   auto R = std::make_unique<PathSensitiveBugReport>(
2578       *BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
2579       AllocNode->getLocationContext()->getDecl());
2580   R->markInteresting(Sym);
2581   R->addVisitor<MallocBugVisitor>(Sym, true);
2582   C.emitReport(std::move(R));
2583 }
2584 
checkDeadSymbols(SymbolReaper & SymReaper,CheckerContext & C) const2585 void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
2586                                      CheckerContext &C) const
2587 {
2588   ProgramStateRef state = C.getState();
2589   RegionStateTy OldRS = state->get<RegionState>();
2590   RegionStateTy::Factory &F = state->get_context<RegionState>();
2591 
2592   RegionStateTy RS = OldRS;
2593   SmallVector<SymbolRef, 2> Errors;
2594   for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2595     if (SymReaper.isDead(I->first)) {
2596       if (I->second.isAllocated() || I->second.isAllocatedOfSizeZero())
2597         Errors.push_back(I->first);
2598       // Remove the dead symbol from the map.
2599       RS = F.remove(RS, I->first);
2600     }
2601   }
2602 
2603   if (RS == OldRS) {
2604     // We shouldn't have touched other maps yet.
2605     assert(state->get<ReallocPairs>() ==
2606            C.getState()->get<ReallocPairs>());
2607     assert(state->get<FreeReturnValue>() ==
2608            C.getState()->get<FreeReturnValue>());
2609     return;
2610   }
2611 
2612   // Cleanup the Realloc Pairs Map.
2613   ReallocPairsTy RP = state->get<ReallocPairs>();
2614   for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
2615     if (SymReaper.isDead(I->first) ||
2616         SymReaper.isDead(I->second.ReallocatedSym)) {
2617       state = state->remove<ReallocPairs>(I->first);
2618     }
2619   }
2620 
2621   // Cleanup the FreeReturnValue Map.
2622   FreeReturnValueTy FR = state->get<FreeReturnValue>();
2623   for (FreeReturnValueTy::iterator I = FR.begin(), E = FR.end(); I != E; ++I) {
2624     if (SymReaper.isDead(I->first) ||
2625         SymReaper.isDead(I->second)) {
2626       state = state->remove<FreeReturnValue>(I->first);
2627     }
2628   }
2629 
2630   // Generate leak node.
2631   ExplodedNode *N = C.getPredecessor();
2632   if (!Errors.empty()) {
2633     static CheckerProgramPointTag Tag("MallocChecker", "DeadSymbolsLeak");
2634     N = C.generateNonFatalErrorNode(C.getState(), &Tag);
2635     if (N) {
2636       for (SmallVectorImpl<SymbolRef>::iterator
2637            I = Errors.begin(), E = Errors.end(); I != E; ++I) {
2638         HandleLeak(*I, N, C);
2639       }
2640     }
2641   }
2642 
2643   C.addTransition(state->set<RegionState>(RS), N);
2644 }
2645 
checkPreCall(const CallEvent & Call,CheckerContext & C) const2646 void MallocChecker::checkPreCall(const CallEvent &Call,
2647                                  CheckerContext &C) const {
2648 
2649   if (const auto *DC = dyn_cast<CXXDeallocatorCall>(&Call)) {
2650     const CXXDeleteExpr *DE = DC->getOriginExpr();
2651 
2652     if (!ChecksEnabled[CK_NewDeleteChecker])
2653       if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
2654         checkUseAfterFree(Sym, C, DE->getArgument());
2655 
2656     if (!isStandardNewDelete(DC->getDecl()))
2657       return;
2658 
2659     ProgramStateRef State = C.getState();
2660     bool IsKnownToBeAllocated;
2661     State = FreeMemAux(C, DE->getArgument(), Call, State,
2662                        /*Hold*/ false, IsKnownToBeAllocated,
2663                        (DE->isArrayForm() ? AF_CXXNewArray : AF_CXXNew));
2664 
2665     C.addTransition(State);
2666     return;
2667   }
2668 
2669   if (const auto *DC = dyn_cast<CXXDestructorCall>(&Call)) {
2670     SymbolRef Sym = DC->getCXXThisVal().getAsSymbol();
2671     if (!Sym || checkDoubleDelete(Sym, C))
2672       return;
2673   }
2674 
2675   // We will check for double free in the post visit.
2676   if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
2677     const FunctionDecl *FD = FC->getDecl();
2678     if (!FD)
2679       return;
2680 
2681     if (ChecksEnabled[CK_MallocChecker] && isFreeingCall(Call))
2682       return;
2683   }
2684 
2685   // Check if the callee of a method is deleted.
2686   if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
2687     SymbolRef Sym = CC->getCXXThisVal().getAsSymbol();
2688     if (!Sym || checkUseAfterFree(Sym, C, CC->getCXXThisExpr()))
2689       return;
2690   }
2691 
2692   // Check arguments for being used after free.
2693   for (unsigned I = 0, E = Call.getNumArgs(); I != E; ++I) {
2694     SVal ArgSVal = Call.getArgSVal(I);
2695     if (ArgSVal.getAs<Loc>()) {
2696       SymbolRef Sym = ArgSVal.getAsSymbol();
2697       if (!Sym)
2698         continue;
2699       if (checkUseAfterFree(Sym, C, Call.getArgExpr(I)))
2700         return;
2701     }
2702   }
2703 }
2704 
checkPreStmt(const ReturnStmt * S,CheckerContext & C) const2705 void MallocChecker::checkPreStmt(const ReturnStmt *S,
2706                                  CheckerContext &C) const {
2707   checkEscapeOnReturn(S, C);
2708 }
2709 
2710 // In the CFG, automatic destructors come after the return statement.
2711 // This callback checks for returning memory that is freed by automatic
2712 // destructors, as those cannot be reached in checkPreStmt().
checkEndFunction(const ReturnStmt * S,CheckerContext & C) const2713 void MallocChecker::checkEndFunction(const ReturnStmt *S,
2714                                      CheckerContext &C) const {
2715   checkEscapeOnReturn(S, C);
2716 }
2717 
checkEscapeOnReturn(const ReturnStmt * S,CheckerContext & C) const2718 void MallocChecker::checkEscapeOnReturn(const ReturnStmt *S,
2719                                         CheckerContext &C) const {
2720   if (!S)
2721     return;
2722 
2723   const Expr *E = S->getRetValue();
2724   if (!E)
2725     return;
2726 
2727   // Check if we are returning a symbol.
2728   ProgramStateRef State = C.getState();
2729   SVal RetVal = C.getSVal(E);
2730   SymbolRef Sym = RetVal.getAsSymbol();
2731   if (!Sym)
2732     // If we are returning a field of the allocated struct or an array element,
2733     // the callee could still free the memory.
2734     // TODO: This logic should be a part of generic symbol escape callback.
2735     if (const MemRegion *MR = RetVal.getAsRegion())
2736       if (isa<FieldRegion>(MR) || isa<ElementRegion>(MR))
2737         if (const SymbolicRegion *BMR =
2738               dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
2739           Sym = BMR->getSymbol();
2740 
2741   // Check if we are returning freed memory.
2742   if (Sym)
2743     checkUseAfterFree(Sym, C, E);
2744 }
2745 
2746 // TODO: Blocks should be either inlined or should call invalidate regions
2747 // upon invocation. After that's in place, special casing here will not be
2748 // needed.
checkPostStmt(const BlockExpr * BE,CheckerContext & C) const2749 void MallocChecker::checkPostStmt(const BlockExpr *BE,
2750                                   CheckerContext &C) const {
2751 
2752   // Scan the BlockDecRefExprs for any object the retain count checker
2753   // may be tracking.
2754   if (!BE->getBlockDecl()->hasCaptures())
2755     return;
2756 
2757   ProgramStateRef state = C.getState();
2758   const BlockDataRegion *R =
2759     cast<BlockDataRegion>(C.getSVal(BE).getAsRegion());
2760 
2761   BlockDataRegion::referenced_vars_iterator I = R->referenced_vars_begin(),
2762                                             E = R->referenced_vars_end();
2763 
2764   if (I == E)
2765     return;
2766 
2767   SmallVector<const MemRegion*, 10> Regions;
2768   const LocationContext *LC = C.getLocationContext();
2769   MemRegionManager &MemMgr = C.getSValBuilder().getRegionManager();
2770 
2771   for ( ; I != E; ++I) {
2772     const VarRegion *VR = I.getCapturedRegion();
2773     if (VR->getSuperRegion() == R) {
2774       VR = MemMgr.getVarRegion(VR->getDecl(), LC);
2775     }
2776     Regions.push_back(VR);
2777   }
2778 
2779   state =
2780     state->scanReachableSymbols<StopTrackingCallback>(Regions).getState();
2781   C.addTransition(state);
2782 }
2783 
isReleased(SymbolRef Sym,CheckerContext & C)2784 static bool isReleased(SymbolRef Sym, CheckerContext &C) {
2785   assert(Sym);
2786   const RefState *RS = C.getState()->get<RegionState>(Sym);
2787   return (RS && RS->isReleased());
2788 }
2789 
suppressDeallocationsInSuspiciousContexts(const CallEvent & Call,CheckerContext & C) const2790 bool MallocChecker::suppressDeallocationsInSuspiciousContexts(
2791     const CallEvent &Call, CheckerContext &C) const {
2792   if (Call.getNumArgs() == 0)
2793     return false;
2794 
2795   StringRef FunctionStr = "";
2796   if (const auto *FD = dyn_cast<FunctionDecl>(C.getStackFrame()->getDecl()))
2797     if (const Stmt *Body = FD->getBody())
2798       if (Body->getBeginLoc().isValid())
2799         FunctionStr =
2800             Lexer::getSourceText(CharSourceRange::getTokenRange(
2801                                      {FD->getBeginLoc(), Body->getBeginLoc()}),
2802                                  C.getSourceManager(), C.getLangOpts());
2803 
2804   // We do not model the Integer Set Library's retain-count based allocation.
2805   if (!FunctionStr.contains("__isl_"))
2806     return false;
2807 
2808   ProgramStateRef State = C.getState();
2809 
2810   for (const Expr *Arg : cast<CallExpr>(Call.getOriginExpr())->arguments())
2811     if (SymbolRef Sym = C.getSVal(Arg).getAsSymbol())
2812       if (const RefState *RS = State->get<RegionState>(Sym))
2813         State = State->set<RegionState>(Sym, RefState::getEscaped(RS));
2814 
2815   C.addTransition(State);
2816   return true;
2817 }
2818 
checkUseAfterFree(SymbolRef Sym,CheckerContext & C,const Stmt * S) const2819 bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
2820                                       const Stmt *S) const {
2821 
2822   if (isReleased(Sym, C)) {
2823     HandleUseAfterFree(C, S->getSourceRange(), Sym);
2824     return true;
2825   }
2826 
2827   return false;
2828 }
2829 
checkUseZeroAllocated(SymbolRef Sym,CheckerContext & C,const Stmt * S) const2830 void MallocChecker::checkUseZeroAllocated(SymbolRef Sym, CheckerContext &C,
2831                                           const Stmt *S) const {
2832   assert(Sym);
2833 
2834   if (const RefState *RS = C.getState()->get<RegionState>(Sym)) {
2835     if (RS->isAllocatedOfSizeZero())
2836       HandleUseZeroAlloc(C, RS->getStmt()->getSourceRange(), Sym);
2837   }
2838   else if (C.getState()->contains<ReallocSizeZeroSymbols>(Sym)) {
2839     HandleUseZeroAlloc(C, S->getSourceRange(), Sym);
2840   }
2841 }
2842 
checkDoubleDelete(SymbolRef Sym,CheckerContext & C) const2843 bool MallocChecker::checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const {
2844 
2845   if (isReleased(Sym, C)) {
2846     HandleDoubleDelete(C, Sym);
2847     return true;
2848   }
2849   return false;
2850 }
2851 
2852 // Check if the location is a freed symbolic region.
checkLocation(SVal l,bool isLoad,const Stmt * S,CheckerContext & C) const2853 void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
2854                                   CheckerContext &C) const {
2855   SymbolRef Sym = l.getLocSymbolInBase();
2856   if (Sym) {
2857     checkUseAfterFree(Sym, C, S);
2858     checkUseZeroAllocated(Sym, C, S);
2859   }
2860 }
2861 
2862 // If a symbolic region is assumed to NULL (or another constant), stop tracking
2863 // it - assuming that allocation failed on this path.
evalAssume(ProgramStateRef state,SVal Cond,bool Assumption) const2864 ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
2865                                               SVal Cond,
2866                                               bool Assumption) const {
2867   RegionStateTy RS = state->get<RegionState>();
2868   for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
2869     // If the symbol is assumed to be NULL, remove it from consideration.
2870     ConstraintManager &CMgr = state->getConstraintManager();
2871     ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
2872     if (AllocFailed.isConstrainedTrue())
2873       state = state->remove<RegionState>(I.getKey());
2874   }
2875 
2876   // Realloc returns 0 when reallocation fails, which means that we should
2877   // restore the state of the pointer being reallocated.
2878   ReallocPairsTy RP = state->get<ReallocPairs>();
2879   for (ReallocPairsTy::iterator I = RP.begin(), E = RP.end(); I != E; ++I) {
2880     // If the symbol is assumed to be NULL, remove it from consideration.
2881     ConstraintManager &CMgr = state->getConstraintManager();
2882     ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
2883     if (!AllocFailed.isConstrainedTrue())
2884       continue;
2885 
2886     SymbolRef ReallocSym = I.getData().ReallocatedSym;
2887     if (const RefState *RS = state->get<RegionState>(ReallocSym)) {
2888       if (RS->isReleased()) {
2889         switch (I.getData().Kind) {
2890         case OAR_ToBeFreedAfterFailure:
2891           state = state->set<RegionState>(ReallocSym,
2892               RefState::getAllocated(RS->getAllocationFamily(), RS->getStmt()));
2893           break;
2894         case OAR_DoNotTrackAfterFailure:
2895           state = state->remove<RegionState>(ReallocSym);
2896           break;
2897         default:
2898           assert(I.getData().Kind == OAR_FreeOnFailure);
2899         }
2900       }
2901     }
2902     state = state->remove<ReallocPairs>(I.getKey());
2903   }
2904 
2905   return state;
2906 }
2907 
mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent * Call,ProgramStateRef State,SymbolRef & EscapingSymbol) const2908 bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
2909                                               const CallEvent *Call,
2910                                               ProgramStateRef State,
2911                                               SymbolRef &EscapingSymbol) const {
2912   assert(Call);
2913   EscapingSymbol = nullptr;
2914 
2915   // For now, assume that any C++ or block call can free memory.
2916   // TODO: If we want to be more optimistic here, we'll need to make sure that
2917   // regions escape to C++ containers. They seem to do that even now, but for
2918   // mysterious reasons.
2919   if (!(isa<SimpleFunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
2920     return true;
2921 
2922   // Check Objective-C messages by selector name.
2923   if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
2924     // If it's not a framework call, or if it takes a callback, assume it
2925     // can free memory.
2926     if (!Call->isInSystemHeader() || Call->argumentsMayEscape())
2927       return true;
2928 
2929     // If it's a method we know about, handle it explicitly post-call.
2930     // This should happen before the "freeWhenDone" check below.
2931     if (isKnownDeallocObjCMethodName(*Msg))
2932       return false;
2933 
2934     // If there's a "freeWhenDone" parameter, but the method isn't one we know
2935     // about, we can't be sure that the object will use free() to deallocate the
2936     // memory, so we can't model it explicitly. The best we can do is use it to
2937     // decide whether the pointer escapes.
2938     if (Optional<bool> FreeWhenDone = getFreeWhenDoneArg(*Msg))
2939       return *FreeWhenDone;
2940 
2941     // If the first selector piece ends with "NoCopy", and there is no
2942     // "freeWhenDone" parameter set to zero, we know ownership is being
2943     // transferred. Again, though, we can't be sure that the object will use
2944     // free() to deallocate the memory, so we can't model it explicitly.
2945     StringRef FirstSlot = Msg->getSelector().getNameForSlot(0);
2946     if (FirstSlot.endswith("NoCopy"))
2947       return true;
2948 
2949     // If the first selector starts with addPointer, insertPointer,
2950     // or replacePointer, assume we are dealing with NSPointerArray or similar.
2951     // This is similar to C++ containers (vector); we still might want to check
2952     // that the pointers get freed by following the container itself.
2953     if (FirstSlot.startswith("addPointer") ||
2954         FirstSlot.startswith("insertPointer") ||
2955         FirstSlot.startswith("replacePointer") ||
2956         FirstSlot.equals("valueWithPointer")) {
2957       return true;
2958     }
2959 
2960     // We should escape receiver on call to 'init'. This is especially relevant
2961     // to the receiver, as the corresponding symbol is usually not referenced
2962     // after the call.
2963     if (Msg->getMethodFamily() == OMF_init) {
2964       EscapingSymbol = Msg->getReceiverSVal().getAsSymbol();
2965       return true;
2966     }
2967 
2968     // Otherwise, assume that the method does not free memory.
2969     // Most framework methods do not free memory.
2970     return false;
2971   }
2972 
2973   // At this point the only thing left to handle is straight function calls.
2974   const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl();
2975   if (!FD)
2976     return true;
2977 
2978   // If it's one of the allocation functions we can reason about, we model
2979   // its behavior explicitly.
2980   if (isMemCall(*Call))
2981     return false;
2982 
2983   // If it's not a system call, assume it frees memory.
2984   if (!Call->isInSystemHeader())
2985     return true;
2986 
2987   // White list the system functions whose arguments escape.
2988   const IdentifierInfo *II = FD->getIdentifier();
2989   if (!II)
2990     return true;
2991   StringRef FName = II->getName();
2992 
2993   // White list the 'XXXNoCopy' CoreFoundation functions.
2994   // We specifically check these before
2995   if (FName.endswith("NoCopy")) {
2996     // Look for the deallocator argument. We know that the memory ownership
2997     // is not transferred only if the deallocator argument is
2998     // 'kCFAllocatorNull'.
2999     for (unsigned i = 1; i < Call->getNumArgs(); ++i) {
3000       const Expr *ArgE = Call->getArgExpr(i)->IgnoreParenCasts();
3001       if (const DeclRefExpr *DE = dyn_cast<DeclRefExpr>(ArgE)) {
3002         StringRef DeallocatorName = DE->getFoundDecl()->getName();
3003         if (DeallocatorName == "kCFAllocatorNull")
3004           return false;
3005       }
3006     }
3007     return true;
3008   }
3009 
3010   // Associating streams with malloced buffers. The pointer can escape if
3011   // 'closefn' is specified (and if that function does free memory),
3012   // but it will not if closefn is not specified.
3013   // Currently, we do not inspect the 'closefn' function (PR12101).
3014   if (FName == "funopen")
3015     if (Call->getNumArgs() >= 4 && Call->getArgSVal(4).isConstant(0))
3016       return false;
3017 
3018   // Do not warn on pointers passed to 'setbuf' when used with std streams,
3019   // these leaks might be intentional when setting the buffer for stdio.
3020   // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
3021   if (FName == "setbuf" || FName =="setbuffer" ||
3022       FName == "setlinebuf" || FName == "setvbuf") {
3023     if (Call->getNumArgs() >= 1) {
3024       const Expr *ArgE = Call->getArgExpr(0)->IgnoreParenCasts();
3025       if (const DeclRefExpr *ArgDRE = dyn_cast<DeclRefExpr>(ArgE))
3026         if (const VarDecl *D = dyn_cast<VarDecl>(ArgDRE->getDecl()))
3027           if (D->getCanonicalDecl()->getName().find("std") != StringRef::npos)
3028             return true;
3029     }
3030   }
3031 
3032   // A bunch of other functions which either take ownership of a pointer or
3033   // wrap the result up in a struct or object, meaning it can be freed later.
3034   // (See RetainCountChecker.) Not all the parameters here are invalidated,
3035   // but the Malloc checker cannot differentiate between them. The right way
3036   // of doing this would be to implement a pointer escapes callback.
3037   if (FName == "CGBitmapContextCreate" ||
3038       FName == "CGBitmapContextCreateWithData" ||
3039       FName == "CVPixelBufferCreateWithBytes" ||
3040       FName == "CVPixelBufferCreateWithPlanarBytes" ||
3041       FName == "OSAtomicEnqueue") {
3042     return true;
3043   }
3044 
3045   if (FName == "postEvent" &&
3046       FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
3047     return true;
3048   }
3049 
3050   if (FName == "connectImpl" &&
3051       FD->getQualifiedNameAsString() == "QObject::connectImpl") {
3052     return true;
3053   }
3054 
3055   // Handle cases where we know a buffer's /address/ can escape.
3056   // Note that the above checks handle some special cases where we know that
3057   // even though the address escapes, it's still our responsibility to free the
3058   // buffer.
3059   if (Call->argumentsMayEscape())
3060     return true;
3061 
3062   // Otherwise, assume that the function does not free memory.
3063   // Most system calls do not free the memory.
3064   return false;
3065 }
3066 
checkPointerEscape(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind) const3067 ProgramStateRef MallocChecker::checkPointerEscape(ProgramStateRef State,
3068                                              const InvalidatedSymbols &Escaped,
3069                                              const CallEvent *Call,
3070                                              PointerEscapeKind Kind) const {
3071   return checkPointerEscapeAux(State, Escaped, Call, Kind,
3072                                /*IsConstPointerEscape*/ false);
3073 }
3074 
checkConstPointerEscape(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind) const3075 ProgramStateRef MallocChecker::checkConstPointerEscape(ProgramStateRef State,
3076                                               const InvalidatedSymbols &Escaped,
3077                                               const CallEvent *Call,
3078                                               PointerEscapeKind Kind) const {
3079   // If a const pointer escapes, it may not be freed(), but it could be deleted.
3080   return checkPointerEscapeAux(State, Escaped, Call, Kind,
3081                                /*IsConstPointerEscape*/ true);
3082 }
3083 
checkIfNewOrNewArrayFamily(const RefState * RS)3084 static bool checkIfNewOrNewArrayFamily(const RefState *RS) {
3085   return (RS->getAllocationFamily() == AF_CXXNewArray ||
3086           RS->getAllocationFamily() == AF_CXXNew);
3087 }
3088 
checkPointerEscapeAux(ProgramStateRef State,const InvalidatedSymbols & Escaped,const CallEvent * Call,PointerEscapeKind Kind,bool IsConstPointerEscape) const3089 ProgramStateRef MallocChecker::checkPointerEscapeAux(
3090     ProgramStateRef State, const InvalidatedSymbols &Escaped,
3091     const CallEvent *Call, PointerEscapeKind Kind,
3092     bool IsConstPointerEscape) const {
3093   // If we know that the call does not free memory, or we want to process the
3094   // call later, keep tracking the top level arguments.
3095   SymbolRef EscapingSymbol = nullptr;
3096   if (Kind == PSK_DirectEscapeOnCall &&
3097       !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State,
3098                                                     EscapingSymbol) &&
3099       !EscapingSymbol) {
3100     return State;
3101   }
3102 
3103   for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
3104        E = Escaped.end();
3105        I != E; ++I) {
3106     SymbolRef sym = *I;
3107 
3108     if (EscapingSymbol && EscapingSymbol != sym)
3109       continue;
3110 
3111     if (const RefState *RS = State->get<RegionState>(sym))
3112       if (RS->isAllocated() || RS->isAllocatedOfSizeZero())
3113         if (!IsConstPointerEscape || checkIfNewOrNewArrayFamily(RS))
3114           State = State->set<RegionState>(sym, RefState::getEscaped(RS));
3115   }
3116   return State;
3117 }
3118 
isArgZERO_SIZE_PTR(ProgramStateRef State,CheckerContext & C,SVal ArgVal) const3119 bool MallocChecker::isArgZERO_SIZE_PTR(ProgramStateRef State, CheckerContext &C,
3120                                        SVal ArgVal) const {
3121   if (!KernelZeroSizePtrValue)
3122     KernelZeroSizePtrValue =
3123         tryExpandAsInteger("ZERO_SIZE_PTR", C.getPreprocessor());
3124 
3125   const llvm::APSInt *ArgValKnown =
3126       C.getSValBuilder().getKnownValue(State, ArgVal);
3127   return ArgValKnown && *KernelZeroSizePtrValue &&
3128          ArgValKnown->getSExtValue() == **KernelZeroSizePtrValue;
3129 }
3130 
findFailedReallocSymbol(ProgramStateRef currState,ProgramStateRef prevState)3131 static SymbolRef findFailedReallocSymbol(ProgramStateRef currState,
3132                                          ProgramStateRef prevState) {
3133   ReallocPairsTy currMap = currState->get<ReallocPairs>();
3134   ReallocPairsTy prevMap = prevState->get<ReallocPairs>();
3135 
3136   for (const ReallocPairsTy::value_type &Pair : prevMap) {
3137     SymbolRef sym = Pair.first;
3138     if (!currMap.lookup(sym))
3139       return sym;
3140   }
3141 
3142   return nullptr;
3143 }
3144 
isReferenceCountingPointerDestructor(const CXXDestructorDecl * DD)3145 static bool isReferenceCountingPointerDestructor(const CXXDestructorDecl *DD) {
3146   if (const IdentifierInfo *II = DD->getParent()->getIdentifier()) {
3147     StringRef N = II->getName();
3148     if (N.contains_insensitive("ptr") || N.contains_insensitive("pointer")) {
3149       if (N.contains_insensitive("ref") || N.contains_insensitive("cnt") ||
3150           N.contains_insensitive("intrusive") ||
3151           N.contains_insensitive("shared")) {
3152         return true;
3153       }
3154     }
3155   }
3156   return false;
3157 }
3158 
VisitNode(const ExplodedNode * N,BugReporterContext & BRC,PathSensitiveBugReport & BR)3159 PathDiagnosticPieceRef MallocBugVisitor::VisitNode(const ExplodedNode *N,
3160                                                    BugReporterContext &BRC,
3161                                                    PathSensitiveBugReport &BR) {
3162   ProgramStateRef state = N->getState();
3163   ProgramStateRef statePrev = N->getFirstPred()->getState();
3164 
3165   const RefState *RSCurr = state->get<RegionState>(Sym);
3166   const RefState *RSPrev = statePrev->get<RegionState>(Sym);
3167 
3168   const Stmt *S = N->getStmtForDiagnostics();
3169   // When dealing with containers, we sometimes want to give a note
3170   // even if the statement is missing.
3171   if (!S && (!RSCurr || RSCurr->getAllocationFamily() != AF_InnerBuffer))
3172     return nullptr;
3173 
3174   const LocationContext *CurrentLC = N->getLocationContext();
3175 
3176   // If we find an atomic fetch_add or fetch_sub within the destructor in which
3177   // the pointer was released (before the release), this is likely a destructor
3178   // of a shared pointer.
3179   // Because we don't model atomics, and also because we don't know that the
3180   // original reference count is positive, we should not report use-after-frees
3181   // on objects deleted in such destructors. This can probably be improved
3182   // through better shared pointer modeling.
3183   if (ReleaseDestructorLC) {
3184     if (const auto *AE = dyn_cast<AtomicExpr>(S)) {
3185       AtomicExpr::AtomicOp Op = AE->getOp();
3186       if (Op == AtomicExpr::AO__c11_atomic_fetch_add ||
3187           Op == AtomicExpr::AO__c11_atomic_fetch_sub) {
3188         if (ReleaseDestructorLC == CurrentLC ||
3189             ReleaseDestructorLC->isParentOf(CurrentLC)) {
3190           BR.markInvalid(getTag(), S);
3191         }
3192       }
3193     }
3194   }
3195 
3196   // FIXME: We will eventually need to handle non-statement-based events
3197   // (__attribute__((cleanup))).
3198 
3199   // Find out if this is an interesting point and what is the kind.
3200   StringRef Msg;
3201   std::unique_ptr<StackHintGeneratorForSymbol> StackHint = nullptr;
3202   SmallString<256> Buf;
3203   llvm::raw_svector_ostream OS(Buf);
3204 
3205   if (Mode == Normal) {
3206     if (isAllocated(RSCurr, RSPrev, S)) {
3207       Msg = "Memory is allocated";
3208       StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3209           Sym, "Returned allocated memory");
3210     } else if (isReleased(RSCurr, RSPrev, S)) {
3211       const auto Family = RSCurr->getAllocationFamily();
3212       switch (Family) {
3213         case AF_Alloca:
3214         case AF_Malloc:
3215         case AF_CXXNew:
3216         case AF_CXXNewArray:
3217         case AF_IfNameIndex:
3218           Msg = "Memory is released";
3219           StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3220               Sym, "Returning; memory was released");
3221           break;
3222         case AF_InnerBuffer: {
3223           const MemRegion *ObjRegion =
3224               allocation_state::getContainerObjRegion(statePrev, Sym);
3225           const auto *TypedRegion = cast<TypedValueRegion>(ObjRegion);
3226           QualType ObjTy = TypedRegion->getValueType();
3227           OS << "Inner buffer of '" << ObjTy.getAsString() << "' ";
3228 
3229           if (N->getLocation().getKind() == ProgramPoint::PostImplicitCallKind) {
3230             OS << "deallocated by call to destructor";
3231             StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3232                 Sym, "Returning; inner buffer was deallocated");
3233           } else {
3234             OS << "reallocated by call to '";
3235             const Stmt *S = RSCurr->getStmt();
3236             if (const auto *MemCallE = dyn_cast<CXXMemberCallExpr>(S)) {
3237               OS << MemCallE->getMethodDecl()->getDeclName();
3238             } else if (const auto *OpCallE = dyn_cast<CXXOperatorCallExpr>(S)) {
3239               OS << OpCallE->getDirectCallee()->getDeclName();
3240             } else if (const auto *CallE = dyn_cast<CallExpr>(S)) {
3241               auto &CEMgr = BRC.getStateManager().getCallEventManager();
3242               CallEventRef<> Call = CEMgr.getSimpleCall(CallE, state, CurrentLC);
3243               if (const auto *D = dyn_cast_or_null<NamedDecl>(Call->getDecl()))
3244                 OS << D->getDeclName();
3245               else
3246                 OS << "unknown";
3247             }
3248             OS << "'";
3249             StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3250                 Sym, "Returning; inner buffer was reallocated");
3251           }
3252           Msg = OS.str();
3253           break;
3254         }
3255         case AF_None:
3256           llvm_unreachable("Unhandled allocation family!");
3257       }
3258 
3259       // See if we're releasing memory while inlining a destructor
3260       // (or one of its callees). This turns on various common
3261       // false positive suppressions.
3262       bool FoundAnyDestructor = false;
3263       for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) {
3264         if (const auto *DD = dyn_cast<CXXDestructorDecl>(LC->getDecl())) {
3265           if (isReferenceCountingPointerDestructor(DD)) {
3266             // This immediately looks like a reference-counting destructor.
3267             // We're bad at guessing the original reference count of the object,
3268             // so suppress the report for now.
3269             BR.markInvalid(getTag(), DD);
3270           } else if (!FoundAnyDestructor) {
3271             assert(!ReleaseDestructorLC &&
3272                    "There can be only one release point!");
3273             // Suspect that it's a reference counting pointer destructor.
3274             // On one of the next nodes might find out that it has atomic
3275             // reference counting operations within it (see the code above),
3276             // and if so, we'd conclude that it likely is a reference counting
3277             // pointer destructor.
3278             ReleaseDestructorLC = LC->getStackFrame();
3279             // It is unlikely that releasing memory is delegated to a destructor
3280             // inside a destructor of a shared pointer, because it's fairly hard
3281             // to pass the information that the pointer indeed needs to be
3282             // released into it. So we're only interested in the innermost
3283             // destructor.
3284             FoundAnyDestructor = true;
3285           }
3286         }
3287       }
3288     } else if (isRelinquished(RSCurr, RSPrev, S)) {
3289       Msg = "Memory ownership is transferred";
3290       StackHint = std::make_unique<StackHintGeneratorForSymbol>(Sym, "");
3291     } else if (hasReallocFailed(RSCurr, RSPrev, S)) {
3292       Mode = ReallocationFailed;
3293       Msg = "Reallocation failed";
3294       StackHint = std::make_unique<StackHintGeneratorForReallocationFailed>(
3295           Sym, "Reallocation failed");
3296 
3297       if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
3298         // Is it possible to fail two reallocs WITHOUT testing in between?
3299         assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
3300           "We only support one failed realloc at a time.");
3301         BR.markInteresting(sym);
3302         FailedReallocSymbol = sym;
3303       }
3304     }
3305 
3306   // We are in a special mode if a reallocation failed later in the path.
3307   } else if (Mode == ReallocationFailed) {
3308     assert(FailedReallocSymbol && "No symbol to look for.");
3309 
3310     // Is this is the first appearance of the reallocated symbol?
3311     if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
3312       // We're at the reallocation point.
3313       Msg = "Attempt to reallocate memory";
3314       StackHint = std::make_unique<StackHintGeneratorForSymbol>(
3315           Sym, "Returned reallocated memory");
3316       FailedReallocSymbol = nullptr;
3317       Mode = Normal;
3318     }
3319   }
3320 
3321   if (Msg.empty()) {
3322     assert(!StackHint);
3323     return nullptr;
3324   }
3325 
3326   assert(StackHint);
3327 
3328   // Generate the extra diagnostic.
3329   PathDiagnosticLocation Pos;
3330   if (!S) {
3331     assert(RSCurr->getAllocationFamily() == AF_InnerBuffer);
3332     auto PostImplCall = N->getLocation().getAs<PostImplicitCall>();
3333     if (!PostImplCall)
3334       return nullptr;
3335     Pos = PathDiagnosticLocation(PostImplCall->getLocation(),
3336                                  BRC.getSourceManager());
3337   } else {
3338     Pos = PathDiagnosticLocation(S, BRC.getSourceManager(),
3339                                  N->getLocationContext());
3340   }
3341 
3342   auto P = std::make_shared<PathDiagnosticEventPiece>(Pos, Msg, true);
3343   BR.addCallStackHint(P, std::move(StackHint));
3344   return P;
3345 }
3346 
printState(raw_ostream & Out,ProgramStateRef State,const char * NL,const char * Sep) const3347 void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State,
3348                                const char *NL, const char *Sep) const {
3349 
3350   RegionStateTy RS = State->get<RegionState>();
3351 
3352   if (!RS.isEmpty()) {
3353     Out << Sep << "MallocChecker :" << NL;
3354     for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
3355       const RefState *RefS = State->get<RegionState>(I.getKey());
3356       AllocationFamily Family = RefS->getAllocationFamily();
3357       Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
3358       if (!CheckKind.hasValue())
3359          CheckKind = getCheckIfTracked(Family, true);
3360 
3361       I.getKey()->dumpToStream(Out);
3362       Out << " : ";
3363       I.getData().dump(Out);
3364       if (CheckKind.hasValue())
3365         Out << " (" << CheckNames[*CheckKind].getName() << ")";
3366       Out << NL;
3367     }
3368   }
3369 }
3370 
3371 namespace clang {
3372 namespace ento {
3373 namespace allocation_state {
3374 
3375 ProgramStateRef
markReleased(ProgramStateRef State,SymbolRef Sym,const Expr * Origin)3376 markReleased(ProgramStateRef State, SymbolRef Sym, const Expr *Origin) {
3377   AllocationFamily Family = AF_InnerBuffer;
3378   return State->set<RegionState>(Sym, RefState::getReleased(Family, Origin));
3379 }
3380 
3381 } // end namespace allocation_state
3382 } // end namespace ento
3383 } // end namespace clang
3384 
3385 // Intended to be used in InnerPointerChecker to register the part of
3386 // MallocChecker connected to it.
registerInnerPointerCheckerAux(CheckerManager & mgr)3387 void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) {
3388   MallocChecker *checker = mgr.getChecker<MallocChecker>();
3389   checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true;
3390   checker->CheckNames[MallocChecker::CK_InnerPointerChecker] =
3391       mgr.getCurrentCheckerName();
3392 }
3393 
registerDynamicMemoryModeling(CheckerManager & mgr)3394 void ento::registerDynamicMemoryModeling(CheckerManager &mgr) {
3395   auto *checker = mgr.registerChecker<MallocChecker>();
3396   checker->ShouldIncludeOwnershipAnnotatedFunctions =
3397       mgr.getAnalyzerOptions().getCheckerBooleanOption(checker, "Optimistic");
3398 }
3399 
shouldRegisterDynamicMemoryModeling(const CheckerManager & mgr)3400 bool ento::shouldRegisterDynamicMemoryModeling(const CheckerManager &mgr) {
3401   return true;
3402 }
3403 
3404 #define REGISTER_CHECKER(name)                                                 \
3405   void ento::register##name(CheckerManager &mgr) {                             \
3406     MallocChecker *checker = mgr.getChecker<MallocChecker>();                  \
3407     checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
3408     checker->CheckNames[MallocChecker::CK_##name] =                            \
3409         mgr.getCurrentCheckerName();                                           \
3410   }                                                                            \
3411                                                                                \
3412   bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
3413 
3414 REGISTER_CHECKER(MallocChecker)
3415 REGISTER_CHECKER(NewDeleteChecker)
3416 REGISTER_CHECKER(NewDeleteLeaksChecker)
3417 REGISTER_CHECKER(MismatchedDeallocatorChecker)
3418