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