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