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