1 //=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines a variety of memory management related checkers, such as
10 // leak, double free, and use-after-free.
12 // The following checkers are defined here:
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
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.
29 // Enables the modeling of new, new[], delete, delete[] in MallocChecker,
30 // and checks for related double-free and use-after-free errors.
32 // * NewDeleteLeaksChecker
33 // Checks for leaks related to new, new[], delete, delete[].
34 // Depends on NewDeleteChecker.
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[].
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.
45 //===----------------------------------------------------------------------===//
47 #include "AllocationState.h"
48 #include "InterCheckerAPI.h"
49 #include "clang/AST/Attr.h"
50 #include "clang/AST/DeclCXX.h"
51 #include "clang/AST/DeclTemplate.h"
52 #include "clang/AST/Expr.h"
53 #include "clang/AST/ExprCXX.h"
54 #include "clang/AST/ParentMap.h"
55 #include "clang/ASTMatchers/ASTMatchFinder.h"
56 #include "clang/ASTMatchers/ASTMatchers.h"
57 #include "clang/Analysis/ProgramPoint.h"
58 #include "clang/Basic/LLVM.h"
59 #include "clang/Basic/SourceManager.h"
60 #include "clang/Basic/TargetInfo.h"
61 #include "clang/Lex/Lexer.h"
62 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
63 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
64 #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
65 #include "clang/StaticAnalyzer/Core/Checker.h"
66 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
67 #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
68 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
69 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
70 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
71 #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
72 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
73 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
74 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
75 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
76 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
77 #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
78 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
79 #include "llvm/ADT/STLExtras.h"
80 #include "llvm/ADT/SetOperations.h"
81 #include "llvm/ADT/SmallString.h"
82 #include "llvm/ADT/StringExtras.h"
83 #include "llvm/Support/Casting.h"
84 #include "llvm/Support/Compiler.h"
85 #include "llvm/Support/ErrorHandling.h"
86 #include "llvm/Support/raw_ostream.h"
92 using namespace clang
;
94 using namespace std::placeholders
;
96 //===----------------------------------------------------------------------===//
97 // The types of allocation we're modeling. This is used to check whether a
98 // dynamically allocated object is deallocated with the correct function, like
99 // not using operator delete on an object created by malloc(), or alloca regions
100 // aren't ever deallocated manually.
101 //===----------------------------------------------------------------------===//
105 // Used to check correspondence between allocators and deallocators.
106 enum AllocationFamily
{
116 } // end of anonymous namespace
118 /// Print names of allocators and deallocators.
120 /// \returns true on success.
121 static bool printMemFnName(raw_ostream
&os
, CheckerContext
&C
, const Expr
*E
);
123 /// Print expected name of an allocator based on the deallocator's family
124 /// derived from the DeallocExpr.
125 static void printExpectedAllocName(raw_ostream
&os
, AllocationFamily Family
);
127 /// Print expected name of a deallocator based on the allocator's
129 static void printExpectedDeallocName(raw_ostream
&os
, AllocationFamily Family
);
131 //===----------------------------------------------------------------------===//
132 // The state of a symbol, in terms of memory management.
133 //===----------------------------------------------------------------------===//
139 // Reference to allocated memory.
141 // Reference to zero-allocated memory.
143 // Reference to released/freed memory.
145 // The responsibility for freeing resources has transferred from
146 // this reference. A relinquished symbol should not be freed.
148 // We are no longer guaranteed to have observed all manipulations
149 // of this pointer/memory. For example, it could have been
150 // passed as a parameter to an opaque function.
157 AllocationFamily Family
;
159 RefState(Kind k
, const Stmt
*s
, AllocationFamily family
)
160 : S(s
), K(k
), Family(family
) {
161 assert(family
!= AF_None
);
165 bool isAllocated() const { return K
== Allocated
; }
166 bool isAllocatedOfSizeZero() const { return K
== AllocatedOfSizeZero
; }
167 bool isReleased() const { return K
== Released
; }
168 bool isRelinquished() const { return K
== Relinquished
; }
169 bool isEscaped() const { return K
== Escaped
; }
170 AllocationFamily
getAllocationFamily() const { return Family
; }
171 const Stmt
*getStmt() const { return S
; }
173 bool operator==(const RefState
&X
) const {
174 return K
== X
.K
&& S
== X
.S
&& Family
== X
.Family
;
177 static RefState
getAllocated(AllocationFamily family
, const Stmt
*s
) {
178 return RefState(Allocated
, s
, family
);
180 static RefState
getAllocatedOfSizeZero(const RefState
*RS
) {
181 return RefState(AllocatedOfSizeZero
, RS
->getStmt(),
182 RS
->getAllocationFamily());
184 static RefState
getReleased(AllocationFamily family
, const Stmt
*s
) {
185 return RefState(Released
, s
, family
);
187 static RefState
getRelinquished(AllocationFamily family
, const Stmt
*s
) {
188 return RefState(Relinquished
, s
, family
);
190 static RefState
getEscaped(const RefState
*RS
) {
191 return RefState(Escaped
, RS
->getStmt(), RS
->getAllocationFamily());
194 void Profile(llvm::FoldingSetNodeID
&ID
) const {
197 ID
.AddInteger(Family
);
200 LLVM_DUMP_METHOD
void dump(raw_ostream
&OS
) const {
202 #define CASE(ID) case ID: OS << #ID; break;
204 CASE(AllocatedOfSizeZero
)
211 LLVM_DUMP_METHOD
void dump() const { dump(llvm::errs()); }
214 } // end of anonymous namespace
216 REGISTER_MAP_WITH_PROGRAMSTATE(RegionState
, SymbolRef
, RefState
)
218 /// Check if the memory associated with this symbol was released.
219 static bool isReleased(SymbolRef Sym
, CheckerContext
&C
);
221 /// Update the RefState to reflect the new memory allocation.
222 /// The optional \p RetVal parameter specifies the newly allocated pointer
223 /// value; if unspecified, the value of expression \p E is used.
224 static ProgramStateRef
225 MallocUpdateRefState(CheckerContext
&C
, const Expr
*E
, ProgramStateRef State
,
226 AllocationFamily Family
,
227 std::optional
<SVal
> RetVal
= std::nullopt
);
229 //===----------------------------------------------------------------------===//
230 // The modeling of memory reallocation.
232 // The terminology 'toPtr' and 'fromPtr' will be used:
233 // toPtr = realloc(fromPtr, 20);
234 //===----------------------------------------------------------------------===//
236 REGISTER_SET_WITH_PROGRAMSTATE(ReallocSizeZeroSymbols
, SymbolRef
)
240 /// The state of 'fromPtr' after reallocation is known to have failed.
241 enum OwnershipAfterReallocKind
{
242 // The symbol needs to be freed (e.g.: realloc)
243 OAR_ToBeFreedAfterFailure
,
244 // The symbol has been freed (e.g.: reallocf)
246 // The symbol doesn't have to freed (e.g.: we aren't sure if, how and where
247 // 'fromPtr' was allocated:
248 // void Haha(int *ptr) {
249 // ptr = realloc(ptr, 67);
253 OAR_DoNotTrackAfterFailure
256 /// Stores information about the 'fromPtr' symbol after reallocation.
258 /// This is important because realloc may fail, and that needs special modeling.
259 /// Whether reallocation failed or not will not be known until later, so we'll
260 /// store whether upon failure 'fromPtr' will be freed, or needs to be freed
265 SymbolRef ReallocatedSym
;
266 OwnershipAfterReallocKind Kind
;
268 ReallocPair(SymbolRef S
, OwnershipAfterReallocKind K
)
269 : ReallocatedSym(S
), Kind(K
) {}
270 void Profile(llvm::FoldingSetNodeID
&ID
) const {
272 ID
.AddPointer(ReallocatedSym
);
274 bool operator==(const ReallocPair
&X
) const {
275 return ReallocatedSym
== X
.ReallocatedSym
&&
280 } // end of anonymous namespace
282 REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs
, SymbolRef
, ReallocPair
)
284 /// Tells if the callee is one of the builtin new/delete operators, including
285 /// placement operators and other standard overloads.
286 static bool isStandardNewDelete(const FunctionDecl
*FD
);
287 static bool isStandardNewDelete(const CallEvent
&Call
) {
288 if (!Call
.getDecl() || !isa
<FunctionDecl
>(Call
.getDecl()))
290 return isStandardNewDelete(cast
<FunctionDecl
>(Call
.getDecl()));
293 //===----------------------------------------------------------------------===//
294 // Definition of the MallocChecker class.
295 //===----------------------------------------------------------------------===//
300 : public Checker
<check::DeadSymbols
, check::PointerEscape
,
301 check::ConstPointerEscape
, check::PreStmt
<ReturnStmt
>,
302 check::EndFunction
, check::PreCall
, check::PostCall
,
303 check::NewAllocator
, check::PostStmt
<BlockExpr
>,
304 check::PostObjCMessage
, check::Location
, eval::Assume
> {
306 /// In pessimistic mode, the checker assumes that it does not know which
307 /// functions might free the memory.
308 /// In optimistic mode, the checker assumes that all user-defined functions
309 /// which might free a pointer are annotated.
310 bool ShouldIncludeOwnershipAnnotatedFunctions
= false;
312 bool ShouldRegisterNoOwnershipChangeVisitor
= false;
314 /// Many checkers are essentially built into this one, so enabling them will
315 /// make MallocChecker perform additional modeling and reporting.
317 /// When a subchecker is enabled but MallocChecker isn't, model memory
318 /// management but do not emit warnings emitted with MallocChecker only
322 CK_NewDeleteLeaksChecker
,
323 CK_MismatchedDeallocatorChecker
,
324 CK_InnerPointerChecker
,
328 using LeakInfo
= std::pair
<const ExplodedNode
*, const MemRegion
*>;
330 bool ChecksEnabled
[CK_NumCheckKinds
] = {false};
331 CheckerNameRef CheckNames
[CK_NumCheckKinds
];
333 void checkPreCall(const CallEvent
&Call
, CheckerContext
&C
) const;
334 void checkPostCall(const CallEvent
&Call
, CheckerContext
&C
) const;
335 void checkNewAllocator(const CXXAllocatorCall
&Call
, CheckerContext
&C
) const;
336 void checkPostObjCMessage(const ObjCMethodCall
&Call
, CheckerContext
&C
) const;
337 void checkPostStmt(const BlockExpr
*BE
, CheckerContext
&C
) const;
338 void checkDeadSymbols(SymbolReaper
&SymReaper
, CheckerContext
&C
) const;
339 void checkPreStmt(const ReturnStmt
*S
, CheckerContext
&C
) const;
340 void checkEndFunction(const ReturnStmt
*S
, CheckerContext
&C
) const;
341 ProgramStateRef
evalAssume(ProgramStateRef state
, SVal Cond
,
342 bool Assumption
) const;
343 void checkLocation(SVal l
, bool isLoad
, const Stmt
*S
,
344 CheckerContext
&C
) const;
346 ProgramStateRef
checkPointerEscape(ProgramStateRef State
,
347 const InvalidatedSymbols
&Escaped
,
348 const CallEvent
*Call
,
349 PointerEscapeKind Kind
) const;
350 ProgramStateRef
checkConstPointerEscape(ProgramStateRef State
,
351 const InvalidatedSymbols
&Escaped
,
352 const CallEvent
*Call
,
353 PointerEscapeKind Kind
) const;
355 void printState(raw_ostream
&Out
, ProgramStateRef State
,
356 const char *NL
, const char *Sep
) const override
;
359 mutable std::unique_ptr
<BugType
> BT_DoubleFree
[CK_NumCheckKinds
];
360 mutable std::unique_ptr
<BugType
> BT_DoubleDelete
;
361 mutable std::unique_ptr
<BugType
> BT_Leak
[CK_NumCheckKinds
];
362 mutable std::unique_ptr
<BugType
> BT_UseFree
[CK_NumCheckKinds
];
363 mutable std::unique_ptr
<BugType
> BT_BadFree
[CK_NumCheckKinds
];
364 mutable std::unique_ptr
<BugType
> BT_FreeAlloca
[CK_NumCheckKinds
];
365 mutable std::unique_ptr
<BugType
> BT_MismatchedDealloc
;
366 mutable std::unique_ptr
<BugType
> BT_OffsetFree
[CK_NumCheckKinds
];
367 mutable std::unique_ptr
<BugType
> BT_UseZerroAllocated
[CK_NumCheckKinds
];
369 #define CHECK_FN(NAME) \
370 void NAME(const CallEvent &Call, CheckerContext &C) const;
373 CHECK_FN(checkIfNameIndex
)
374 CHECK_FN(checkBasicAlloc
)
375 CHECK_FN(checkKernelMalloc
)
376 CHECK_FN(checkCalloc
)
377 CHECK_FN(checkAlloca
)
378 CHECK_FN(checkStrdup
)
379 CHECK_FN(checkIfFreeNameIndex
)
380 CHECK_FN(checkCXXNewOrCXXDelete
)
381 CHECK_FN(checkGMalloc0
)
382 CHECK_FN(checkGMemdup
)
383 CHECK_FN(checkGMallocN
)
384 CHECK_FN(checkGMallocN0
)
385 CHECK_FN(checkReallocN
)
386 CHECK_FN(checkOwnershipAttr
)
388 void checkRealloc(const CallEvent
&Call
, CheckerContext
&C
,
389 bool ShouldFreeOnFail
) const;
391 using CheckFn
= std::function
<void(const MallocChecker
*,
392 const CallEvent
&Call
, CheckerContext
&C
)>;
394 const CallDescriptionMap
<CheckFn
> FreeingMemFnMap
{
395 {{{"free"}, 1}, &MallocChecker::checkFree
},
396 {{{"if_freenameindex"}, 1}, &MallocChecker::checkIfFreeNameIndex
},
397 {{{"kfree"}, 1}, &MallocChecker::checkFree
},
398 {{{"g_free"}, 1}, &MallocChecker::checkFree
},
401 bool isFreeingCall(const CallEvent
&Call
) const;
402 static bool isFreeingOwnershipAttrCall(const FunctionDecl
*Func
);
404 friend class NoOwnershipChangeVisitor
;
406 CallDescriptionMap
<CheckFn
> AllocatingMemFnMap
{
407 {{{"alloca"}, 1}, &MallocChecker::checkAlloca
},
408 {{{"_alloca"}, 1}, &MallocChecker::checkAlloca
},
409 {{{"malloc"}, 1}, &MallocChecker::checkBasicAlloc
},
410 {{{"malloc"}, 3}, &MallocChecker::checkKernelMalloc
},
411 {{{"calloc"}, 2}, &MallocChecker::checkCalloc
},
412 {{{"valloc"}, 1}, &MallocChecker::checkBasicAlloc
},
413 {{CDF_MaybeBuiltin
, {"strndup"}, 2}, &MallocChecker::checkStrdup
},
414 {{CDF_MaybeBuiltin
, {"strdup"}, 1}, &MallocChecker::checkStrdup
},
415 {{{"_strdup"}, 1}, &MallocChecker::checkStrdup
},
416 {{{"kmalloc"}, 2}, &MallocChecker::checkKernelMalloc
},
417 {{{"if_nameindex"}, 1}, &MallocChecker::checkIfNameIndex
},
418 {{CDF_MaybeBuiltin
, {"wcsdup"}, 1}, &MallocChecker::checkStrdup
},
419 {{CDF_MaybeBuiltin
, {"_wcsdup"}, 1}, &MallocChecker::checkStrdup
},
420 {{{"g_malloc"}, 1}, &MallocChecker::checkBasicAlloc
},
421 {{{"g_malloc0"}, 1}, &MallocChecker::checkGMalloc0
},
422 {{{"g_try_malloc"}, 1}, &MallocChecker::checkBasicAlloc
},
423 {{{"g_try_malloc0"}, 1}, &MallocChecker::checkGMalloc0
},
424 {{{"g_memdup"}, 2}, &MallocChecker::checkGMemdup
},
425 {{{"g_malloc_n"}, 2}, &MallocChecker::checkGMallocN
},
426 {{{"g_malloc0_n"}, 2}, &MallocChecker::checkGMallocN0
},
427 {{{"g_try_malloc_n"}, 2}, &MallocChecker::checkGMallocN
},
428 {{{"g_try_malloc0_n"}, 2}, &MallocChecker::checkGMallocN0
},
431 CallDescriptionMap
<CheckFn
> ReallocatingMemFnMap
{
433 std::bind(&MallocChecker::checkRealloc
, _1
, _2
, _3
, false)},
435 std::bind(&MallocChecker::checkRealloc
, _1
, _2
, _3
, true)},
437 std::bind(&MallocChecker::checkRealloc
, _1
, _2
, _3
, false)},
438 {{{"g_try_realloc"}, 2},
439 std::bind(&MallocChecker::checkRealloc
, _1
, _2
, _3
, false)},
440 {{{"g_realloc_n"}, 3}, &MallocChecker::checkReallocN
},
441 {{{"g_try_realloc_n"}, 3}, &MallocChecker::checkReallocN
},
444 bool isMemCall(const CallEvent
&Call
) const;
446 // TODO: Remove mutable by moving the initializtaion to the registry function.
447 mutable std::optional
<uint64_t> KernelZeroFlagVal
;
449 using KernelZeroSizePtrValueTy
= std::optional
<int>;
450 /// Store the value of macro called `ZERO_SIZE_PTR`.
451 /// The value is initialized at first use, before first use the outer
452 /// Optional is empty, afterwards it contains another Optional that indicates
453 /// if the macro value could be determined, and if yes the value itself.
454 mutable std::optional
<KernelZeroSizePtrValueTy
> KernelZeroSizePtrValue
;
456 /// Process C++ operator new()'s allocation, which is the part of C++
457 /// new-expression that goes before the constructor.
458 [[nodiscard
]] ProgramStateRef
459 processNewAllocation(const CXXAllocatorCall
&Call
, CheckerContext
&C
,
460 AllocationFamily Family
) const;
462 /// Perform a zero-allocation check.
464 /// \param [in] Call The expression that allocates memory.
465 /// \param [in] IndexOfSizeArg Index of the argument that specifies the size
466 /// of the memory that needs to be allocated. E.g. for malloc, this would be
468 /// \param [in] RetVal Specifies the newly allocated pointer value;
469 /// if unspecified, the value of expression \p E is used.
470 [[nodiscard
]] static ProgramStateRef
471 ProcessZeroAllocCheck(const CallEvent
&Call
, const unsigned IndexOfSizeArg
,
472 ProgramStateRef State
,
473 std::optional
<SVal
> RetVal
= std::nullopt
);
475 /// Model functions with the ownership_returns attribute.
477 /// User-defined function may have the ownership_returns attribute, which
478 /// annotates that the function returns with an object that was allocated on
479 /// the heap, and passes the ownertship to the callee.
481 /// void __attribute((ownership_returns(malloc, 1))) *my_malloc(size_t);
483 /// It has two parameters:
484 /// - first: name of the resource (e.g. 'malloc')
485 /// - (OPTIONAL) second: size of the allocated region
487 /// \param [in] Call The expression that allocates memory.
488 /// \param [in] Att The ownership_returns attribute.
489 /// \param [in] State The \c ProgramState right before allocation.
490 /// \returns The ProgramState right after allocation.
491 [[nodiscard
]] ProgramStateRef
492 MallocMemReturnsAttr(CheckerContext
&C
, const CallEvent
&Call
,
493 const OwnershipAttr
*Att
, ProgramStateRef State
) const;
495 /// Models memory allocation.
497 /// \param [in] Call The expression that allocates memory.
498 /// \param [in] SizeEx Size of the memory that needs to be allocated.
499 /// \param [in] Init The value the allocated memory needs to be initialized.
500 /// with. For example, \c calloc initializes the allocated memory to 0,
501 /// malloc leaves it undefined.
502 /// \param [in] State The \c ProgramState right before allocation.
503 /// \returns The ProgramState right after allocation.
504 [[nodiscard
]] static ProgramStateRef
505 MallocMemAux(CheckerContext
&C
, const CallEvent
&Call
, const Expr
*SizeEx
,
506 SVal Init
, ProgramStateRef State
, AllocationFamily Family
);
508 /// Models memory allocation.
510 /// \param [in] Call The expression that allocates memory.
511 /// \param [in] Size Size of the memory that needs to be allocated.
512 /// \param [in] Init The value the allocated memory needs to be initialized.
513 /// with. For example, \c calloc initializes the allocated memory to 0,
514 /// malloc leaves it undefined.
515 /// \param [in] State The \c ProgramState right before allocation.
516 /// \returns The ProgramState right after allocation.
517 [[nodiscard
]] static ProgramStateRef
518 MallocMemAux(CheckerContext
&C
, const CallEvent
&Call
, SVal Size
, SVal Init
,
519 ProgramStateRef State
, AllocationFamily Family
);
521 // Check if this malloc() for special flags. At present that means M_ZERO or
522 // __GFP_ZERO (in which case, treat it like calloc).
523 [[nodiscard
]] std::optional
<ProgramStateRef
>
524 performKernelMalloc(const CallEvent
&Call
, CheckerContext
&C
,
525 const ProgramStateRef
&State
) const;
527 /// Model functions with the ownership_takes and ownership_holds attributes.
529 /// User-defined function may have the ownership_takes and/or ownership_holds
530 /// attributes, which annotates that the function frees the memory passed as a
533 /// void __attribute((ownership_takes(malloc, 1))) my_free(void *);
534 /// void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
536 /// They have two parameters:
537 /// - first: name of the resource (e.g. 'malloc')
538 /// - second: index of the parameter the attribute applies to
540 /// \param [in] Call The expression that frees memory.
541 /// \param [in] Att The ownership_takes or ownership_holds attribute.
542 /// \param [in] State The \c ProgramState right before allocation.
543 /// \returns The ProgramState right after deallocation.
544 [[nodiscard
]] ProgramStateRef
FreeMemAttr(CheckerContext
&C
,
545 const CallEvent
&Call
,
546 const OwnershipAttr
*Att
,
547 ProgramStateRef State
) const;
549 /// Models memory deallocation.
551 /// \param [in] Call The expression that frees memory.
552 /// \param [in] State The \c ProgramState right before allocation.
553 /// \param [in] Num Index of the argument that needs to be freed. This is
554 /// normally 0, but for custom free functions it may be different.
555 /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds
557 /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known
558 /// to have been allocated, or in other words, the symbol to be freed was
559 /// registered as allocated by this checker. In the following case, \c ptr
560 /// isn't known to be allocated.
561 /// void Haha(int *ptr) {
562 /// ptr = realloc(ptr, 67);
565 /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function
566 /// we're modeling returns with Null on failure.
567 /// \returns The ProgramState right after deallocation.
568 [[nodiscard
]] ProgramStateRef
569 FreeMemAux(CheckerContext
&C
, const CallEvent
&Call
, ProgramStateRef State
,
570 unsigned Num
, bool Hold
, bool &IsKnownToBeAllocated
,
571 AllocationFamily Family
, bool ReturnsNullOnFailure
= false) const;
573 /// Models memory deallocation.
575 /// \param [in] ArgExpr The variable who's pointee needs to be freed.
576 /// \param [in] Call The expression that frees the memory.
577 /// \param [in] State The \c ProgramState right before allocation.
578 /// normally 0, but for custom free functions it may be different.
579 /// \param [in] Hold Whether the parameter at \p Index has the ownership_holds
581 /// \param [out] IsKnownToBeAllocated Whether the memory to be freed is known
582 /// to have been allocated, or in other words, the symbol to be freed was
583 /// registered as allocated by this checker. In the following case, \c ptr
584 /// isn't known to be allocated.
585 /// void Haha(int *ptr) {
586 /// ptr = realloc(ptr, 67);
589 /// \param [in] ReturnsNullOnFailure Whether the memory deallocation function
590 /// we're modeling returns with Null on failure.
591 /// \returns The ProgramState right after deallocation.
592 [[nodiscard
]] ProgramStateRef
593 FreeMemAux(CheckerContext
&C
, const Expr
*ArgExpr
, const CallEvent
&Call
,
594 ProgramStateRef State
, bool Hold
, bool &IsKnownToBeAllocated
,
595 AllocationFamily Family
, bool ReturnsNullOnFailure
= false) const;
597 // TODO: Needs some refactoring, as all other deallocation modeling
598 // functions are suffering from out parameters and messy code due to how
599 // realloc is handled.
601 /// Models memory reallocation.
603 /// \param [in] Call The expression that reallocated memory
604 /// \param [in] ShouldFreeOnFail Whether if reallocation fails, the supplied
605 /// memory should be freed.
606 /// \param [in] State The \c ProgramState right before reallocation.
607 /// \param [in] SuffixWithN Whether the reallocation function we're modeling
608 /// has an '_n' suffix, such as g_realloc_n.
609 /// \returns The ProgramState right after reallocation.
610 [[nodiscard
]] ProgramStateRef
611 ReallocMemAux(CheckerContext
&C
, const CallEvent
&Call
, bool ShouldFreeOnFail
,
612 ProgramStateRef State
, AllocationFamily Family
,
613 bool SuffixWithN
= false) const;
615 /// Evaluates the buffer size that needs to be allocated.
617 /// \param [in] Blocks The amount of blocks that needs to be allocated.
618 /// \param [in] BlockBytes The size of a block.
619 /// \returns The symbolic value of \p Blocks * \p BlockBytes.
620 [[nodiscard
]] static SVal
evalMulForBufferSize(CheckerContext
&C
,
622 const Expr
*BlockBytes
);
624 /// Models zero initialized array allocation.
626 /// \param [in] Call The expression that reallocated memory
627 /// \param [in] State The \c ProgramState right before reallocation.
628 /// \returns The ProgramState right after allocation.
629 [[nodiscard
]] static ProgramStateRef
630 CallocMem(CheckerContext
&C
, const CallEvent
&Call
, ProgramStateRef State
);
632 /// See if deallocation happens in a suspicious context. If so, escape the
633 /// pointers that otherwise would have been deallocated and return true.
634 bool suppressDeallocationsInSuspiciousContexts(const CallEvent
&Call
,
635 CheckerContext
&C
) const;
637 /// If in \p S \p Sym is used, check whether \p Sym was already freed.
638 bool checkUseAfterFree(SymbolRef Sym
, CheckerContext
&C
, const Stmt
*S
) const;
640 /// If in \p S \p Sym is used, check whether \p Sym was allocated as a zero
641 /// sized memory region.
642 void checkUseZeroAllocated(SymbolRef Sym
, CheckerContext
&C
,
643 const Stmt
*S
) const;
645 /// If in \p S \p Sym is being freed, check whether \p Sym was already freed.
646 bool checkDoubleDelete(SymbolRef Sym
, CheckerContext
&C
) const;
648 /// Check if the function is known to free memory, or if it is
649 /// "interesting" and should be modeled explicitly.
651 /// \param [out] EscapingSymbol A function might not free memory in general,
652 /// but could be known to free a particular symbol. In this case, false is
653 /// returned and the single escaping symbol is returned through the out
656 /// We assume that pointers do not escape through calls to system functions
657 /// not handled by this checker.
658 bool mayFreeAnyEscapedMemoryOrIsModeledExplicitly(const CallEvent
*Call
,
659 ProgramStateRef State
,
660 SymbolRef
&EscapingSymbol
) const;
662 /// Implementation of the checkPointerEscape callbacks.
663 [[nodiscard
]] ProgramStateRef
664 checkPointerEscapeAux(ProgramStateRef State
,
665 const InvalidatedSymbols
&Escaped
,
666 const CallEvent
*Call
, PointerEscapeKind Kind
,
667 bool IsConstPointerEscape
) const;
669 // Implementation of the checkPreStmt and checkEndFunction callbacks.
670 void checkEscapeOnReturn(const ReturnStmt
*S
, CheckerContext
&C
) const;
673 /// Tells if a given family/call/symbol is tracked by the current checker.
674 /// Sets CheckKind to the kind of the checker responsible for this
675 /// family/call/symbol.
676 std::optional
<CheckKind
> getCheckIfTracked(AllocationFamily Family
,
677 bool IsALeakCheck
= false) const;
679 std::optional
<CheckKind
> getCheckIfTracked(CheckerContext
&C
, SymbolRef Sym
,
680 bool IsALeakCheck
= false) const;
682 static bool SummarizeValue(raw_ostream
&os
, SVal V
);
683 static bool SummarizeRegion(raw_ostream
&os
, const MemRegion
*MR
);
685 void HandleNonHeapDealloc(CheckerContext
&C
, SVal ArgVal
, SourceRange Range
,
686 const Expr
*DeallocExpr
,
687 AllocationFamily Family
) const;
689 void HandleFreeAlloca(CheckerContext
&C
, SVal ArgVal
,
690 SourceRange Range
) const;
692 void HandleMismatchedDealloc(CheckerContext
&C
, SourceRange Range
,
693 const Expr
*DeallocExpr
, const RefState
*RS
,
694 SymbolRef Sym
, bool OwnershipTransferred
) const;
696 void HandleOffsetFree(CheckerContext
&C
, SVal ArgVal
, SourceRange Range
,
697 const Expr
*DeallocExpr
, AllocationFamily Family
,
698 const Expr
*AllocExpr
= nullptr) const;
700 void HandleUseAfterFree(CheckerContext
&C
, SourceRange Range
,
701 SymbolRef Sym
) const;
703 void HandleDoubleFree(CheckerContext
&C
, SourceRange Range
, bool Released
,
704 SymbolRef Sym
, SymbolRef PrevSym
) const;
706 void HandleDoubleDelete(CheckerContext
&C
, SymbolRef Sym
) const;
708 void HandleUseZeroAlloc(CheckerContext
&C
, SourceRange Range
,
709 SymbolRef Sym
) const;
711 void HandleFunctionPtrFree(CheckerContext
&C
, SVal ArgVal
, SourceRange Range
,
712 const Expr
*FreeExpr
,
713 AllocationFamily Family
) const;
715 /// Find the location of the allocation for Sym on the path leading to the
717 static LeakInfo
getAllocationSite(const ExplodedNode
*N
, SymbolRef Sym
,
720 void HandleLeak(SymbolRef Sym
, ExplodedNode
*N
, CheckerContext
&C
) const;
722 /// Test if value in ArgVal equals to value in macro `ZERO_SIZE_PTR`.
723 bool isArgZERO_SIZE_PTR(ProgramStateRef State
, CheckerContext
&C
,
726 } // end anonymous namespace
728 //===----------------------------------------------------------------------===//
729 // Definition of NoOwnershipChangeVisitor.
730 //===----------------------------------------------------------------------===//
733 class NoOwnershipChangeVisitor final
: public NoStateChangeFuncVisitor
{
734 // The symbol whose (lack of) ownership change we are interested in.
736 const MallocChecker
&Checker
;
737 using OwnerSet
= llvm::SmallPtrSet
<const MemRegion
*, 8>;
739 // Collect which entities point to the allocated memory, and could be
740 // responsible for deallocating it.
741 class OwnershipBindingsHandler
: public StoreManager::BindingsHandler
{
746 OwnershipBindingsHandler(SymbolRef Sym
, OwnerSet
&Owners
)
747 : Sym(Sym
), Owners(Owners
) {}
749 bool HandleBinding(StoreManager
&SMgr
, Store Store
, const MemRegion
*Region
,
751 if (Val
.getAsSymbol() == Sym
)
752 Owners
.insert(Region
);
756 LLVM_DUMP_METHOD
void dump() const { dumpToStream(llvm::errs()); }
757 LLVM_DUMP_METHOD
void dumpToStream(llvm::raw_ostream
&out
) const {
758 out
<< "Owners: {\n";
759 for (const MemRegion
*Owner
: Owners
) {
761 Owner
->dumpToStream(out
);
769 OwnerSet
getOwnersAtNode(const ExplodedNode
*N
) {
772 ProgramStateRef State
= N
->getState();
773 OwnershipBindingsHandler Handler
{Sym
, Ret
};
774 State
->getStateManager().getStoreManager().iterBindings(State
->getStore(),
779 LLVM_DUMP_METHOD
static std::string
780 getFunctionName(const ExplodedNode
*CallEnterN
) {
781 if (const CallExpr
*CE
= llvm::dyn_cast_or_null
<CallExpr
>(
782 CallEnterN
->getLocationAs
<CallEnter
>()->getCallExpr()))
783 if (const FunctionDecl
*FD
= CE
->getDirectCallee())
784 return FD
->getQualifiedNameAsString();
788 /// Syntactically checks whether the callee is a deallocating function. Since
789 /// we have no path-sensitive information on this call (we would need a
790 /// CallEvent instead of a CallExpr for that), its possible that a
791 /// deallocation function was called indirectly through a function pointer,
792 /// but we are not able to tell, so this is a best effort analysis.
793 /// See namespace `memory_passed_to_fn_call_free_through_fn_ptr` in
794 /// clang/test/Analysis/NewDeleteLeaks.cpp.
795 bool isFreeingCallAsWritten(const CallExpr
&Call
) const {
796 if (Checker
.FreeingMemFnMap
.lookupAsWritten(Call
) ||
797 Checker
.ReallocatingMemFnMap
.lookupAsWritten(Call
))
800 if (const auto *Func
=
801 llvm::dyn_cast_or_null
<FunctionDecl
>(Call
.getCalleeDecl()))
802 return MallocChecker::isFreeingOwnershipAttrCall(Func
);
807 /// Heuristically guess whether the callee intended to free memory. This is
808 /// done syntactically, because we are trying to argue about alternative
809 /// paths of execution, and as a consequence we don't have path-sensitive
811 bool doesFnIntendToHandleOwnership(const Decl
*Callee
, ASTContext
&ACtx
) {
812 using namespace clang::ast_matchers
;
813 const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(Callee
);
815 // Given that the stack frame was entered, the body should always be
816 // theoretically obtainable. In case of body farms, the synthesized body
817 // is not attached to declaration, thus triggering the '!FD->hasBody()'
818 // branch. That said, would a synthesized body ever intend to handle
819 // ownership? As of today they don't. And if they did, how would we
820 // put notes inside it, given that it doesn't match any source locations?
821 if (!FD
|| !FD
->hasBody())
824 auto Matches
= match(findAll(stmt(anyOf(cxxDeleteExpr().bind("delete"),
825 callExpr().bind("call")))),
826 *FD
->getBody(), ACtx
);
827 for (BoundNodes Match
: Matches
) {
828 if (Match
.getNodeAs
<CXXDeleteExpr
>("delete"))
831 if (const auto *Call
= Match
.getNodeAs
<CallExpr
>("call"))
832 if (isFreeingCallAsWritten(*Call
))
835 // TODO: Ownership might change with an attempt to store the allocated
836 // memory, not only through deallocation. Check for attempted stores as
841 bool wasModifiedInFunction(const ExplodedNode
*CallEnterN
,
842 const ExplodedNode
*CallExitEndN
) override
{
843 if (!doesFnIntendToHandleOwnership(
844 CallExitEndN
->getFirstPred()->getLocationContext()->getDecl(),
845 CallExitEndN
->getState()->getAnalysisManager().getASTContext()))
848 if (CallEnterN
->getState()->get
<RegionState
>(Sym
) !=
849 CallExitEndN
->getState()->get
<RegionState
>(Sym
))
852 OwnerSet CurrOwners
= getOwnersAtNode(CallEnterN
);
853 OwnerSet ExitOwners
= getOwnersAtNode(CallExitEndN
);
855 // Owners in the current set may be purged from the analyzer later on.
856 // If a variable is dead (is not referenced directly or indirectly after
857 // some point), it will be removed from the Store before the end of its
859 // This means that if the ownership status didn't change, CurrOwners
860 // must be a superset of, but not necessarily equal to ExitOwners.
861 return !llvm::set_is_subset(ExitOwners
, CurrOwners
);
864 static PathDiagnosticPieceRef
emitNote(const ExplodedNode
*N
) {
865 PathDiagnosticLocation L
= PathDiagnosticLocation::create(
867 N
->getState()->getStateManager().getContext().getSourceManager());
868 return std::make_shared
<PathDiagnosticEventPiece
>(
869 L
, "Returning without deallocating memory or storing the pointer for "
870 "later deallocation");
873 PathDiagnosticPieceRef
874 maybeEmitNoteForObjCSelf(PathSensitiveBugReport
&R
,
875 const ObjCMethodCall
&Call
,
876 const ExplodedNode
*N
) override
{
881 PathDiagnosticPieceRef
882 maybeEmitNoteForCXXThis(PathSensitiveBugReport
&R
,
883 const CXXConstructorCall
&Call
,
884 const ExplodedNode
*N
) override
{
889 PathDiagnosticPieceRef
890 maybeEmitNoteForParameters(PathSensitiveBugReport
&R
, const CallEvent
&Call
,
891 const ExplodedNode
*N
) override
{
892 // TODO: Factor the logic of "what constitutes as an entity being passed
893 // into a function call" out by reusing the code in
894 // NoStoreFuncVisitor::maybeEmitNoteForParameters, maybe by incorporating
895 // the printing technology in UninitializedObject's FieldChainInfo.
896 ArrayRef
<ParmVarDecl
*> Parameters
= Call
.parameters();
897 for (unsigned I
= 0; I
< Call
.getNumArgs() && I
< Parameters
.size(); ++I
) {
898 SVal V
= Call
.getArgSVal(I
);
899 if (V
.getAsSymbol() == Sym
)
906 NoOwnershipChangeVisitor(SymbolRef Sym
, const MallocChecker
*Checker
)
907 : NoStateChangeFuncVisitor(bugreporter::TrackingKind::Thorough
), Sym(Sym
),
910 void Profile(llvm::FoldingSetNodeID
&ID
) const override
{
917 } // end anonymous namespace
919 //===----------------------------------------------------------------------===//
920 // Definition of MallocBugVisitor.
921 //===----------------------------------------------------------------------===//
924 /// The bug visitor which allows us to print extra diagnostics along the
925 /// BugReport path. For example, showing the allocation site of the leaked
927 class MallocBugVisitor final
: public BugReporterVisitor
{
929 enum NotificationMode
{ Normal
, ReallocationFailed
};
931 // The allocated region symbol tracked by the main analysis.
934 // The mode we are in, i.e. what kind of diagnostics will be emitted.
935 NotificationMode Mode
;
937 // A symbol from when the primary region should have been reallocated.
938 SymbolRef FailedReallocSymbol
;
940 // A C++ destructor stack frame in which memory was released. Used for
941 // miscellaneous false positive suppression.
942 const StackFrameContext
*ReleaseDestructorLC
;
947 MallocBugVisitor(SymbolRef S
, bool isLeak
= false)
948 : Sym(S
), Mode(Normal
), FailedReallocSymbol(nullptr),
949 ReleaseDestructorLC(nullptr), IsLeak(isLeak
) {}
951 static void *getTag() {
956 void Profile(llvm::FoldingSetNodeID
&ID
) const override
{
957 ID
.AddPointer(getTag());
961 /// Did not track -> allocated. Other state (released) -> allocated.
962 static inline bool isAllocated(const RefState
*RSCurr
, const RefState
*RSPrev
,
964 return (isa_and_nonnull
<CallExpr
, CXXNewExpr
>(Stmt
) &&
966 (RSCurr
->isAllocated() || RSCurr
->isAllocatedOfSizeZero())) &&
968 !(RSPrev
->isAllocated() || RSPrev
->isAllocatedOfSizeZero())));
971 /// Did not track -> released. Other state (allocated) -> released.
972 /// The statement associated with the release might be missing.
973 static inline bool isReleased(const RefState
*RSCurr
, const RefState
*RSPrev
,
976 (RSCurr
&& RSCurr
->isReleased()) && (!RSPrev
|| !RSPrev
->isReleased());
977 assert(!IsReleased
|| (isa_and_nonnull
<CallExpr
, CXXDeleteExpr
>(Stmt
)) ||
978 (!Stmt
&& RSCurr
->getAllocationFamily() == AF_InnerBuffer
));
982 /// Did not track -> relinquished. Other state (allocated) -> relinquished.
983 static inline bool isRelinquished(const RefState
*RSCurr
,
984 const RefState
*RSPrev
, const Stmt
*Stmt
) {
986 isa_and_nonnull
<CallExpr
, ObjCMessageExpr
, ObjCPropertyRefExpr
>(Stmt
) &&
987 (RSCurr
&& RSCurr
->isRelinquished()) &&
988 (!RSPrev
|| !RSPrev
->isRelinquished()));
991 /// If the expression is not a call, and the state change is
992 /// released -> allocated, it must be the realloc return value
993 /// check. If we have to handle more cases here, it might be cleaner just
994 /// to track this extra bit in the state itself.
995 static inline bool hasReallocFailed(const RefState
*RSCurr
,
996 const RefState
*RSPrev
,
998 return ((!isa_and_nonnull
<CallExpr
>(Stmt
)) &&
1000 (RSCurr
->isAllocated() || RSCurr
->isAllocatedOfSizeZero())) &&
1002 !(RSPrev
->isAllocated() || RSPrev
->isAllocatedOfSizeZero())));
1005 PathDiagnosticPieceRef
VisitNode(const ExplodedNode
*N
,
1006 BugReporterContext
&BRC
,
1007 PathSensitiveBugReport
&BR
) override
;
1009 PathDiagnosticPieceRef
getEndPath(BugReporterContext
&BRC
,
1010 const ExplodedNode
*EndPathNode
,
1011 PathSensitiveBugReport
&BR
) override
{
1015 PathDiagnosticLocation L
= BR
.getLocation();
1016 // Do not add the statement itself as a range in case of leak.
1017 return std::make_shared
<PathDiagnosticEventPiece
>(L
, BR
.getDescription(),
1022 class StackHintGeneratorForReallocationFailed
1023 : public StackHintGeneratorForSymbol
{
1025 StackHintGeneratorForReallocationFailed(SymbolRef S
, StringRef M
)
1026 : StackHintGeneratorForSymbol(S
, M
) {}
1028 std::string
getMessageForArg(const Expr
*ArgE
, unsigned ArgIndex
) override
{
1029 // Printed parameters start at 1, not 0.
1032 SmallString
<200> buf
;
1033 llvm::raw_svector_ostream
os(buf
);
1035 os
<< "Reallocation of " << ArgIndex
<< llvm::getOrdinalSuffix(ArgIndex
)
1036 << " parameter failed";
1038 return std::string(os
.str());
1041 std::string
getMessageForReturn(const CallExpr
*CallExpr
) override
{
1042 return "Reallocation of returned value failed";
1046 } // end anonymous namespace
1048 // A map from the freed symbol to the symbol representing the return value of
1049 // the free function.
1050 REGISTER_MAP_WITH_PROGRAMSTATE(FreeReturnValue
, SymbolRef
, SymbolRef
)
1053 class StopTrackingCallback final
: public SymbolVisitor
{
1054 ProgramStateRef state
;
1057 StopTrackingCallback(ProgramStateRef st
) : state(std::move(st
)) {}
1058 ProgramStateRef
getState() const { return state
; }
1060 bool VisitSymbol(SymbolRef sym
) override
{
1061 state
= state
->remove
<RegionState
>(sym
);
1065 } // end anonymous namespace
1067 static bool isStandardNewDelete(const FunctionDecl
*FD
) {
1071 OverloadedOperatorKind Kind
= FD
->getOverloadedOperator();
1072 if (Kind
!= OO_New
&& Kind
!= OO_Array_New
&& Kind
!= OO_Delete
&&
1073 Kind
!= OO_Array_Delete
)
1076 // This is standard if and only if it's not defined in a user file.
1077 SourceLocation L
= FD
->getLocation();
1078 // If the header for operator delete is not included, it's still defined
1079 // in an invalid source location. Check to make sure we don't crash.
1080 return !L
.isValid() ||
1081 FD
->getASTContext().getSourceManager().isInSystemHeader(L
);
1084 //===----------------------------------------------------------------------===//
1085 // Methods of MallocChecker and MallocBugVisitor.
1086 //===----------------------------------------------------------------------===//
1088 bool MallocChecker::isFreeingOwnershipAttrCall(const FunctionDecl
*Func
) {
1089 if (Func
->hasAttrs()) {
1090 for (const auto *I
: Func
->specific_attrs
<OwnershipAttr
>()) {
1091 OwnershipAttr::OwnershipKind OwnKind
= I
->getOwnKind();
1092 if (OwnKind
== OwnershipAttr::Takes
|| OwnKind
== OwnershipAttr::Holds
)
1099 bool MallocChecker::isFreeingCall(const CallEvent
&Call
) const {
1100 if (FreeingMemFnMap
.lookup(Call
) || ReallocatingMemFnMap
.lookup(Call
))
1103 if (const auto *Func
= dyn_cast_or_null
<FunctionDecl
>(Call
.getDecl()))
1104 return isFreeingOwnershipAttrCall(Func
);
1109 bool MallocChecker::isMemCall(const CallEvent
&Call
) const {
1110 if (FreeingMemFnMap
.lookup(Call
) || AllocatingMemFnMap
.lookup(Call
) ||
1111 ReallocatingMemFnMap
.lookup(Call
))
1114 if (!ShouldIncludeOwnershipAnnotatedFunctions
)
1117 const auto *Func
= dyn_cast
<FunctionDecl
>(Call
.getDecl());
1118 return Func
&& Func
->hasAttr
<OwnershipAttr
>();
1121 std::optional
<ProgramStateRef
>
1122 MallocChecker::performKernelMalloc(const CallEvent
&Call
, CheckerContext
&C
,
1123 const ProgramStateRef
&State
) const {
1124 // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels:
1126 // void *malloc(unsigned long size, struct malloc_type *mtp, int flags);
1128 // One of the possible flags is M_ZERO, which means 'give me back an
1129 // allocation which is already zeroed', like calloc.
1131 // 2-argument kmalloc(), as used in the Linux kernel:
1133 // void *kmalloc(size_t size, gfp_t flags);
1135 // Has the similar flag value __GFP_ZERO.
1137 // This logic is largely cloned from O_CREAT in UnixAPIChecker, maybe some
1138 // code could be shared.
1140 ASTContext
&Ctx
= C
.getASTContext();
1141 llvm::Triple::OSType OS
= Ctx
.getTargetInfo().getTriple().getOS();
1143 if (!KernelZeroFlagVal
) {
1145 case llvm::Triple::FreeBSD
:
1146 KernelZeroFlagVal
= 0x0100;
1148 case llvm::Triple::NetBSD
:
1149 KernelZeroFlagVal
= 0x0002;
1151 case llvm::Triple::OpenBSD
:
1152 KernelZeroFlagVal
= 0x0008;
1154 case llvm::Triple::Linux
:
1156 KernelZeroFlagVal
= 0x8000;
1159 // FIXME: We need a more general way of getting the M_ZERO value.
1160 // See also: O_CREAT in UnixAPIChecker.cpp.
1162 // Fall back to normal malloc behavior on platforms where we don't
1164 return std::nullopt
;
1168 // We treat the last argument as the flags argument, and callers fall-back to
1169 // normal malloc on a None return. This works for the FreeBSD kernel malloc
1170 // as well as Linux kmalloc.
1171 if (Call
.getNumArgs() < 2)
1172 return std::nullopt
;
1174 const Expr
*FlagsEx
= Call
.getArgExpr(Call
.getNumArgs() - 1);
1175 const SVal V
= C
.getSVal(FlagsEx
);
1176 if (!isa
<NonLoc
>(V
)) {
1177 // The case where 'V' can be a location can only be due to a bad header,
1178 // so in this case bail out.
1179 return std::nullopt
;
1182 NonLoc Flags
= V
.castAs
<NonLoc
>();
1183 NonLoc ZeroFlag
= C
.getSValBuilder()
1184 .makeIntVal(*KernelZeroFlagVal
, FlagsEx
->getType())
1186 SVal MaskedFlagsUC
= C
.getSValBuilder().evalBinOpNN(State
, BO_And
,
1188 FlagsEx
->getType());
1189 if (MaskedFlagsUC
.isUnknownOrUndef())
1190 return std::nullopt
;
1191 DefinedSVal MaskedFlags
= MaskedFlagsUC
.castAs
<DefinedSVal
>();
1193 // Check if maskedFlags is non-zero.
1194 ProgramStateRef TrueState
, FalseState
;
1195 std::tie(TrueState
, FalseState
) = State
->assume(MaskedFlags
);
1197 // If M_ZERO is set, treat this like calloc (initialized).
1198 if (TrueState
&& !FalseState
) {
1199 SVal ZeroVal
= C
.getSValBuilder().makeZeroVal(Ctx
.CharTy
);
1200 return MallocMemAux(C
, Call
, Call
.getArgExpr(0), ZeroVal
, TrueState
,
1204 return std::nullopt
;
1207 SVal
MallocChecker::evalMulForBufferSize(CheckerContext
&C
, const Expr
*Blocks
,
1208 const Expr
*BlockBytes
) {
1209 SValBuilder
&SB
= C
.getSValBuilder();
1210 SVal BlocksVal
= C
.getSVal(Blocks
);
1211 SVal BlockBytesVal
= C
.getSVal(BlockBytes
);
1212 ProgramStateRef State
= C
.getState();
1213 SVal TotalSize
= SB
.evalBinOp(State
, BO_Mul
, BlocksVal
, BlockBytesVal
,
1214 SB
.getContext().getSizeType());
1218 void MallocChecker::checkBasicAlloc(const CallEvent
&Call
,
1219 CheckerContext
&C
) const {
1220 ProgramStateRef State
= C
.getState();
1221 State
= MallocMemAux(C
, Call
, Call
.getArgExpr(0), UndefinedVal(), State
,
1223 State
= ProcessZeroAllocCheck(Call
, 0, State
);
1224 C
.addTransition(State
);
1227 void MallocChecker::checkKernelMalloc(const CallEvent
&Call
,
1228 CheckerContext
&C
) const {
1229 ProgramStateRef State
= C
.getState();
1230 std::optional
<ProgramStateRef
> MaybeState
=
1231 performKernelMalloc(Call
, C
, State
);
1233 State
= *MaybeState
;
1235 State
= MallocMemAux(C
, Call
, Call
.getArgExpr(0), UndefinedVal(), State
,
1237 C
.addTransition(State
);
1240 static bool isStandardRealloc(const CallEvent
&Call
) {
1241 const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(Call
.getDecl());
1243 ASTContext
&AC
= FD
->getASTContext();
1245 if (isa
<CXXMethodDecl
>(FD
))
1248 return FD
->getDeclaredReturnType().getDesugaredType(AC
) == AC
.VoidPtrTy
&&
1249 FD
->getParamDecl(0)->getType().getDesugaredType(AC
) == AC
.VoidPtrTy
&&
1250 FD
->getParamDecl(1)->getType().getDesugaredType(AC
) ==
1254 static bool isGRealloc(const CallEvent
&Call
) {
1255 const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(Call
.getDecl());
1257 ASTContext
&AC
= FD
->getASTContext();
1259 if (isa
<CXXMethodDecl
>(FD
))
1262 return FD
->getDeclaredReturnType().getDesugaredType(AC
) == AC
.VoidPtrTy
&&
1263 FD
->getParamDecl(0)->getType().getDesugaredType(AC
) == AC
.VoidPtrTy
&&
1264 FD
->getParamDecl(1)->getType().getDesugaredType(AC
) ==
1268 void MallocChecker::checkRealloc(const CallEvent
&Call
, CheckerContext
&C
,
1269 bool ShouldFreeOnFail
) const {
1270 // HACK: CallDescription currently recognizes non-standard realloc functions
1271 // as standard because it doesn't check the type, or wether its a non-method
1272 // function. This should be solved by making CallDescription smarter.
1273 // Mind that this came from a bug report, and all other functions suffer from
1275 // https://bugs.llvm.org/show_bug.cgi?id=46253
1276 if (!isStandardRealloc(Call
) && !isGRealloc(Call
))
1278 ProgramStateRef State
= C
.getState();
1279 State
= ReallocMemAux(C
, Call
, ShouldFreeOnFail
, State
, AF_Malloc
);
1280 State
= ProcessZeroAllocCheck(Call
, 1, State
);
1281 C
.addTransition(State
);
1284 void MallocChecker::checkCalloc(const CallEvent
&Call
,
1285 CheckerContext
&C
) const {
1286 ProgramStateRef State
= C
.getState();
1287 State
= CallocMem(C
, Call
, State
);
1288 State
= ProcessZeroAllocCheck(Call
, 0, State
);
1289 State
= ProcessZeroAllocCheck(Call
, 1, State
);
1290 C
.addTransition(State
);
1293 void MallocChecker::checkFree(const CallEvent
&Call
, CheckerContext
&C
) const {
1294 ProgramStateRef State
= C
.getState();
1295 bool IsKnownToBeAllocatedMemory
= false;
1296 if (suppressDeallocationsInSuspiciousContexts(Call
, C
))
1298 State
= FreeMemAux(C
, Call
, State
, 0, false, IsKnownToBeAllocatedMemory
,
1300 C
.addTransition(State
);
1303 void MallocChecker::checkAlloca(const CallEvent
&Call
,
1304 CheckerContext
&C
) const {
1305 ProgramStateRef State
= C
.getState();
1306 State
= MallocMemAux(C
, Call
, Call
.getArgExpr(0), UndefinedVal(), State
,
1308 State
= ProcessZeroAllocCheck(Call
, 0, State
);
1309 C
.addTransition(State
);
1312 void MallocChecker::checkStrdup(const CallEvent
&Call
,
1313 CheckerContext
&C
) const {
1314 ProgramStateRef State
= C
.getState();
1315 const auto *CE
= dyn_cast_or_null
<CallExpr
>(Call
.getOriginExpr());
1318 State
= MallocUpdateRefState(C
, CE
, State
, AF_Malloc
);
1320 C
.addTransition(State
);
1323 void MallocChecker::checkIfNameIndex(const CallEvent
&Call
,
1324 CheckerContext
&C
) const {
1325 ProgramStateRef State
= C
.getState();
1326 // Should we model this differently? We can allocate a fixed number of
1327 // elements with zeros in the last one.
1329 MallocMemAux(C
, Call
, UnknownVal(), UnknownVal(), State
, AF_IfNameIndex
);
1331 C
.addTransition(State
);
1334 void MallocChecker::checkIfFreeNameIndex(const CallEvent
&Call
,
1335 CheckerContext
&C
) const {
1336 ProgramStateRef State
= C
.getState();
1337 bool IsKnownToBeAllocatedMemory
= false;
1338 State
= FreeMemAux(C
, Call
, State
, 0, false, IsKnownToBeAllocatedMemory
,
1340 C
.addTransition(State
);
1343 void MallocChecker::checkCXXNewOrCXXDelete(const CallEvent
&Call
,
1344 CheckerContext
&C
) const {
1345 ProgramStateRef State
= C
.getState();
1346 bool IsKnownToBeAllocatedMemory
= false;
1347 const auto *CE
= dyn_cast_or_null
<CallExpr
>(Call
.getOriginExpr());
1351 assert(isStandardNewDelete(Call
));
1353 // Process direct calls to operator new/new[]/delete/delete[] functions
1354 // as distinct from new/new[]/delete/delete[] expressions that are
1355 // processed by the checkPostStmt callbacks for CXXNewExpr and
1357 const FunctionDecl
*FD
= C
.getCalleeDecl(CE
);
1358 switch (FD
->getOverloadedOperator()) {
1361 MallocMemAux(C
, Call
, CE
->getArg(0), UndefinedVal(), State
, AF_CXXNew
);
1362 State
= ProcessZeroAllocCheck(Call
, 0, State
);
1365 State
= MallocMemAux(C
, Call
, CE
->getArg(0), UndefinedVal(), State
,
1367 State
= ProcessZeroAllocCheck(Call
, 0, State
);
1370 State
= FreeMemAux(C
, Call
, State
, 0, false, IsKnownToBeAllocatedMemory
,
1373 case OO_Array_Delete
:
1374 State
= FreeMemAux(C
, Call
, State
, 0, false, IsKnownToBeAllocatedMemory
,
1378 llvm_unreachable("not a new/delete operator");
1381 C
.addTransition(State
);
1384 void MallocChecker::checkGMalloc0(const CallEvent
&Call
,
1385 CheckerContext
&C
) const {
1386 ProgramStateRef State
= C
.getState();
1387 SValBuilder
&svalBuilder
= C
.getSValBuilder();
1388 SVal zeroVal
= svalBuilder
.makeZeroVal(svalBuilder
.getContext().CharTy
);
1389 State
= MallocMemAux(C
, Call
, Call
.getArgExpr(0), zeroVal
, State
, AF_Malloc
);
1390 State
= ProcessZeroAllocCheck(Call
, 0, State
);
1391 C
.addTransition(State
);
1394 void MallocChecker::checkGMemdup(const CallEvent
&Call
,
1395 CheckerContext
&C
) const {
1396 ProgramStateRef State
= C
.getState();
1398 MallocMemAux(C
, Call
, Call
.getArgExpr(1), UnknownVal(), State
, AF_Malloc
);
1399 State
= ProcessZeroAllocCheck(Call
, 1, State
);
1400 C
.addTransition(State
);
1403 void MallocChecker::checkGMallocN(const CallEvent
&Call
,
1404 CheckerContext
&C
) const {
1405 ProgramStateRef State
= C
.getState();
1406 SVal Init
= UndefinedVal();
1407 SVal TotalSize
= evalMulForBufferSize(C
, Call
.getArgExpr(0), Call
.getArgExpr(1));
1408 State
= MallocMemAux(C
, Call
, TotalSize
, Init
, State
, AF_Malloc
);
1409 State
= ProcessZeroAllocCheck(Call
, 0, State
);
1410 State
= ProcessZeroAllocCheck(Call
, 1, State
);
1411 C
.addTransition(State
);
1414 void MallocChecker::checkGMallocN0(const CallEvent
&Call
,
1415 CheckerContext
&C
) const {
1416 ProgramStateRef State
= C
.getState();
1417 SValBuilder
&SB
= C
.getSValBuilder();
1418 SVal Init
= SB
.makeZeroVal(SB
.getContext().CharTy
);
1419 SVal TotalSize
= evalMulForBufferSize(C
, Call
.getArgExpr(0), Call
.getArgExpr(1));
1420 State
= MallocMemAux(C
, Call
, TotalSize
, Init
, State
, AF_Malloc
);
1421 State
= ProcessZeroAllocCheck(Call
, 0, State
);
1422 State
= ProcessZeroAllocCheck(Call
, 1, State
);
1423 C
.addTransition(State
);
1426 void MallocChecker::checkReallocN(const CallEvent
&Call
,
1427 CheckerContext
&C
) const {
1428 ProgramStateRef State
= C
.getState();
1429 State
= ReallocMemAux(C
, Call
, /*ShouldFreeOnFail=*/false, State
, AF_Malloc
,
1430 /*SuffixWithN=*/true);
1431 State
= ProcessZeroAllocCheck(Call
, 1, State
);
1432 State
= ProcessZeroAllocCheck(Call
, 2, State
);
1433 C
.addTransition(State
);
1436 void MallocChecker::checkOwnershipAttr(const CallEvent
&Call
,
1437 CheckerContext
&C
) const {
1438 ProgramStateRef State
= C
.getState();
1439 const auto *CE
= dyn_cast_or_null
<CallExpr
>(Call
.getOriginExpr());
1442 const FunctionDecl
*FD
= C
.getCalleeDecl(CE
);
1445 if (ShouldIncludeOwnershipAnnotatedFunctions
||
1446 ChecksEnabled
[CK_MismatchedDeallocatorChecker
]) {
1447 // Check all the attributes, if there are any.
1448 // There can be multiple of these attributes.
1450 for (const auto *I
: FD
->specific_attrs
<OwnershipAttr
>()) {
1451 switch (I
->getOwnKind()) {
1452 case OwnershipAttr::Returns
:
1453 State
= MallocMemReturnsAttr(C
, Call
, I
, State
);
1455 case OwnershipAttr::Takes
:
1456 case OwnershipAttr::Holds
:
1457 State
= FreeMemAttr(C
, Call
, I
, State
);
1462 C
.addTransition(State
);
1465 void MallocChecker::checkPostCall(const CallEvent
&Call
,
1466 CheckerContext
&C
) const {
1469 if (!Call
.getOriginExpr())
1472 ProgramStateRef State
= C
.getState();
1474 if (const CheckFn
*Callback
= FreeingMemFnMap
.lookup(Call
)) {
1475 (*Callback
)(this, Call
, C
);
1479 if (const CheckFn
*Callback
= AllocatingMemFnMap
.lookup(Call
)) {
1480 (*Callback
)(this, Call
, C
);
1484 if (const CheckFn
*Callback
= ReallocatingMemFnMap
.lookup(Call
)) {
1485 (*Callback
)(this, Call
, C
);
1489 if (isStandardNewDelete(Call
)) {
1490 checkCXXNewOrCXXDelete(Call
, C
);
1494 checkOwnershipAttr(Call
, C
);
1497 // Performs a 0-sized allocations check.
1498 ProgramStateRef
MallocChecker::ProcessZeroAllocCheck(
1499 const CallEvent
&Call
, const unsigned IndexOfSizeArg
, ProgramStateRef State
,
1500 std::optional
<SVal
> RetVal
) {
1505 RetVal
= Call
.getReturnValue();
1507 const Expr
*Arg
= nullptr;
1509 if (const CallExpr
*CE
= dyn_cast
<CallExpr
>(Call
.getOriginExpr())) {
1510 Arg
= CE
->getArg(IndexOfSizeArg
);
1511 } else if (const CXXNewExpr
*NE
=
1512 dyn_cast
<CXXNewExpr
>(Call
.getOriginExpr())) {
1513 if (NE
->isArray()) {
1514 Arg
= *NE
->getArraySize();
1519 llvm_unreachable("not a CallExpr or CXXNewExpr");
1524 State
->getSVal(Arg
, Call
.getLocationContext()).getAs
<DefinedSVal
>();
1529 // Check if the allocation size is 0.
1530 ProgramStateRef TrueState
, FalseState
;
1531 SValBuilder
&SvalBuilder
= State
->getStateManager().getSValBuilder();
1533 SvalBuilder
.makeZeroVal(Arg
->getType()).castAs
<DefinedSVal
>();
1535 std::tie(TrueState
, FalseState
) =
1536 State
->assume(SvalBuilder
.evalEQ(State
, *DefArgVal
, Zero
));
1538 if (TrueState
&& !FalseState
) {
1539 SymbolRef Sym
= RetVal
->getAsLocSymbol();
1543 const RefState
*RS
= State
->get
<RegionState
>(Sym
);
1545 if (RS
->isAllocated())
1546 return TrueState
->set
<RegionState
>(Sym
,
1547 RefState::getAllocatedOfSizeZero(RS
));
1551 // Case of zero-size realloc. Historically 'realloc(ptr, 0)' is treated as
1552 // 'free(ptr)' and the returned value from 'realloc(ptr, 0)' is not
1553 // tracked. Add zero-reallocated Sym to the state to catch references
1554 // to zero-allocated memory.
1555 return TrueState
->add
<ReallocSizeZeroSymbols
>(Sym
);
1559 // Assume the value is non-zero going forward.
1564 static QualType
getDeepPointeeType(QualType T
) {
1565 QualType Result
= T
, PointeeType
= T
->getPointeeType();
1566 while (!PointeeType
.isNull()) {
1567 Result
= PointeeType
;
1568 PointeeType
= PointeeType
->getPointeeType();
1573 /// \returns true if the constructor invoked by \p NE has an argument of a
1574 /// pointer/reference to a record type.
1575 static bool hasNonTrivialConstructorCall(const CXXNewExpr
*NE
) {
1577 const CXXConstructExpr
*ConstructE
= NE
->getConstructExpr();
1581 if (!NE
->getAllocatedType()->getAsCXXRecordDecl())
1584 const CXXConstructorDecl
*CtorD
= ConstructE
->getConstructor();
1586 // Iterate over the constructor parameters.
1587 for (const auto *CtorParam
: CtorD
->parameters()) {
1589 QualType CtorParamPointeeT
= CtorParam
->getType()->getPointeeType();
1590 if (CtorParamPointeeT
.isNull())
1593 CtorParamPointeeT
= getDeepPointeeType(CtorParamPointeeT
);
1595 if (CtorParamPointeeT
->getAsCXXRecordDecl())
1603 MallocChecker::processNewAllocation(const CXXAllocatorCall
&Call
,
1605 AllocationFamily Family
) const {
1606 if (!isStandardNewDelete(Call
))
1609 const CXXNewExpr
*NE
= Call
.getOriginExpr();
1610 const ParentMap
&PM
= C
.getLocationContext()->getParentMap();
1611 ProgramStateRef State
= C
.getState();
1613 // Non-trivial constructors have a chance to escape 'this', but marking all
1614 // invocations of trivial constructors as escaped would cause too great of
1615 // reduction of true positives, so let's just do that for constructors that
1616 // have an argument of a pointer-to-record type.
1617 if (!PM
.isConsumedExpr(NE
) && hasNonTrivialConstructorCall(NE
))
1620 // The return value from operator new is bound to a specified initialization
1621 // value (if any) and we don't want to loose this value. So we call
1622 // MallocUpdateRefState() instead of MallocMemAux() which breaks the
1623 // existing binding.
1624 SVal Target
= Call
.getObjectUnderConstruction();
1625 State
= MallocUpdateRefState(C
, NE
, State
, Family
, Target
);
1626 State
= ProcessZeroAllocCheck(Call
, 0, State
, Target
);
1630 void MallocChecker::checkNewAllocator(const CXXAllocatorCall
&Call
,
1631 CheckerContext
&C
) const {
1632 if (!C
.wasInlined
) {
1633 ProgramStateRef State
= processNewAllocation(
1635 (Call
.getOriginExpr()->isArray() ? AF_CXXNewArray
: AF_CXXNew
));
1636 C
.addTransition(State
);
1640 static bool isKnownDeallocObjCMethodName(const ObjCMethodCall
&Call
) {
1641 // If the first selector piece is one of the names below, assume that the
1642 // object takes ownership of the memory, promising to eventually deallocate it
1644 // Ex: [NSData dataWithBytesNoCopy:bytes length:10];
1645 // (...unless a 'freeWhenDone' parameter is false, but that's checked later.)
1646 StringRef FirstSlot
= Call
.getSelector().getNameForSlot(0);
1647 return FirstSlot
== "dataWithBytesNoCopy" ||
1648 FirstSlot
== "initWithBytesNoCopy" ||
1649 FirstSlot
== "initWithCharactersNoCopy";
1652 static std::optional
<bool> getFreeWhenDoneArg(const ObjCMethodCall
&Call
) {
1653 Selector S
= Call
.getSelector();
1655 // FIXME: We should not rely on fully-constrained symbols being folded.
1656 for (unsigned i
= 1; i
< S
.getNumArgs(); ++i
)
1657 if (S
.getNameForSlot(i
).equals("freeWhenDone"))
1658 return !Call
.getArgSVal(i
).isZeroConstant();
1660 return std::nullopt
;
1663 void MallocChecker::checkPostObjCMessage(const ObjCMethodCall
&Call
,
1664 CheckerContext
&C
) const {
1668 if (!isKnownDeallocObjCMethodName(Call
))
1671 if (std::optional
<bool> FreeWhenDone
= getFreeWhenDoneArg(Call
))
1675 if (Call
.hasNonZeroCallbackArg())
1678 bool IsKnownToBeAllocatedMemory
;
1679 ProgramStateRef State
=
1680 FreeMemAux(C
, Call
.getArgExpr(0), Call
, C
.getState(),
1681 /*Hold=*/true, IsKnownToBeAllocatedMemory
, AF_Malloc
,
1682 /*ReturnsNullOnFailure=*/true);
1684 C
.addTransition(State
);
1688 MallocChecker::MallocMemReturnsAttr(CheckerContext
&C
, const CallEvent
&Call
,
1689 const OwnershipAttr
*Att
,
1690 ProgramStateRef State
) const {
1694 if (Att
->getModule()->getName() != "malloc")
1697 if (!Att
->args().empty()) {
1698 return MallocMemAux(C
, Call
,
1699 Call
.getArgExpr(Att
->args_begin()->getASTIndex()),
1700 UndefinedVal(), State
, AF_Malloc
);
1702 return MallocMemAux(C
, Call
, UnknownVal(), UndefinedVal(), State
, AF_Malloc
);
1705 ProgramStateRef
MallocChecker::MallocMemAux(CheckerContext
&C
,
1706 const CallEvent
&Call
,
1707 const Expr
*SizeEx
, SVal Init
,
1708 ProgramStateRef State
,
1709 AllocationFamily Family
) {
1714 return MallocMemAux(C
, Call
, C
.getSVal(SizeEx
), Init
, State
, Family
);
1717 ProgramStateRef
MallocChecker::MallocMemAux(CheckerContext
&C
,
1718 const CallEvent
&Call
, SVal Size
,
1719 SVal Init
, ProgramStateRef State
,
1720 AllocationFamily Family
) {
1724 const Expr
*CE
= Call
.getOriginExpr();
1726 // We expect the malloc functions to return a pointer.
1727 if (!Loc::isLocType(CE
->getType()))
1730 // Bind the return value to the symbolic value from the heap region.
1731 // TODO: We could rewrite post visit to eval call; 'malloc' does not have
1732 // side effects other than what we model here.
1733 unsigned Count
= C
.blockCount();
1734 SValBuilder
&svalBuilder
= C
.getSValBuilder();
1735 const LocationContext
*LCtx
= C
.getPredecessor()->getLocationContext();
1736 DefinedSVal RetVal
= svalBuilder
.getConjuredHeapSymbolVal(CE
, LCtx
, Count
)
1737 .castAs
<DefinedSVal
>();
1738 State
= State
->BindExpr(CE
, C
.getLocationContext(), RetVal
);
1740 // Fill the region with the initialization value.
1741 State
= State
->bindDefaultInitial(RetVal
, Init
, LCtx
);
1743 // If Size is somehow undefined at this point, this line prevents a crash.
1745 Size
= UnknownVal();
1747 // Set the region's extent.
1748 State
= setDynamicExtent(State
, RetVal
.getAsRegion(),
1749 Size
.castAs
<DefinedOrUnknownSVal
>(), svalBuilder
);
1751 return MallocUpdateRefState(C
, CE
, State
, Family
);
1754 static ProgramStateRef
MallocUpdateRefState(CheckerContext
&C
, const Expr
*E
,
1755 ProgramStateRef State
,
1756 AllocationFamily Family
,
1757 std::optional
<SVal
> RetVal
) {
1761 // Get the return value.
1763 RetVal
= C
.getSVal(E
);
1765 // We expect the malloc functions to return a pointer.
1766 if (!RetVal
->getAs
<Loc
>())
1769 SymbolRef Sym
= RetVal
->getAsLocSymbol();
1770 // This is a return value of a function that was not inlined, such as malloc()
1771 // or new(). We've checked that in the caller. Therefore, it must be a symbol.
1774 // Set the symbol's state to Allocated.
1775 return State
->set
<RegionState
>(Sym
, RefState::getAllocated(Family
, E
));
1778 ProgramStateRef
MallocChecker::FreeMemAttr(CheckerContext
&C
,
1779 const CallEvent
&Call
,
1780 const OwnershipAttr
*Att
,
1781 ProgramStateRef State
) const {
1785 if (Att
->getModule()->getName() != "malloc")
1788 bool IsKnownToBeAllocated
= false;
1790 for (const auto &Arg
: Att
->args()) {
1791 ProgramStateRef StateI
=
1792 FreeMemAux(C
, Call
, State
, Arg
.getASTIndex(),
1793 Att
->getOwnKind() == OwnershipAttr::Holds
,
1794 IsKnownToBeAllocated
, AF_Malloc
);
1801 ProgramStateRef
MallocChecker::FreeMemAux(CheckerContext
&C
,
1802 const CallEvent
&Call
,
1803 ProgramStateRef State
, unsigned Num
,
1804 bool Hold
, bool &IsKnownToBeAllocated
,
1805 AllocationFamily Family
,
1806 bool ReturnsNullOnFailure
) const {
1810 if (Call
.getNumArgs() < (Num
+ 1))
1813 return FreeMemAux(C
, Call
.getArgExpr(Num
), Call
, State
, Hold
,
1814 IsKnownToBeAllocated
, Family
, ReturnsNullOnFailure
);
1817 /// Checks if the previous call to free on the given symbol failed - if free
1818 /// failed, returns true. Also, returns the corresponding return value symbol.
1819 static bool didPreviousFreeFail(ProgramStateRef State
,
1820 SymbolRef Sym
, SymbolRef
&RetStatusSymbol
) {
1821 const SymbolRef
*Ret
= State
->get
<FreeReturnValue
>(Sym
);
1823 assert(*Ret
&& "We should not store the null return symbol");
1824 ConstraintManager
&CMgr
= State
->getConstraintManager();
1825 ConditionTruthVal FreeFailed
= CMgr
.isNull(State
, *Ret
);
1826 RetStatusSymbol
= *Ret
;
1827 return FreeFailed
.isConstrainedTrue();
1832 static bool printMemFnName(raw_ostream
&os
, CheckerContext
&C
, const Expr
*E
) {
1833 if (const CallExpr
*CE
= dyn_cast
<CallExpr
>(E
)) {
1834 // FIXME: This doesn't handle indirect calls.
1835 const FunctionDecl
*FD
= CE
->getDirectCallee();
1840 if (!FD
->isOverloadedOperator())
1845 if (const ObjCMessageExpr
*Msg
= dyn_cast
<ObjCMessageExpr
>(E
)) {
1846 if (Msg
->isInstanceMessage())
1850 Msg
->getSelector().print(os
);
1854 if (const CXXNewExpr
*NE
= dyn_cast
<CXXNewExpr
>(E
)) {
1856 << getOperatorSpelling(NE
->getOperatorNew()->getOverloadedOperator())
1861 if (const CXXDeleteExpr
*DE
= dyn_cast
<CXXDeleteExpr
>(E
)) {
1863 << getOperatorSpelling(DE
->getOperatorDelete()->getOverloadedOperator())
1871 static void printExpectedAllocName(raw_ostream
&os
, AllocationFamily Family
) {
1874 case AF_Malloc
: os
<< "malloc()"; return;
1875 case AF_CXXNew
: os
<< "'new'"; return;
1876 case AF_CXXNewArray
: os
<< "'new[]'"; return;
1877 case AF_IfNameIndex
: os
<< "'if_nameindex()'"; return;
1878 case AF_InnerBuffer
: os
<< "container-specific allocator"; return;
1880 case AF_None
: llvm_unreachable("not a deallocation expression");
1884 static void printExpectedDeallocName(raw_ostream
&os
, AllocationFamily Family
) {
1886 case AF_Malloc
: os
<< "free()"; return;
1887 case AF_CXXNew
: os
<< "'delete'"; return;
1888 case AF_CXXNewArray
: os
<< "'delete[]'"; return;
1889 case AF_IfNameIndex
: os
<< "'if_freenameindex()'"; return;
1890 case AF_InnerBuffer
: os
<< "container-specific deallocator"; return;
1892 case AF_None
: llvm_unreachable("suspicious argument");
1896 ProgramStateRef
MallocChecker::FreeMemAux(
1897 CheckerContext
&C
, const Expr
*ArgExpr
, const CallEvent
&Call
,
1898 ProgramStateRef State
, bool Hold
, bool &IsKnownToBeAllocated
,
1899 AllocationFamily Family
, bool ReturnsNullOnFailure
) const {
1904 SVal ArgVal
= C
.getSVal(ArgExpr
);
1905 if (!isa
<DefinedOrUnknownSVal
>(ArgVal
))
1907 DefinedOrUnknownSVal location
= ArgVal
.castAs
<DefinedOrUnknownSVal
>();
1909 // Check for null dereferences.
1910 if (!isa
<Loc
>(location
))
1913 // The explicit NULL case, no operation is performed.
1914 ProgramStateRef notNullState
, nullState
;
1915 std::tie(notNullState
, nullState
) = State
->assume(location
);
1916 if (nullState
&& !notNullState
)
1919 // Unknown values could easily be okay
1920 // Undefined values are handled elsewhere
1921 if (ArgVal
.isUnknownOrUndef())
1924 const MemRegion
*R
= ArgVal
.getAsRegion();
1925 const Expr
*ParentExpr
= Call
.getOriginExpr();
1927 // NOTE: We detected a bug, but the checker under whose name we would emit the
1928 // error could be disabled. Generally speaking, the MallocChecker family is an
1929 // integral part of the Static Analyzer, and disabling any part of it should
1930 // only be done under exceptional circumstances, such as frequent false
1931 // positives. If this is the case, we can reasonably believe that there are
1932 // serious faults in our understanding of the source code, and even if we
1933 // don't emit an warning, we should terminate further analysis with a sink
1936 // Nonlocs can't be freed, of course.
1937 // Non-region locations (labels and fixed addresses) also shouldn't be freed.
1940 // If the macro ZERO_SIZE_PTR is defined, this could be a kernel source
1941 // code. In that case, the ZERO_SIZE_PTR defines a special value used for a
1942 // zero-sized memory block which is allowed to be freed, despite not being a
1944 if (Family
!= AF_Malloc
|| !isArgZERO_SIZE_PTR(State
, C
, ArgVal
))
1945 HandleNonHeapDealloc(C
, ArgVal
, ArgExpr
->getSourceRange(), ParentExpr
,
1950 R
= R
->StripCasts();
1952 // Blocks might show up as heap data, but should not be free()d
1953 if (isa
<BlockDataRegion
>(R
)) {
1954 HandleNonHeapDealloc(C
, ArgVal
, ArgExpr
->getSourceRange(), ParentExpr
,
1959 const MemSpaceRegion
*MS
= R
->getMemorySpace();
1961 // Parameters, locals, statics, globals, and memory returned by
1962 // __builtin_alloca() shouldn't be freed.
1963 if (!isa
<UnknownSpaceRegion
, HeapSpaceRegion
>(MS
)) {
1964 // Regions returned by malloc() are represented by SymbolicRegion objects
1965 // within HeapSpaceRegion. Of course, free() can work on memory allocated
1966 // outside the current function, so UnknownSpaceRegion is also a
1967 // possibility here.
1969 if (isa
<AllocaRegion
>(R
))
1970 HandleFreeAlloca(C
, ArgVal
, ArgExpr
->getSourceRange());
1972 HandleNonHeapDealloc(C
, ArgVal
, ArgExpr
->getSourceRange(), ParentExpr
,
1978 const SymbolicRegion
*SrBase
= dyn_cast
<SymbolicRegion
>(R
->getBaseRegion());
1979 // Various cases could lead to non-symbol values here.
1980 // For now, ignore them.
1984 SymbolRef SymBase
= SrBase
->getSymbol();
1985 const RefState
*RsBase
= State
->get
<RegionState
>(SymBase
);
1986 SymbolRef PreviousRetStatusSymbol
= nullptr;
1988 IsKnownToBeAllocated
=
1989 RsBase
&& (RsBase
->isAllocated() || RsBase
->isAllocatedOfSizeZero());
1993 // Memory returned by alloca() shouldn't be freed.
1994 if (RsBase
->getAllocationFamily() == AF_Alloca
) {
1995 HandleFreeAlloca(C
, ArgVal
, ArgExpr
->getSourceRange());
1999 // Check for double free first.
2000 if ((RsBase
->isReleased() || RsBase
->isRelinquished()) &&
2001 !didPreviousFreeFail(State
, SymBase
, PreviousRetStatusSymbol
)) {
2002 HandleDoubleFree(C
, ParentExpr
->getSourceRange(), RsBase
->isReleased(),
2003 SymBase
, PreviousRetStatusSymbol
);
2006 // If the pointer is allocated or escaped, but we are now trying to free it,
2007 // check that the call to free is proper.
2008 } else if (RsBase
->isAllocated() || RsBase
->isAllocatedOfSizeZero() ||
2009 RsBase
->isEscaped()) {
2011 // Check if an expected deallocation function matches the real one.
2012 bool DeallocMatchesAlloc
= RsBase
->getAllocationFamily() == Family
;
2013 if (!DeallocMatchesAlloc
) {
2014 HandleMismatchedDealloc(C
, ArgExpr
->getSourceRange(), ParentExpr
,
2015 RsBase
, SymBase
, Hold
);
2019 // Check if the memory location being freed is the actual location
2020 // allocated, or an offset.
2021 RegionOffset Offset
= R
->getAsOffset();
2022 if (Offset
.isValid() &&
2023 !Offset
.hasSymbolicOffset() &&
2024 Offset
.getOffset() != 0) {
2025 const Expr
*AllocExpr
= cast
<Expr
>(RsBase
->getStmt());
2026 HandleOffsetFree(C
, ArgVal
, ArgExpr
->getSourceRange(), ParentExpr
,
2033 if (SymBase
->getType()->isFunctionPointerType()) {
2034 HandleFunctionPtrFree(C
, ArgVal
, ArgExpr
->getSourceRange(), ParentExpr
,
2039 // Clean out the info on previous call to free return info.
2040 State
= State
->remove
<FreeReturnValue
>(SymBase
);
2042 // Keep track of the return value. If it is NULL, we will know that free
2044 if (ReturnsNullOnFailure
) {
2045 SVal RetVal
= C
.getSVal(ParentExpr
);
2046 SymbolRef RetStatusSymbol
= RetVal
.getAsSymbol();
2047 if (RetStatusSymbol
) {
2048 C
.getSymbolManager().addSymbolDependency(SymBase
, RetStatusSymbol
);
2049 State
= State
->set
<FreeReturnValue
>(SymBase
, RetStatusSymbol
);
2053 // If we don't know anything about this symbol, a free on it may be totally
2054 // valid. If this is the case, lets assume that the allocation family of the
2055 // freeing function is the same as the symbols allocation family, and go with
2057 assert(!RsBase
|| (RsBase
&& RsBase
->getAllocationFamily() == Family
));
2061 return State
->set
<RegionState
>(SymBase
,
2062 RefState::getRelinquished(Family
,
2065 return State
->set
<RegionState
>(SymBase
,
2066 RefState::getReleased(Family
, ParentExpr
));
2069 std::optional
<MallocChecker::CheckKind
>
2070 MallocChecker::getCheckIfTracked(AllocationFamily Family
,
2071 bool IsALeakCheck
) const {
2075 case AF_IfNameIndex
: {
2076 if (ChecksEnabled
[CK_MallocChecker
])
2077 return CK_MallocChecker
;
2078 return std::nullopt
;
2081 case AF_CXXNewArray
: {
2083 if (ChecksEnabled
[CK_NewDeleteLeaksChecker
])
2084 return CK_NewDeleteLeaksChecker
;
2087 if (ChecksEnabled
[CK_NewDeleteChecker
])
2088 return CK_NewDeleteChecker
;
2090 return std::nullopt
;
2092 case AF_InnerBuffer
: {
2093 if (ChecksEnabled
[CK_InnerPointerChecker
])
2094 return CK_InnerPointerChecker
;
2095 return std::nullopt
;
2098 llvm_unreachable("no family");
2101 llvm_unreachable("unhandled family");
2104 std::optional
<MallocChecker::CheckKind
>
2105 MallocChecker::getCheckIfTracked(CheckerContext
&C
, SymbolRef Sym
,
2106 bool IsALeakCheck
) const {
2107 if (C
.getState()->contains
<ReallocSizeZeroSymbols
>(Sym
))
2108 return CK_MallocChecker
;
2110 const RefState
*RS
= C
.getState()->get
<RegionState
>(Sym
);
2112 return getCheckIfTracked(RS
->getAllocationFamily(), IsALeakCheck
);
2115 bool MallocChecker::SummarizeValue(raw_ostream
&os
, SVal V
) {
2116 if (std::optional
<nonloc::ConcreteInt
> IntVal
=
2117 V
.getAs
<nonloc::ConcreteInt
>())
2118 os
<< "an integer (" << IntVal
->getValue() << ")";
2119 else if (std::optional
<loc::ConcreteInt
> ConstAddr
=
2120 V
.getAs
<loc::ConcreteInt
>())
2121 os
<< "a constant address (" << ConstAddr
->getValue() << ")";
2122 else if (std::optional
<loc::GotoLabel
> Label
= V
.getAs
<loc::GotoLabel
>())
2123 os
<< "the address of the label '" << Label
->getLabel()->getName() << "'";
2130 bool MallocChecker::SummarizeRegion(raw_ostream
&os
,
2131 const MemRegion
*MR
) {
2132 switch (MR
->getKind()) {
2133 case MemRegion::FunctionCodeRegionKind
: {
2134 const NamedDecl
*FD
= cast
<FunctionCodeRegion
>(MR
)->getDecl();
2136 os
<< "the address of the function '" << *FD
<< '\'';
2138 os
<< "the address of a function";
2141 case MemRegion::BlockCodeRegionKind
:
2144 case MemRegion::BlockDataRegionKind
:
2145 // FIXME: where the block came from?
2149 const MemSpaceRegion
*MS
= MR
->getMemorySpace();
2151 if (isa
<StackLocalsSpaceRegion
>(MS
)) {
2152 const VarRegion
*VR
= dyn_cast
<VarRegion
>(MR
);
2160 os
<< "the address of the local variable '" << VD
->getName() << "'";
2162 os
<< "the address of a local stack variable";
2166 if (isa
<StackArgumentsSpaceRegion
>(MS
)) {
2167 const VarRegion
*VR
= dyn_cast
<VarRegion
>(MR
);
2175 os
<< "the address of the parameter '" << VD
->getName() << "'";
2177 os
<< "the address of a parameter";
2181 if (isa
<GlobalsSpaceRegion
>(MS
)) {
2182 const VarRegion
*VR
= dyn_cast
<VarRegion
>(MR
);
2190 if (VD
->isStaticLocal())
2191 os
<< "the address of the static variable '" << VD
->getName() << "'";
2193 os
<< "the address of the global variable '" << VD
->getName() << "'";
2195 os
<< "the address of a global variable";
2204 void MallocChecker::HandleNonHeapDealloc(CheckerContext
&C
, SVal ArgVal
,
2206 const Expr
*DeallocExpr
,
2207 AllocationFamily Family
) const {
2209 if (!ChecksEnabled
[CK_MallocChecker
] && !ChecksEnabled
[CK_NewDeleteChecker
]) {
2214 std::optional
<MallocChecker::CheckKind
> CheckKind
= getCheckIfTracked(Family
);
2218 if (ExplodedNode
*N
= C
.generateErrorNode()) {
2219 if (!BT_BadFree
[*CheckKind
])
2220 BT_BadFree
[*CheckKind
].reset(new BugType(
2221 CheckNames
[*CheckKind
], "Bad free", categories::MemoryError
));
2223 SmallString
<100> buf
;
2224 llvm::raw_svector_ostream
os(buf
);
2226 const MemRegion
*MR
= ArgVal
.getAsRegion();
2227 while (const ElementRegion
*ER
= dyn_cast_or_null
<ElementRegion
>(MR
))
2228 MR
= ER
->getSuperRegion();
2230 os
<< "Argument to ";
2231 if (!printMemFnName(os
, C
, DeallocExpr
))
2232 os
<< "deallocator";
2235 bool Summarized
= MR
? SummarizeRegion(os
, MR
)
2236 : SummarizeValue(os
, ArgVal
);
2238 os
<< ", which is not memory allocated by ";
2240 os
<< "not memory allocated by ";
2242 printExpectedAllocName(os
, Family
);
2244 auto R
= std::make_unique
<PathSensitiveBugReport
>(*BT_BadFree
[*CheckKind
],
2246 R
->markInteresting(MR
);
2248 C
.emitReport(std::move(R
));
2252 void MallocChecker::HandleFreeAlloca(CheckerContext
&C
, SVal ArgVal
,
2253 SourceRange Range
) const {
2255 std::optional
<MallocChecker::CheckKind
> CheckKind
;
2257 if (ChecksEnabled
[CK_MallocChecker
])
2258 CheckKind
= CK_MallocChecker
;
2259 else if (ChecksEnabled
[CK_MismatchedDeallocatorChecker
])
2260 CheckKind
= CK_MismatchedDeallocatorChecker
;
2266 if (ExplodedNode
*N
= C
.generateErrorNode()) {
2267 if (!BT_FreeAlloca
[*CheckKind
])
2268 BT_FreeAlloca
[*CheckKind
].reset(new BugType(
2269 CheckNames
[*CheckKind
], "Free alloca()", categories::MemoryError
));
2271 auto R
= std::make_unique
<PathSensitiveBugReport
>(
2272 *BT_FreeAlloca
[*CheckKind
],
2273 "Memory allocated by alloca() should not be deallocated", N
);
2274 R
->markInteresting(ArgVal
.getAsRegion());
2276 C
.emitReport(std::move(R
));
2280 void MallocChecker::HandleMismatchedDealloc(CheckerContext
&C
,
2282 const Expr
*DeallocExpr
,
2283 const RefState
*RS
, SymbolRef Sym
,
2284 bool OwnershipTransferred
) const {
2286 if (!ChecksEnabled
[CK_MismatchedDeallocatorChecker
]) {
2291 if (ExplodedNode
*N
= C
.generateErrorNode()) {
2292 if (!BT_MismatchedDealloc
)
2293 BT_MismatchedDealloc
.reset(
2294 new BugType(CheckNames
[CK_MismatchedDeallocatorChecker
],
2295 "Bad deallocator", categories::MemoryError
));
2297 SmallString
<100> buf
;
2298 llvm::raw_svector_ostream
os(buf
);
2300 const Expr
*AllocExpr
= cast
<Expr
>(RS
->getStmt());
2301 SmallString
<20> AllocBuf
;
2302 llvm::raw_svector_ostream
AllocOs(AllocBuf
);
2303 SmallString
<20> DeallocBuf
;
2304 llvm::raw_svector_ostream
DeallocOs(DeallocBuf
);
2306 if (OwnershipTransferred
) {
2307 if (printMemFnName(DeallocOs
, C
, DeallocExpr
))
2308 os
<< DeallocOs
.str() << " cannot";
2312 os
<< " take ownership of memory";
2314 if (printMemFnName(AllocOs
, C
, AllocExpr
))
2315 os
<< " allocated by " << AllocOs
.str();
2318 if (printMemFnName(AllocOs
, C
, AllocExpr
))
2319 os
<< " allocated by " << AllocOs
.str();
2321 os
<< " should be deallocated by ";
2322 printExpectedDeallocName(os
, RS
->getAllocationFamily());
2324 if (printMemFnName(DeallocOs
, C
, DeallocExpr
))
2325 os
<< ", not " << DeallocOs
.str();
2328 auto R
= std::make_unique
<PathSensitiveBugReport
>(*BT_MismatchedDealloc
,
2330 R
->markInteresting(Sym
);
2332 R
->addVisitor
<MallocBugVisitor
>(Sym
);
2333 C
.emitReport(std::move(R
));
2337 void MallocChecker::HandleOffsetFree(CheckerContext
&C
, SVal ArgVal
,
2338 SourceRange Range
, const Expr
*DeallocExpr
,
2339 AllocationFamily Family
,
2340 const Expr
*AllocExpr
) const {
2342 if (!ChecksEnabled
[CK_MallocChecker
] && !ChecksEnabled
[CK_NewDeleteChecker
]) {
2347 std::optional
<MallocChecker::CheckKind
> CheckKind
= getCheckIfTracked(Family
);
2351 ExplodedNode
*N
= C
.generateErrorNode();
2355 if (!BT_OffsetFree
[*CheckKind
])
2356 BT_OffsetFree
[*CheckKind
].reset(new BugType(
2357 CheckNames
[*CheckKind
], "Offset free", categories::MemoryError
));
2359 SmallString
<100> buf
;
2360 llvm::raw_svector_ostream
os(buf
);
2361 SmallString
<20> AllocNameBuf
;
2362 llvm::raw_svector_ostream
AllocNameOs(AllocNameBuf
);
2364 const MemRegion
*MR
= ArgVal
.getAsRegion();
2365 assert(MR
&& "Only MemRegion based symbols can have offset free errors");
2367 RegionOffset Offset
= MR
->getAsOffset();
2368 assert((Offset
.isValid() &&
2369 !Offset
.hasSymbolicOffset() &&
2370 Offset
.getOffset() != 0) &&
2371 "Only symbols with a valid offset can have offset free errors");
2373 int offsetBytes
= Offset
.getOffset() / C
.getASTContext().getCharWidth();
2375 os
<< "Argument to ";
2376 if (!printMemFnName(os
, C
, DeallocExpr
))
2377 os
<< "deallocator";
2378 os
<< " is offset by "
2381 << ((abs(offsetBytes
) > 1) ? "bytes" : "byte")
2382 << " from the start of ";
2383 if (AllocExpr
&& printMemFnName(AllocNameOs
, C
, AllocExpr
))
2384 os
<< "memory allocated by " << AllocNameOs
.str();
2386 os
<< "allocated memory";
2388 auto R
= std::make_unique
<PathSensitiveBugReport
>(*BT_OffsetFree
[*CheckKind
],
2390 R
->markInteresting(MR
->getBaseRegion());
2392 C
.emitReport(std::move(R
));
2395 void MallocChecker::HandleUseAfterFree(CheckerContext
&C
, SourceRange Range
,
2396 SymbolRef Sym
) const {
2398 if (!ChecksEnabled
[CK_MallocChecker
] && !ChecksEnabled
[CK_NewDeleteChecker
] &&
2399 !ChecksEnabled
[CK_InnerPointerChecker
]) {
2404 std::optional
<MallocChecker::CheckKind
> CheckKind
= getCheckIfTracked(C
, Sym
);
2408 if (ExplodedNode
*N
= C
.generateErrorNode()) {
2409 if (!BT_UseFree
[*CheckKind
])
2410 BT_UseFree
[*CheckKind
].reset(new BugType(
2411 CheckNames
[*CheckKind
], "Use-after-free", categories::MemoryError
));
2413 AllocationFamily AF
=
2414 C
.getState()->get
<RegionState
>(Sym
)->getAllocationFamily();
2416 auto R
= std::make_unique
<PathSensitiveBugReport
>(
2417 *BT_UseFree
[*CheckKind
],
2418 AF
== AF_InnerBuffer
2419 ? "Inner pointer of container used after re/deallocation"
2420 : "Use of memory after it is freed",
2423 R
->markInteresting(Sym
);
2425 R
->addVisitor
<MallocBugVisitor
>(Sym
);
2427 if (AF
== AF_InnerBuffer
)
2428 R
->addVisitor(allocation_state::getInnerPointerBRVisitor(Sym
));
2430 C
.emitReport(std::move(R
));
2434 void MallocChecker::HandleDoubleFree(CheckerContext
&C
, SourceRange Range
,
2435 bool Released
, SymbolRef Sym
,
2436 SymbolRef PrevSym
) const {
2438 if (!ChecksEnabled
[CK_MallocChecker
] && !ChecksEnabled
[CK_NewDeleteChecker
]) {
2443 std::optional
<MallocChecker::CheckKind
> CheckKind
= getCheckIfTracked(C
, Sym
);
2447 if (ExplodedNode
*N
= C
.generateErrorNode()) {
2448 if (!BT_DoubleFree
[*CheckKind
])
2449 BT_DoubleFree
[*CheckKind
].reset(new BugType(
2450 CheckNames
[*CheckKind
], "Double free", categories::MemoryError
));
2452 auto R
= std::make_unique
<PathSensitiveBugReport
>(
2453 *BT_DoubleFree
[*CheckKind
],
2454 (Released
? "Attempt to free released memory"
2455 : "Attempt to free non-owned memory"),
2458 R
->markInteresting(Sym
);
2460 R
->markInteresting(PrevSym
);
2461 R
->addVisitor
<MallocBugVisitor
>(Sym
);
2462 C
.emitReport(std::move(R
));
2466 void MallocChecker::HandleDoubleDelete(CheckerContext
&C
, SymbolRef Sym
) const {
2468 if (!ChecksEnabled
[CK_NewDeleteChecker
]) {
2473 std::optional
<MallocChecker::CheckKind
> CheckKind
= getCheckIfTracked(C
, Sym
);
2477 if (ExplodedNode
*N
= C
.generateErrorNode()) {
2478 if (!BT_DoubleDelete
)
2479 BT_DoubleDelete
.reset(new BugType(CheckNames
[CK_NewDeleteChecker
],
2481 categories::MemoryError
));
2483 auto R
= std::make_unique
<PathSensitiveBugReport
>(
2484 *BT_DoubleDelete
, "Attempt to delete released memory", N
);
2486 R
->markInteresting(Sym
);
2487 R
->addVisitor
<MallocBugVisitor
>(Sym
);
2488 C
.emitReport(std::move(R
));
2492 void MallocChecker::HandleUseZeroAlloc(CheckerContext
&C
, SourceRange Range
,
2493 SymbolRef Sym
) const {
2495 if (!ChecksEnabled
[CK_MallocChecker
] && !ChecksEnabled
[CK_NewDeleteChecker
]) {
2500 std::optional
<MallocChecker::CheckKind
> CheckKind
= getCheckIfTracked(C
, Sym
);
2505 if (ExplodedNode
*N
= C
.generateErrorNode()) {
2506 if (!BT_UseZerroAllocated
[*CheckKind
])
2507 BT_UseZerroAllocated
[*CheckKind
].reset(
2508 new BugType(CheckNames
[*CheckKind
], "Use of zero allocated",
2509 categories::MemoryError
));
2511 auto R
= std::make_unique
<PathSensitiveBugReport
>(
2512 *BT_UseZerroAllocated
[*CheckKind
],
2513 "Use of memory allocated with size zero", N
);
2517 R
->markInteresting(Sym
);
2518 R
->addVisitor
<MallocBugVisitor
>(Sym
);
2520 C
.emitReport(std::move(R
));
2524 void MallocChecker::HandleFunctionPtrFree(CheckerContext
&C
, SVal ArgVal
,
2526 const Expr
*FreeExpr
,
2527 AllocationFamily Family
) const {
2528 if (!ChecksEnabled
[CK_MallocChecker
]) {
2533 std::optional
<MallocChecker::CheckKind
> CheckKind
= getCheckIfTracked(Family
);
2537 if (ExplodedNode
*N
= C
.generateErrorNode()) {
2538 if (!BT_BadFree
[*CheckKind
])
2539 BT_BadFree
[*CheckKind
].reset(new BugType(
2540 CheckNames
[*CheckKind
], "Bad free", categories::MemoryError
));
2542 SmallString
<100> Buf
;
2543 llvm::raw_svector_ostream
Os(Buf
);
2545 const MemRegion
*MR
= ArgVal
.getAsRegion();
2546 while (const ElementRegion
*ER
= dyn_cast_or_null
<ElementRegion
>(MR
))
2547 MR
= ER
->getSuperRegion();
2549 Os
<< "Argument to ";
2550 if (!printMemFnName(Os
, C
, FreeExpr
))
2551 Os
<< "deallocator";
2553 Os
<< " is a function pointer";
2555 auto R
= std::make_unique
<PathSensitiveBugReport
>(*BT_BadFree
[*CheckKind
],
2557 R
->markInteresting(MR
);
2559 C
.emitReport(std::move(R
));
2564 MallocChecker::ReallocMemAux(CheckerContext
&C
, const CallEvent
&Call
,
2565 bool ShouldFreeOnFail
, ProgramStateRef State
,
2566 AllocationFamily Family
, bool SuffixWithN
) const {
2570 const CallExpr
*CE
= cast
<CallExpr
>(Call
.getOriginExpr());
2572 if (SuffixWithN
&& CE
->getNumArgs() < 3)
2574 else if (CE
->getNumArgs() < 2)
2577 const Expr
*arg0Expr
= CE
->getArg(0);
2578 SVal Arg0Val
= C
.getSVal(arg0Expr
);
2579 if (!isa
<DefinedOrUnknownSVal
>(Arg0Val
))
2581 DefinedOrUnknownSVal arg0Val
= Arg0Val
.castAs
<DefinedOrUnknownSVal
>();
2583 SValBuilder
&svalBuilder
= C
.getSValBuilder();
2585 DefinedOrUnknownSVal PtrEQ
= svalBuilder
.evalEQ(
2586 State
, arg0Val
, svalBuilder
.makeNullWithType(arg0Expr
->getType()));
2588 // Get the size argument.
2589 const Expr
*Arg1
= CE
->getArg(1);
2591 // Get the value of the size argument.
2592 SVal TotalSize
= C
.getSVal(Arg1
);
2594 TotalSize
= evalMulForBufferSize(C
, Arg1
, CE
->getArg(2));
2595 if (!isa
<DefinedOrUnknownSVal
>(TotalSize
))
2598 // Compare the size argument to 0.
2599 DefinedOrUnknownSVal SizeZero
=
2600 svalBuilder
.evalEQ(State
, TotalSize
.castAs
<DefinedOrUnknownSVal
>(),
2601 svalBuilder
.makeIntValWithWidth(
2602 svalBuilder
.getContext().getSizeType(), 0));
2604 ProgramStateRef StatePtrIsNull
, StatePtrNotNull
;
2605 std::tie(StatePtrIsNull
, StatePtrNotNull
) = State
->assume(PtrEQ
);
2606 ProgramStateRef StateSizeIsZero
, StateSizeNotZero
;
2607 std::tie(StateSizeIsZero
, StateSizeNotZero
) = State
->assume(SizeZero
);
2608 // We only assume exceptional states if they are definitely true; if the
2609 // state is under-constrained, assume regular realloc behavior.
2610 bool PrtIsNull
= StatePtrIsNull
&& !StatePtrNotNull
;
2611 bool SizeIsZero
= StateSizeIsZero
&& !StateSizeNotZero
;
2613 // If the ptr is NULL and the size is not 0, the call is equivalent to
2615 if (PrtIsNull
&& !SizeIsZero
) {
2616 ProgramStateRef stateMalloc
= MallocMemAux(
2617 C
, Call
, TotalSize
, UndefinedVal(), StatePtrIsNull
, Family
);
2621 if (PrtIsNull
&& SizeIsZero
)
2626 bool IsKnownToBeAllocated
= false;
2628 // If the size is 0, free the memory.
2630 // The semantics of the return value are:
2631 // If size was equal to 0, either NULL or a pointer suitable to be passed
2632 // to free() is returned. We just free the input pointer and do not add
2633 // any constrains on the output pointer.
2634 if (ProgramStateRef stateFree
= FreeMemAux(
2635 C
, Call
, StateSizeIsZero
, 0, false, IsKnownToBeAllocated
, Family
))
2638 // Default behavior.
2639 if (ProgramStateRef stateFree
=
2640 FreeMemAux(C
, Call
, State
, 0, false, IsKnownToBeAllocated
, Family
)) {
2642 ProgramStateRef stateRealloc
=
2643 MallocMemAux(C
, Call
, TotalSize
, UnknownVal(), stateFree
, Family
);
2647 OwnershipAfterReallocKind Kind
= OAR_ToBeFreedAfterFailure
;
2648 if (ShouldFreeOnFail
)
2649 Kind
= OAR_FreeOnFailure
;
2650 else if (!IsKnownToBeAllocated
)
2651 Kind
= OAR_DoNotTrackAfterFailure
;
2653 // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
2654 SymbolRef FromPtr
= arg0Val
.getLocSymbolInBase();
2655 SVal RetVal
= C
.getSVal(CE
);
2656 SymbolRef ToPtr
= RetVal
.getAsSymbol();
2657 assert(FromPtr
&& ToPtr
&&
2658 "By this point, FreeMemAux and MallocMemAux should have checked "
2659 "whether the argument or the return value is symbolic!");
2661 // Record the info about the reallocated symbol so that we could properly
2662 // process failed reallocation.
2663 stateRealloc
= stateRealloc
->set
<ReallocPairs
>(ToPtr
,
2664 ReallocPair(FromPtr
, Kind
));
2665 // The reallocated symbol should stay alive for as long as the new symbol.
2666 C
.getSymbolManager().addSymbolDependency(ToPtr
, FromPtr
);
2667 return stateRealloc
;
2672 ProgramStateRef
MallocChecker::CallocMem(CheckerContext
&C
,
2673 const CallEvent
&Call
,
2674 ProgramStateRef State
) {
2678 if (Call
.getNumArgs() < 2)
2681 SValBuilder
&svalBuilder
= C
.getSValBuilder();
2682 SVal zeroVal
= svalBuilder
.makeZeroVal(svalBuilder
.getContext().CharTy
);
2684 evalMulForBufferSize(C
, Call
.getArgExpr(0), Call
.getArgExpr(1));
2686 return MallocMemAux(C
, Call
, TotalSize
, zeroVal
, State
, AF_Malloc
);
2689 MallocChecker::LeakInfo
MallocChecker::getAllocationSite(const ExplodedNode
*N
,
2691 CheckerContext
&C
) {
2692 const LocationContext
*LeakContext
= N
->getLocationContext();
2693 // Walk the ExplodedGraph backwards and find the first node that referred to
2694 // the tracked symbol.
2695 const ExplodedNode
*AllocNode
= N
;
2696 const MemRegion
*ReferenceRegion
= nullptr;
2699 ProgramStateRef State
= N
->getState();
2700 if (!State
->get
<RegionState
>(Sym
))
2703 // Find the most recent expression bound to the symbol in the current
2705 if (!ReferenceRegion
) {
2706 if (const MemRegion
*MR
= C
.getLocationRegionIfPostStore(N
)) {
2707 SVal Val
= State
->getSVal(MR
);
2708 if (Val
.getAsLocSymbol() == Sym
) {
2709 const VarRegion
*VR
= MR
->getBaseRegion()->getAs
<VarRegion
>();
2710 // Do not show local variables belonging to a function other than
2711 // where the error is reported.
2712 if (!VR
|| (VR
->getStackFrame() == LeakContext
->getStackFrame()))
2713 ReferenceRegion
= MR
;
2718 // Allocation node, is the last node in the current or parent context in
2719 // which the symbol was tracked.
2720 const LocationContext
*NContext
= N
->getLocationContext();
2721 if (NContext
== LeakContext
||
2722 NContext
->isParentOf(LeakContext
))
2724 N
= N
->pred_empty() ? nullptr : *(N
->pred_begin());
2727 return LeakInfo(AllocNode
, ReferenceRegion
);
2730 void MallocChecker::HandleLeak(SymbolRef Sym
, ExplodedNode
*N
,
2731 CheckerContext
&C
) const {
2733 if (!ChecksEnabled
[CK_MallocChecker
] &&
2734 !ChecksEnabled
[CK_NewDeleteLeaksChecker
])
2737 const RefState
*RS
= C
.getState()->get
<RegionState
>(Sym
);
2738 assert(RS
&& "cannot leak an untracked symbol");
2739 AllocationFamily Family
= RS
->getAllocationFamily();
2741 if (Family
== AF_Alloca
)
2744 std::optional
<MallocChecker::CheckKind
> CheckKind
=
2745 getCheckIfTracked(Family
, true);
2751 if (!BT_Leak
[*CheckKind
]) {
2752 // Leaks should not be reported if they are post-dominated by a sink:
2753 // (1) Sinks are higher importance bugs.
2754 // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
2755 // with __noreturn functions such as assert() or exit(). We choose not
2756 // to report leaks on such paths.
2757 BT_Leak
[*CheckKind
].reset(new BugType(CheckNames
[*CheckKind
], "Memory leak",
2758 categories::MemoryError
,
2759 /*SuppressOnSink=*/true));
2762 // Most bug reports are cached at the location where they occurred.
2763 // With leaks, we want to unique them by the location where they were
2764 // allocated, and only report a single path.
2765 PathDiagnosticLocation LocUsedForUniqueing
;
2766 const ExplodedNode
*AllocNode
= nullptr;
2767 const MemRegion
*Region
= nullptr;
2768 std::tie(AllocNode
, Region
) = getAllocationSite(N
, Sym
, C
);
2770 const Stmt
*AllocationStmt
= AllocNode
->getStmtForDiagnostics();
2772 LocUsedForUniqueing
= PathDiagnosticLocation::createBegin(AllocationStmt
,
2773 C
.getSourceManager(),
2774 AllocNode
->getLocationContext());
2776 SmallString
<200> buf
;
2777 llvm::raw_svector_ostream
os(buf
);
2778 if (Region
&& Region
->canPrintPretty()) {
2779 os
<< "Potential leak of memory pointed to by ";
2780 Region
->printPretty(os
);
2782 os
<< "Potential memory leak";
2785 auto R
= std::make_unique
<PathSensitiveBugReport
>(
2786 *BT_Leak
[*CheckKind
], os
.str(), N
, LocUsedForUniqueing
,
2787 AllocNode
->getLocationContext()->getDecl());
2788 R
->markInteresting(Sym
);
2789 R
->addVisitor
<MallocBugVisitor
>(Sym
, true);
2790 if (ShouldRegisterNoOwnershipChangeVisitor
)
2791 R
->addVisitor
<NoOwnershipChangeVisitor
>(Sym
, this);
2792 C
.emitReport(std::move(R
));
2795 void MallocChecker::checkDeadSymbols(SymbolReaper
&SymReaper
,
2796 CheckerContext
&C
) const
2798 ProgramStateRef state
= C
.getState();
2799 RegionStateTy OldRS
= state
->get
<RegionState
>();
2800 RegionStateTy::Factory
&F
= state
->get_context
<RegionState
>();
2802 RegionStateTy RS
= OldRS
;
2803 SmallVector
<SymbolRef
, 2> Errors
;
2804 for (auto [Sym
, State
] : RS
) {
2805 if (SymReaper
.isDead(Sym
)) {
2806 if (State
.isAllocated() || State
.isAllocatedOfSizeZero())
2807 Errors
.push_back(Sym
);
2808 // Remove the dead symbol from the map.
2809 RS
= F
.remove(RS
, Sym
);
2814 // We shouldn't have touched other maps yet.
2815 assert(state
->get
<ReallocPairs
>() ==
2816 C
.getState()->get
<ReallocPairs
>());
2817 assert(state
->get
<FreeReturnValue
>() ==
2818 C
.getState()->get
<FreeReturnValue
>());
2822 // Cleanup the Realloc Pairs Map.
2823 ReallocPairsTy RP
= state
->get
<ReallocPairs
>();
2824 for (auto [Sym
, ReallocPair
] : RP
) {
2825 if (SymReaper
.isDead(Sym
) || SymReaper
.isDead(ReallocPair
.ReallocatedSym
)) {
2826 state
= state
->remove
<ReallocPairs
>(Sym
);
2830 // Cleanup the FreeReturnValue Map.
2831 FreeReturnValueTy FR
= state
->get
<FreeReturnValue
>();
2832 for (auto [Sym
, RetSym
] : FR
) {
2833 if (SymReaper
.isDead(Sym
) || SymReaper
.isDead(RetSym
)) {
2834 state
= state
->remove
<FreeReturnValue
>(Sym
);
2838 // Generate leak node.
2839 ExplodedNode
*N
= C
.getPredecessor();
2840 if (!Errors
.empty()) {
2841 static CheckerProgramPointTag
Tag("MallocChecker", "DeadSymbolsLeak");
2842 N
= C
.generateNonFatalErrorNode(C
.getState(), &Tag
);
2844 for (SymbolRef Sym
: Errors
) {
2845 HandleLeak(Sym
, N
, C
);
2850 C
.addTransition(state
->set
<RegionState
>(RS
), N
);
2853 void MallocChecker::checkPreCall(const CallEvent
&Call
,
2854 CheckerContext
&C
) const {
2856 if (const auto *DC
= dyn_cast
<CXXDeallocatorCall
>(&Call
)) {
2857 const CXXDeleteExpr
*DE
= DC
->getOriginExpr();
2859 if (!ChecksEnabled
[CK_NewDeleteChecker
])
2860 if (SymbolRef Sym
= C
.getSVal(DE
->getArgument()).getAsSymbol())
2861 checkUseAfterFree(Sym
, C
, DE
->getArgument());
2863 if (!isStandardNewDelete(DC
->getDecl()))
2866 ProgramStateRef State
= C
.getState();
2867 bool IsKnownToBeAllocated
;
2868 State
= FreeMemAux(C
, DE
->getArgument(), Call
, State
,
2869 /*Hold*/ false, IsKnownToBeAllocated
,
2870 (DE
->isArrayForm() ? AF_CXXNewArray
: AF_CXXNew
));
2872 C
.addTransition(State
);
2876 if (const auto *DC
= dyn_cast
<CXXDestructorCall
>(&Call
)) {
2877 SymbolRef Sym
= DC
->getCXXThisVal().getAsSymbol();
2878 if (!Sym
|| checkDoubleDelete(Sym
, C
))
2882 // We will check for double free in the post visit.
2883 if (const AnyFunctionCall
*FC
= dyn_cast
<AnyFunctionCall
>(&Call
)) {
2884 const FunctionDecl
*FD
= FC
->getDecl();
2888 if (ChecksEnabled
[CK_MallocChecker
] && isFreeingCall(Call
))
2892 // Check if the callee of a method is deleted.
2893 if (const CXXInstanceCall
*CC
= dyn_cast
<CXXInstanceCall
>(&Call
)) {
2894 SymbolRef Sym
= CC
->getCXXThisVal().getAsSymbol();
2895 if (!Sym
|| checkUseAfterFree(Sym
, C
, CC
->getCXXThisExpr()))
2899 // Check arguments for being used after free.
2900 for (unsigned I
= 0, E
= Call
.getNumArgs(); I
!= E
; ++I
) {
2901 SVal ArgSVal
= Call
.getArgSVal(I
);
2902 if (isa
<Loc
>(ArgSVal
)) {
2903 SymbolRef Sym
= ArgSVal
.getAsSymbol();
2906 if (checkUseAfterFree(Sym
, C
, Call
.getArgExpr(I
)))
2912 void MallocChecker::checkPreStmt(const ReturnStmt
*S
,
2913 CheckerContext
&C
) const {
2914 checkEscapeOnReturn(S
, C
);
2917 // In the CFG, automatic destructors come after the return statement.
2918 // This callback checks for returning memory that is freed by automatic
2919 // destructors, as those cannot be reached in checkPreStmt().
2920 void MallocChecker::checkEndFunction(const ReturnStmt
*S
,
2921 CheckerContext
&C
) const {
2922 checkEscapeOnReturn(S
, C
);
2925 void MallocChecker::checkEscapeOnReturn(const ReturnStmt
*S
,
2926 CheckerContext
&C
) const {
2930 const Expr
*E
= S
->getRetValue();
2934 // Check if we are returning a symbol.
2935 ProgramStateRef State
= C
.getState();
2936 SVal RetVal
= C
.getSVal(E
);
2937 SymbolRef Sym
= RetVal
.getAsSymbol();
2939 // If we are returning a field of the allocated struct or an array element,
2940 // the callee could still free the memory.
2941 // TODO: This logic should be a part of generic symbol escape callback.
2942 if (const MemRegion
*MR
= RetVal
.getAsRegion())
2943 if (isa
<FieldRegion
, ElementRegion
>(MR
))
2944 if (const SymbolicRegion
*BMR
=
2945 dyn_cast
<SymbolicRegion
>(MR
->getBaseRegion()))
2946 Sym
= BMR
->getSymbol();
2948 // Check if we are returning freed memory.
2950 checkUseAfterFree(Sym
, C
, E
);
2953 // TODO: Blocks should be either inlined or should call invalidate regions
2954 // upon invocation. After that's in place, special casing here will not be
2956 void MallocChecker::checkPostStmt(const BlockExpr
*BE
,
2957 CheckerContext
&C
) const {
2959 // Scan the BlockDecRefExprs for any object the retain count checker
2961 if (!BE
->getBlockDecl()->hasCaptures())
2964 ProgramStateRef state
= C
.getState();
2965 const BlockDataRegion
*R
=
2966 cast
<BlockDataRegion
>(C
.getSVal(BE
).getAsRegion());
2968 auto ReferencedVars
= R
->referenced_vars();
2969 if (ReferencedVars
.empty())
2972 SmallVector
<const MemRegion
*, 10> Regions
;
2973 const LocationContext
*LC
= C
.getLocationContext();
2974 MemRegionManager
&MemMgr
= C
.getSValBuilder().getRegionManager();
2976 for (const auto &Var
: ReferencedVars
) {
2977 const VarRegion
*VR
= Var
.getCapturedRegion();
2978 if (VR
->getSuperRegion() == R
) {
2979 VR
= MemMgr
.getVarRegion(VR
->getDecl(), LC
);
2981 Regions
.push_back(VR
);
2985 state
->scanReachableSymbols
<StopTrackingCallback
>(Regions
).getState();
2986 C
.addTransition(state
);
2989 static bool isReleased(SymbolRef Sym
, CheckerContext
&C
) {
2991 const RefState
*RS
= C
.getState()->get
<RegionState
>(Sym
);
2992 return (RS
&& RS
->isReleased());
2995 bool MallocChecker::suppressDeallocationsInSuspiciousContexts(
2996 const CallEvent
&Call
, CheckerContext
&C
) const {
2997 if (Call
.getNumArgs() == 0)
3000 StringRef FunctionStr
= "";
3001 if (const auto *FD
= dyn_cast
<FunctionDecl
>(C
.getStackFrame()->getDecl()))
3002 if (const Stmt
*Body
= FD
->getBody())
3003 if (Body
->getBeginLoc().isValid())
3005 Lexer::getSourceText(CharSourceRange::getTokenRange(
3006 {FD
->getBeginLoc(), Body
->getBeginLoc()}),
3007 C
.getSourceManager(), C
.getLangOpts());
3009 // We do not model the Integer Set Library's retain-count based allocation.
3010 if (!FunctionStr
.contains("__isl_"))
3013 ProgramStateRef State
= C
.getState();
3015 for (const Expr
*Arg
: cast
<CallExpr
>(Call
.getOriginExpr())->arguments())
3016 if (SymbolRef Sym
= C
.getSVal(Arg
).getAsSymbol())
3017 if (const RefState
*RS
= State
->get
<RegionState
>(Sym
))
3018 State
= State
->set
<RegionState
>(Sym
, RefState::getEscaped(RS
));
3020 C
.addTransition(State
);
3024 bool MallocChecker::checkUseAfterFree(SymbolRef Sym
, CheckerContext
&C
,
3025 const Stmt
*S
) const {
3027 if (isReleased(Sym
, C
)) {
3028 HandleUseAfterFree(C
, S
->getSourceRange(), Sym
);
3035 void MallocChecker::checkUseZeroAllocated(SymbolRef Sym
, CheckerContext
&C
,
3036 const Stmt
*S
) const {
3039 if (const RefState
*RS
= C
.getState()->get
<RegionState
>(Sym
)) {
3040 if (RS
->isAllocatedOfSizeZero())
3041 HandleUseZeroAlloc(C
, RS
->getStmt()->getSourceRange(), Sym
);
3043 else if (C
.getState()->contains
<ReallocSizeZeroSymbols
>(Sym
)) {
3044 HandleUseZeroAlloc(C
, S
->getSourceRange(), Sym
);
3048 bool MallocChecker::checkDoubleDelete(SymbolRef Sym
, CheckerContext
&C
) const {
3050 if (isReleased(Sym
, C
)) {
3051 HandleDoubleDelete(C
, Sym
);
3057 // Check if the location is a freed symbolic region.
3058 void MallocChecker::checkLocation(SVal l
, bool isLoad
, const Stmt
*S
,
3059 CheckerContext
&C
) const {
3060 SymbolRef Sym
= l
.getLocSymbolInBase();
3062 checkUseAfterFree(Sym
, C
, S
);
3063 checkUseZeroAllocated(Sym
, C
, S
);
3067 // If a symbolic region is assumed to NULL (or another constant), stop tracking
3068 // it - assuming that allocation failed on this path.
3069 ProgramStateRef
MallocChecker::evalAssume(ProgramStateRef state
,
3071 bool Assumption
) const {
3072 RegionStateTy RS
= state
->get
<RegionState
>();
3073 for (SymbolRef Sym
: llvm::make_first_range(RS
)) {
3074 // If the symbol is assumed to be NULL, remove it from consideration.
3075 ConstraintManager
&CMgr
= state
->getConstraintManager();
3076 ConditionTruthVal AllocFailed
= CMgr
.isNull(state
, Sym
);
3077 if (AllocFailed
.isConstrainedTrue())
3078 state
= state
->remove
<RegionState
>(Sym
);
3081 // Realloc returns 0 when reallocation fails, which means that we should
3082 // restore the state of the pointer being reallocated.
3083 ReallocPairsTy RP
= state
->get
<ReallocPairs
>();
3084 for (auto [Sym
, ReallocPair
] : RP
) {
3085 // If the symbol is assumed to be NULL, remove it from consideration.
3086 ConstraintManager
&CMgr
= state
->getConstraintManager();
3087 ConditionTruthVal AllocFailed
= CMgr
.isNull(state
, Sym
);
3088 if (!AllocFailed
.isConstrainedTrue())
3091 SymbolRef ReallocSym
= ReallocPair
.ReallocatedSym
;
3092 if (const RefState
*RS
= state
->get
<RegionState
>(ReallocSym
)) {
3093 if (RS
->isReleased()) {
3094 switch (ReallocPair
.Kind
) {
3095 case OAR_ToBeFreedAfterFailure
:
3096 state
= state
->set
<RegionState
>(ReallocSym
,
3097 RefState::getAllocated(RS
->getAllocationFamily(), RS
->getStmt()));
3099 case OAR_DoNotTrackAfterFailure
:
3100 state
= state
->remove
<RegionState
>(ReallocSym
);
3103 assert(ReallocPair
.Kind
== OAR_FreeOnFailure
);
3107 state
= state
->remove
<ReallocPairs
>(Sym
);
3113 bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
3114 const CallEvent
*Call
,
3115 ProgramStateRef State
,
3116 SymbolRef
&EscapingSymbol
) const {
3118 EscapingSymbol
= nullptr;
3120 // For now, assume that any C++ or block call can free memory.
3121 // TODO: If we want to be more optimistic here, we'll need to make sure that
3122 // regions escape to C++ containers. They seem to do that even now, but for
3123 // mysterious reasons.
3124 if (!isa
<SimpleFunctionCall
, ObjCMethodCall
>(Call
))
3127 // Check Objective-C messages by selector name.
3128 if (const ObjCMethodCall
*Msg
= dyn_cast
<ObjCMethodCall
>(Call
)) {
3129 // If it's not a framework call, or if it takes a callback, assume it
3131 if (!Call
->isInSystemHeader() || Call
->argumentsMayEscape())
3134 // If it's a method we know about, handle it explicitly post-call.
3135 // This should happen before the "freeWhenDone" check below.
3136 if (isKnownDeallocObjCMethodName(*Msg
))
3139 // If there's a "freeWhenDone" parameter, but the method isn't one we know
3140 // about, we can't be sure that the object will use free() to deallocate the
3141 // memory, so we can't model it explicitly. The best we can do is use it to
3142 // decide whether the pointer escapes.
3143 if (std::optional
<bool> FreeWhenDone
= getFreeWhenDoneArg(*Msg
))
3144 return *FreeWhenDone
;
3146 // If the first selector piece ends with "NoCopy", and there is no
3147 // "freeWhenDone" parameter set to zero, we know ownership is being
3148 // transferred. Again, though, we can't be sure that the object will use
3149 // free() to deallocate the memory, so we can't model it explicitly.
3150 StringRef FirstSlot
= Msg
->getSelector().getNameForSlot(0);
3151 if (FirstSlot
.endswith("NoCopy"))
3154 // If the first selector starts with addPointer, insertPointer,
3155 // or replacePointer, assume we are dealing with NSPointerArray or similar.
3156 // This is similar to C++ containers (vector); we still might want to check
3157 // that the pointers get freed by following the container itself.
3158 if (FirstSlot
.startswith("addPointer") ||
3159 FirstSlot
.startswith("insertPointer") ||
3160 FirstSlot
.startswith("replacePointer") ||
3161 FirstSlot
.equals("valueWithPointer")) {
3165 // We should escape receiver on call to 'init'. This is especially relevant
3166 // to the receiver, as the corresponding symbol is usually not referenced
3168 if (Msg
->getMethodFamily() == OMF_init
) {
3169 EscapingSymbol
= Msg
->getReceiverSVal().getAsSymbol();
3173 // Otherwise, assume that the method does not free memory.
3174 // Most framework methods do not free memory.
3178 // At this point the only thing left to handle is straight function calls.
3179 const FunctionDecl
*FD
= cast
<SimpleFunctionCall
>(Call
)->getDecl();
3183 // If it's one of the allocation functions we can reason about, we model
3184 // its behavior explicitly.
3185 if (isMemCall(*Call
))
3188 // If it's not a system call, assume it frees memory.
3189 if (!Call
->isInSystemHeader())
3192 // White list the system functions whose arguments escape.
3193 const IdentifierInfo
*II
= FD
->getIdentifier();
3196 StringRef FName
= II
->getName();
3198 // White list the 'XXXNoCopy' CoreFoundation functions.
3199 // We specifically check these before
3200 if (FName
.endswith("NoCopy")) {
3201 // Look for the deallocator argument. We know that the memory ownership
3202 // is not transferred only if the deallocator argument is
3203 // 'kCFAllocatorNull'.
3204 for (unsigned i
= 1; i
< Call
->getNumArgs(); ++i
) {
3205 const Expr
*ArgE
= Call
->getArgExpr(i
)->IgnoreParenCasts();
3206 if (const DeclRefExpr
*DE
= dyn_cast
<DeclRefExpr
>(ArgE
)) {
3207 StringRef DeallocatorName
= DE
->getFoundDecl()->getName();
3208 if (DeallocatorName
== "kCFAllocatorNull")
3215 // Associating streams with malloced buffers. The pointer can escape if
3216 // 'closefn' is specified (and if that function does free memory),
3217 // but it will not if closefn is not specified.
3218 // Currently, we do not inspect the 'closefn' function (PR12101).
3219 if (FName
== "funopen")
3220 if (Call
->getNumArgs() >= 4 && Call
->getArgSVal(4).isConstant(0))
3223 // Do not warn on pointers passed to 'setbuf' when used with std streams,
3224 // these leaks might be intentional when setting the buffer for stdio.
3225 // http://stackoverflow.com/questions/2671151/who-frees-setvbuf-buffer
3226 if (FName
== "setbuf" || FName
=="setbuffer" ||
3227 FName
== "setlinebuf" || FName
== "setvbuf") {
3228 if (Call
->getNumArgs() >= 1) {
3229 const Expr
*ArgE
= Call
->getArgExpr(0)->IgnoreParenCasts();
3230 if (const DeclRefExpr
*ArgDRE
= dyn_cast
<DeclRefExpr
>(ArgE
))
3231 if (const VarDecl
*D
= dyn_cast
<VarDecl
>(ArgDRE
->getDecl()))
3232 if (D
->getCanonicalDecl()->getName().contains("std"))
3237 // A bunch of other functions which either take ownership of a pointer or
3238 // wrap the result up in a struct or object, meaning it can be freed later.
3239 // (See RetainCountChecker.) Not all the parameters here are invalidated,
3240 // but the Malloc checker cannot differentiate between them. The right way
3241 // of doing this would be to implement a pointer escapes callback.
3242 if (FName
== "CGBitmapContextCreate" ||
3243 FName
== "CGBitmapContextCreateWithData" ||
3244 FName
== "CVPixelBufferCreateWithBytes" ||
3245 FName
== "CVPixelBufferCreateWithPlanarBytes" ||
3246 FName
== "OSAtomicEnqueue") {
3250 if (FName
== "postEvent" &&
3251 FD
->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
3255 if (FName
== "connectImpl" &&
3256 FD
->getQualifiedNameAsString() == "QObject::connectImpl") {
3260 if (FName
== "singleShotImpl" &&
3261 FD
->getQualifiedNameAsString() == "QTimer::singleShotImpl") {
3265 // Handle cases where we know a buffer's /address/ can escape.
3266 // Note that the above checks handle some special cases where we know that
3267 // even though the address escapes, it's still our responsibility to free the
3269 if (Call
->argumentsMayEscape())
3272 // Otherwise, assume that the function does not free memory.
3273 // Most system calls do not free the memory.
3277 ProgramStateRef
MallocChecker::checkPointerEscape(ProgramStateRef State
,
3278 const InvalidatedSymbols
&Escaped
,
3279 const CallEvent
*Call
,
3280 PointerEscapeKind Kind
) const {
3281 return checkPointerEscapeAux(State
, Escaped
, Call
, Kind
,
3282 /*IsConstPointerEscape*/ false);
3285 ProgramStateRef
MallocChecker::checkConstPointerEscape(ProgramStateRef State
,
3286 const InvalidatedSymbols
&Escaped
,
3287 const CallEvent
*Call
,
3288 PointerEscapeKind Kind
) const {
3289 // If a const pointer escapes, it may not be freed(), but it could be deleted.
3290 return checkPointerEscapeAux(State
, Escaped
, Call
, Kind
,
3291 /*IsConstPointerEscape*/ true);
3294 static bool checkIfNewOrNewArrayFamily(const RefState
*RS
) {
3295 return (RS
->getAllocationFamily() == AF_CXXNewArray
||
3296 RS
->getAllocationFamily() == AF_CXXNew
);
3299 ProgramStateRef
MallocChecker::checkPointerEscapeAux(
3300 ProgramStateRef State
, const InvalidatedSymbols
&Escaped
,
3301 const CallEvent
*Call
, PointerEscapeKind Kind
,
3302 bool IsConstPointerEscape
) const {
3303 // If we know that the call does not free memory, or we want to process the
3304 // call later, keep tracking the top level arguments.
3305 SymbolRef EscapingSymbol
= nullptr;
3306 if (Kind
== PSK_DirectEscapeOnCall
&&
3307 !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call
, State
,
3313 for (SymbolRef sym
: Escaped
) {
3314 if (EscapingSymbol
&& EscapingSymbol
!= sym
)
3317 if (const RefState
*RS
= State
->get
<RegionState
>(sym
))
3318 if (RS
->isAllocated() || RS
->isAllocatedOfSizeZero())
3319 if (!IsConstPointerEscape
|| checkIfNewOrNewArrayFamily(RS
))
3320 State
= State
->set
<RegionState
>(sym
, RefState::getEscaped(RS
));
3325 bool MallocChecker::isArgZERO_SIZE_PTR(ProgramStateRef State
, CheckerContext
&C
,
3326 SVal ArgVal
) const {
3327 if (!KernelZeroSizePtrValue
)
3328 KernelZeroSizePtrValue
=
3329 tryExpandAsInteger("ZERO_SIZE_PTR", C
.getPreprocessor());
3331 const llvm::APSInt
*ArgValKnown
=
3332 C
.getSValBuilder().getKnownValue(State
, ArgVal
);
3333 return ArgValKnown
&& *KernelZeroSizePtrValue
&&
3334 ArgValKnown
->getSExtValue() == **KernelZeroSizePtrValue
;
3337 static SymbolRef
findFailedReallocSymbol(ProgramStateRef currState
,
3338 ProgramStateRef prevState
) {
3339 ReallocPairsTy currMap
= currState
->get
<ReallocPairs
>();
3340 ReallocPairsTy prevMap
= prevState
->get
<ReallocPairs
>();
3342 for (const ReallocPairsTy::value_type
&Pair
: prevMap
) {
3343 SymbolRef sym
= Pair
.first
;
3344 if (!currMap
.lookup(sym
))
3351 static bool isReferenceCountingPointerDestructor(const CXXDestructorDecl
*DD
) {
3352 if (const IdentifierInfo
*II
= DD
->getParent()->getIdentifier()) {
3353 StringRef N
= II
->getName();
3354 if (N
.contains_insensitive("ptr") || N
.contains_insensitive("pointer")) {
3355 if (N
.contains_insensitive("ref") || N
.contains_insensitive("cnt") ||
3356 N
.contains_insensitive("intrusive") ||
3357 N
.contains_insensitive("shared")) {
3365 PathDiagnosticPieceRef
MallocBugVisitor::VisitNode(const ExplodedNode
*N
,
3366 BugReporterContext
&BRC
,
3367 PathSensitiveBugReport
&BR
) {
3368 ProgramStateRef state
= N
->getState();
3369 ProgramStateRef statePrev
= N
->getFirstPred()->getState();
3371 const RefState
*RSCurr
= state
->get
<RegionState
>(Sym
);
3372 const RefState
*RSPrev
= statePrev
->get
<RegionState
>(Sym
);
3374 const Stmt
*S
= N
->getStmtForDiagnostics();
3375 // When dealing with containers, we sometimes want to give a note
3376 // even if the statement is missing.
3377 if (!S
&& (!RSCurr
|| RSCurr
->getAllocationFamily() != AF_InnerBuffer
))
3380 const LocationContext
*CurrentLC
= N
->getLocationContext();
3382 // If we find an atomic fetch_add or fetch_sub within the destructor in which
3383 // the pointer was released (before the release), this is likely a destructor
3384 // of a shared pointer.
3385 // Because we don't model atomics, and also because we don't know that the
3386 // original reference count is positive, we should not report use-after-frees
3387 // on objects deleted in such destructors. This can probably be improved
3388 // through better shared pointer modeling.
3389 if (ReleaseDestructorLC
) {
3390 if (const auto *AE
= dyn_cast
<AtomicExpr
>(S
)) {
3391 AtomicExpr::AtomicOp Op
= AE
->getOp();
3392 if (Op
== AtomicExpr::AO__c11_atomic_fetch_add
||
3393 Op
== AtomicExpr::AO__c11_atomic_fetch_sub
) {
3394 if (ReleaseDestructorLC
== CurrentLC
||
3395 ReleaseDestructorLC
->isParentOf(CurrentLC
)) {
3396 BR
.markInvalid(getTag(), S
);
3402 // FIXME: We will eventually need to handle non-statement-based events
3403 // (__attribute__((cleanup))).
3405 // Find out if this is an interesting point and what is the kind.
3407 std::unique_ptr
<StackHintGeneratorForSymbol
> StackHint
= nullptr;
3408 SmallString
<256> Buf
;
3409 llvm::raw_svector_ostream
OS(Buf
);
3411 if (Mode
== Normal
) {
3412 if (isAllocated(RSCurr
, RSPrev
, S
)) {
3413 Msg
= "Memory is allocated";
3414 StackHint
= std::make_unique
<StackHintGeneratorForSymbol
>(
3415 Sym
, "Returned allocated memory");
3416 } else if (isReleased(RSCurr
, RSPrev
, S
)) {
3417 const auto Family
= RSCurr
->getAllocationFamily();
3422 case AF_CXXNewArray
:
3423 case AF_IfNameIndex
:
3424 Msg
= "Memory is released";
3425 StackHint
= std::make_unique
<StackHintGeneratorForSymbol
>(
3426 Sym
, "Returning; memory was released");
3428 case AF_InnerBuffer
: {
3429 const MemRegion
*ObjRegion
=
3430 allocation_state::getContainerObjRegion(statePrev
, Sym
);
3431 const auto *TypedRegion
= cast
<TypedValueRegion
>(ObjRegion
);
3432 QualType ObjTy
= TypedRegion
->getValueType();
3433 OS
<< "Inner buffer of '" << ObjTy
<< "' ";
3435 if (N
->getLocation().getKind() == ProgramPoint::PostImplicitCallKind
) {
3436 OS
<< "deallocated by call to destructor";
3437 StackHint
= std::make_unique
<StackHintGeneratorForSymbol
>(
3438 Sym
, "Returning; inner buffer was deallocated");
3440 OS
<< "reallocated by call to '";
3441 const Stmt
*S
= RSCurr
->getStmt();
3442 if (const auto *MemCallE
= dyn_cast
<CXXMemberCallExpr
>(S
)) {
3443 OS
<< MemCallE
->getMethodDecl()->getDeclName();
3444 } else if (const auto *OpCallE
= dyn_cast
<CXXOperatorCallExpr
>(S
)) {
3445 OS
<< OpCallE
->getDirectCallee()->getDeclName();
3446 } else if (const auto *CallE
= dyn_cast
<CallExpr
>(S
)) {
3447 auto &CEMgr
= BRC
.getStateManager().getCallEventManager();
3448 CallEventRef
<> Call
=
3449 CEMgr
.getSimpleCall(CallE
, state
, CurrentLC
, {nullptr, 0});
3450 if (const auto *D
= dyn_cast_or_null
<NamedDecl
>(Call
->getDecl()))
3451 OS
<< D
->getDeclName();
3456 StackHint
= std::make_unique
<StackHintGeneratorForSymbol
>(
3457 Sym
, "Returning; inner buffer was reallocated");
3463 llvm_unreachable("Unhandled allocation family!");
3466 // See if we're releasing memory while inlining a destructor
3467 // (or one of its callees). This turns on various common
3468 // false positive suppressions.
3469 bool FoundAnyDestructor
= false;
3470 for (const LocationContext
*LC
= CurrentLC
; LC
; LC
= LC
->getParent()) {
3471 if (const auto *DD
= dyn_cast
<CXXDestructorDecl
>(LC
->getDecl())) {
3472 if (isReferenceCountingPointerDestructor(DD
)) {
3473 // This immediately looks like a reference-counting destructor.
3474 // We're bad at guessing the original reference count of the object,
3475 // so suppress the report for now.
3476 BR
.markInvalid(getTag(), DD
);
3477 } else if (!FoundAnyDestructor
) {
3478 assert(!ReleaseDestructorLC
&&
3479 "There can be only one release point!");
3480 // Suspect that it's a reference counting pointer destructor.
3481 // On one of the next nodes might find out that it has atomic
3482 // reference counting operations within it (see the code above),
3483 // and if so, we'd conclude that it likely is a reference counting
3484 // pointer destructor.
3485 ReleaseDestructorLC
= LC
->getStackFrame();
3486 // It is unlikely that releasing memory is delegated to a destructor
3487 // inside a destructor of a shared pointer, because it's fairly hard
3488 // to pass the information that the pointer indeed needs to be
3489 // released into it. So we're only interested in the innermost
3491 FoundAnyDestructor
= true;
3495 } else if (isRelinquished(RSCurr
, RSPrev
, S
)) {
3496 Msg
= "Memory ownership is transferred";
3497 StackHint
= std::make_unique
<StackHintGeneratorForSymbol
>(Sym
, "");
3498 } else if (hasReallocFailed(RSCurr
, RSPrev
, S
)) {
3499 Mode
= ReallocationFailed
;
3500 Msg
= "Reallocation failed";
3501 StackHint
= std::make_unique
<StackHintGeneratorForReallocationFailed
>(
3502 Sym
, "Reallocation failed");
3504 if (SymbolRef sym
= findFailedReallocSymbol(state
, statePrev
)) {
3505 // Is it possible to fail two reallocs WITHOUT testing in between?
3506 assert((!FailedReallocSymbol
|| FailedReallocSymbol
== sym
) &&
3507 "We only support one failed realloc at a time.");
3508 BR
.markInteresting(sym
);
3509 FailedReallocSymbol
= sym
;
3513 // We are in a special mode if a reallocation failed later in the path.
3514 } else if (Mode
== ReallocationFailed
) {
3515 assert(FailedReallocSymbol
&& "No symbol to look for.");
3517 // Is this is the first appearance of the reallocated symbol?
3518 if (!statePrev
->get
<RegionState
>(FailedReallocSymbol
)) {
3519 // We're at the reallocation point.
3520 Msg
= "Attempt to reallocate memory";
3521 StackHint
= std::make_unique
<StackHintGeneratorForSymbol
>(
3522 Sym
, "Returned reallocated memory");
3523 FailedReallocSymbol
= nullptr;
3535 // Generate the extra diagnostic.
3536 PathDiagnosticLocation Pos
;
3538 assert(RSCurr
->getAllocationFamily() == AF_InnerBuffer
);
3539 auto PostImplCall
= N
->getLocation().getAs
<PostImplicitCall
>();
3542 Pos
= PathDiagnosticLocation(PostImplCall
->getLocation(),
3543 BRC
.getSourceManager());
3545 Pos
= PathDiagnosticLocation(S
, BRC
.getSourceManager(),
3546 N
->getLocationContext());
3549 auto P
= std::make_shared
<PathDiagnosticEventPiece
>(Pos
, Msg
, true);
3550 BR
.addCallStackHint(P
, std::move(StackHint
));
3554 void MallocChecker::printState(raw_ostream
&Out
, ProgramStateRef State
,
3555 const char *NL
, const char *Sep
) const {
3557 RegionStateTy RS
= State
->get
<RegionState
>();
3559 if (!RS
.isEmpty()) {
3560 Out
<< Sep
<< "MallocChecker :" << NL
;
3561 for (auto [Sym
, Data
] : RS
) {
3562 const RefState
*RefS
= State
->get
<RegionState
>(Sym
);
3563 AllocationFamily Family
= RefS
->getAllocationFamily();
3564 std::optional
<MallocChecker::CheckKind
> CheckKind
=
3565 getCheckIfTracked(Family
);
3567 CheckKind
= getCheckIfTracked(Family
, true);
3569 Sym
->dumpToStream(Out
);
3573 Out
<< " (" << CheckNames
[*CheckKind
].getName() << ")";
3581 namespace allocation_state
{
3584 markReleased(ProgramStateRef State
, SymbolRef Sym
, const Expr
*Origin
) {
3585 AllocationFamily Family
= AF_InnerBuffer
;
3586 return State
->set
<RegionState
>(Sym
, RefState::getReleased(Family
, Origin
));
3589 } // end namespace allocation_state
3590 } // end namespace ento
3591 } // end namespace clang
3593 // Intended to be used in InnerPointerChecker to register the part of
3594 // MallocChecker connected to it.
3595 void ento::registerInnerPointerCheckerAux(CheckerManager
&mgr
) {
3596 MallocChecker
*checker
= mgr
.getChecker
<MallocChecker
>();
3597 checker
->ChecksEnabled
[MallocChecker::CK_InnerPointerChecker
] = true;
3598 checker
->CheckNames
[MallocChecker::CK_InnerPointerChecker
] =
3599 mgr
.getCurrentCheckerName();
3602 void ento::registerDynamicMemoryModeling(CheckerManager
&mgr
) {
3603 auto *checker
= mgr
.registerChecker
<MallocChecker
>();
3604 checker
->ShouldIncludeOwnershipAnnotatedFunctions
=
3605 mgr
.getAnalyzerOptions().getCheckerBooleanOption(checker
, "Optimistic");
3606 checker
->ShouldRegisterNoOwnershipChangeVisitor
=
3607 mgr
.getAnalyzerOptions().getCheckerBooleanOption(
3608 checker
, "AddNoOwnershipChangeNotes");
3611 bool ento::shouldRegisterDynamicMemoryModeling(const CheckerManager
&mgr
) {
3615 #define REGISTER_CHECKER(name) \
3616 void ento::register##name(CheckerManager &mgr) { \
3617 MallocChecker *checker = mgr.getChecker<MallocChecker>(); \
3618 checker->ChecksEnabled[MallocChecker::CK_##name] = true; \
3619 checker->CheckNames[MallocChecker::CK_##name] = \
3620 mgr.getCurrentCheckerName(); \
3623 bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
3625 REGISTER_CHECKER(MallocChecker
)
3626 REGISTER_CHECKER(NewDeleteChecker
)
3627 REGISTER_CHECKER(NewDeleteLeaksChecker
)
3628 REGISTER_CHECKER(MismatchedDeallocatorChecker
)