86 Commits

Author SHA1 Message Date
PiJoules
78c5d68029
[asan] Add size/alignment checks for free_[aligned_]sized (#189216)
Historically, alignment and size weren't taken into account when freeing
allocations since `free` just takes a pointer. With `free_sized` and
`free_aligned_sized`, we can do these size and alignment checks in asan
now. This adds a new report type specifically for these functions.

Checking is hidden behind a new env flag `free_size_mismatch` which is
enabled by default, but downstream users can opt out of it.

The bulk of this PR was generated by gemini but thoroughly reviewed and
edited by me to the best of my ability.
2026-03-31 19:10:43 +00:00
PiJoules
a5fa4dba6e
[compiler-rt] Add interceptors for free_[aligned_]sized for asan+hwasan (#189109) 2026-03-27 23:16:52 +00:00
Zack Johnson
7817197780
[ASan][Windows] Fix false positive for zero sized rtl allocations (#181015)
This is a follow up to #155943

On Windows, ASan's allocator internally upgrades zero-size allocation
requests to size 1 (since malloc(0) must return a unique non-NULL
pointer). However, when the user queries the allocation size through
Windows heap APIs (RtlSizeHeap, HeapSize, \_msize, GlobalSize,
LocalSize), ASan reports the internal size (1) instead of the originally
requested size (0).

This causes false positive heap-buffer-overflow errors in a common
pattern:

```c++
void *buf = HeapAlloc(GetProcessHeap(), 0, 0);
SIZE_T size = HeapSize(GetProcessHeap(), 0, buf);  // Returns 1, should be 0
if(size > 0) // could remove this and still be correct
    memset(buf, 0, size);  // ASan reports heap-buffer-overflow
```

The change adds a `from_zero_alloc` bit to `ChunkHeader` that tracks
whether an allocation was originally zero-size. This bit fits in the
existing spare capacity of the header's bitfield byte, so the 16-byte
ChunkHeader size is unchanged, but it also isn't the most elegant.

The 1-byte user region of a zero-size allocation is still poisoned, so
any actual access to it is correctly reported as an overflow.
2026-02-13 15:49:27 -05:00
Jake Egan
839676bef1
[asan][AIX] Add vec_malloc and vec_calloc interceptors (#175584)
On AIX, when both the `__VEC__` and `_ALL_SOURCE` macros are defined
(they are defined by default), the malloc and calloc system calls are
mapped to vec_malloc and vec_calloc respectively, so we need the
following vec_malloc and vec_calloc interceptors.

Issue: #138916
2026-02-09 13:09:41 -05:00
Thurston Dang
b3452d90b0
[asan] Detect dereferencing zero-alloc as heap buffer overflow (#155943)
When a zero-byte allocation is requested, ASan actually allocates 1-byte
for compatibility. This change poisons that byte, to detect
dereferences.

Also updates the test from #155933
2025-08-29 10:19:47 -07:00
Justin King
681c2ee4df
asan: refactor interceptor allocation/deallocation functions (#145087)
Do some refactoring to allocation/deallocation interceptors. Expose
explicit per-alloc_type functions and stop accepting explicit AllocType.
This ensures we do not accidentally mix.

NOTE: This change rejects attempts to call `operator new(<some_size>,
static_cast<std::align_val_t>(0))`.

For https://github.com/llvm/llvm-project/issues/144435

Signed-off-by: Justin King <jcking@google.com>
2025-07-22 15:47:23 -07:00
David Justo
0d7e64f5d2
[ASan][Windows] Honor asan config flags on windows when set through the user function (#122990)
**Related to:** https://github.com/llvm/llvm-project/issues/117925 
**Follow up to:** https://github.com/llvm/llvm-project/pull/117929

**Context:**
As noted in the linked issue, some ASan configuration flags are not
honored on Windows when set through the `__asan_default_options` user
function. The reason for this is that `__asan_default_options` is not
available by the time `AsanInitInternal` executes, which is responsible
for applying the ASan flags.

To fix this properly, we'll probably need a deep re-design of ASan
initialization so that it is consistent across OS'es.
In the meantime, this PR offers a practical workaround.

**This PR:** refactors part of `AsanInitInternal` so that **idempotent**
flag-applying steps are extracted into a new function `ApplyOptions`.
This function is **also** invoked in the "weak function callback" on
Windows (which gets called when `__asan_default_options` is available)
so that, if any flags were set through the user-function, they are
safely applied _then_.

Today, `ApplyOptions` contains only a subset of flags. My hope is that
`ApplyOptions` will over time, through incremental refactorings
`AsanInitInternal` so that **all** flags are eventually honored.

Other minor changes:
* The introduction of a `ApplyAllocatorOptions` helper method, needed to
implement `ApplyOptions` for allocator options without re-initializing
the entire allocator. Reinitializing the entire allocator is expensive,
as it may do a whole pass over all the marked memory. To my knowledge,
this isn't needed for the options captured in `ApplyAllocatorOptions`.
* Rename `ProcessFlags` to `ValidateFlags`, which seems like a more
accurate name to what that function does, and prevents confusion when
compared to the new `ApplyOptions` function.
2025-07-02 15:37:28 -07:00
andrewjcg
6b654a09c2
[sanitizer] Support "alloc_dealloc_mismatch" suppressions (#124197)
This adds a stack-based suppression for alloc-dealloc-mismatch
violations, using the function name to match.
2025-01-28 18:04:12 -08:00
Steven Wu
16f4e85860 Revert "[sanitizer] Remove GetCurrentThread nullness checks from Allocate"
This reverts commit 4411d1e3926d67c393e6a7bdb910bbe77507ff26 for
breaking Darwin bots:
  AddressSanitizer-Unit :: ./Asan-x86_64-calls-Noinst-Test/10/16
  AddressSanitizer-Unit :: ./Asan-x86_64-calls-Noinst-Test/12/16
  AddressSanitizer-Unit :: ./Asan-x86_64-calls-Noinst-Test/13/16
  AddressSanitizer-Unit :: ./Asan-x86_64-inline-Noinst-Test/10/16
  AddressSanitizer-Unit :: ./Asan-x86_64-inline-Noinst-Test/12/16
  AddressSanitizer-Unit :: ./Asan-x86_64-inline-Noinst-Test/13/16
  AddressSanitizer-Unit :: ./Asan-x86_64h-calls-Noinst-Test/10/16
  AddressSanitizer-Unit :: ./Asan-x86_64h-calls-Noinst-Test/12/16
  AddressSanitizer-Unit :: ./Asan-x86_64h-calls-Noinst-Test/13/16
  AddressSanitizer-Unit :: ./Asan-x86_64h-inline-Noinst-Test/10/16
  AddressSanitizer-Unit :: ./Asan-x86_64h-inline-Noinst-Test/12/16
  AddressSanitizer-Unit :: ./Asan-x86_64h-inline-Noinst-Test/13/16
2024-08-15 12:50:03 -07:00
Fangrui Song
4411d1e392
[sanitizer] Remove GetCurrentThread nullness checks from Allocate
The nullness check is unreachable.

* For the main thead and pthread_create created threads, the `*Allocate` functions must be called after `*_current_thread` is set.
set.
* For threads created by Linux's `clone`, static TLS is either reused or
  set to a new value (CLONE_SETTLS).

Make this change for asan/msan and possibly extend the change to other
sanitizers. (asan supports many platforms and I am not 100% certain that
all platforms have the property.)

Pull Request: https://github.com/llvm/llvm-project/pull/102828
2024-08-14 18:32:29 -07:00
Mitch Phillips
8681202dd6
[ASan] [HWASan] Add __sanitizer_ignore_free_hook() (#96749)
This change adds a new weak API function which makes the sanitizer
ignore the call to free(), and implements the
functionality in ASan and HWAsan. The runtime that implements this hook
can then call free() at a later point again on the same pointer (and
making sure the hook returns zero so that the memory will actually be
freed) when it's actually ready for the memory to be cleaned up.

This is needed in order to implement an sanitizer-compatible version
of Chrome's BackupRefPtr algorithm, since process-wide double-shimming
of malloc/free does not work on some platforms.

Requested and designed by @c01db33f (Mark) from Project Zero.

---------

Co-authored-by: Mark Brand <markbrand@google.com>
2024-07-12 13:41:01 +02:00
Zachary Johnson
5d6304f017 [NFC][asan] Change asan_init and asan_init_is_running; add setters/getters
For #71833
2023-11-09 13:57:46 -08:00
Vitaly Buka
30ac031dd5 [NFC][asan] Add FIXME for a posible optimization 2023-06-22 12:41:41 -07:00
Vitaly Buka
82a6152344 [asan] Don't double poison secondary allocations
Sanitizers allocate shadow and memory as MAP_NORESERVE.

User memory can stay this way and do not increase RSS as long as we
don't store there.

The shadow unpoisoning also can avoid RSS increase for zeroed pages.
However as soon we poison the shadow, we need the page in RSS.

To avoid unnececary RSS increase we should not poison memory just before
unpoisoning them.

Depends on D153497.

Reviewed By: thurston

Differential Revision: https://reviews.llvm.org/D153500
2023-06-22 12:35:21 -07:00
Vitaly Buka
a0509884d9 [asan] Optimize Quarantine of secondary allocations
For the secondary allocation we don't need poison and fill memory if we
skip quarantine, and we don't need to poison after quarantine. In both
cases the secondary allocator will unmap memory and unpoison the shadow
from get_allocator().Deallocate().

Depends on D153496.

Reviewed By: thurston

Differential Revision: https://reviews.llvm.org/D153497
2023-06-22 11:24:08 -07:00
Vitaly Buka
bd4bf4947c [NFC][asan] Add const to QuarantineCallback methods 2023-06-22 10:38:40 -07:00
Vitaly Buka
191c162d6e [NFC][asan] Extract FillChunk 2023-06-22 10:38:29 -07:00
Vitaly Buka
735bcc9279 [NFC][asan] Add QuarantineCallback::{PreQuarantine,RecyclePassThrough}
Reviewed By: thurston

Differential Revision: https://reviews.llvm.org/D153496
2023-06-22 10:28:27 -07:00
Vitaly Buka
9e68b7e0e0 [NFC][sanitizer] Rename internal getters 2023-06-21 21:05:27 -07:00
Vitaly Buka
96928abb4d [NFC][sanitizer] Pass user region into OnMapSecondary 2023-06-21 13:50:42 -07:00
Vitaly Buka
38dfcf96df [NFC][sanitizer] Add OnMapSecondary callback
Now it implemented as OnMap everywhere, but in follow up patches
we can optimize Asan handler.
2023-06-21 13:33:41 -07:00
Vitaly Buka
c172210492 [NFC][asan] Move AsanStats update
Deallocate is a more appropiate place to update free count.
2023-06-21 11:50:45 -07:00
Jin Xin Ng
7639265af4
[sanitizer] Implement __sanitizer_get_allocated_size_fast
The primary motivation for this change is to allow FreeHooks to obtain
the allocated size of the pointer being freed in a fast, efficient manner.

Differential Revision: https://reviews.llvm.org/D151360
2023-05-26 00:19:47 +00:00
Fangrui Song
8c63dc6f6d Internalize AllocationBegin functions after D147005
Reviewed By: thurston

Differential Revision: https://reviews.llvm.org/D148195
2023-04-13 10:28:58 -07:00
Vitaly Buka
39c0602414 [lsan] Rename IgnoreObjectLocked into IgnoreObject
We don't lock allocator for this call.
2023-04-05 16:17:44 -07:00
Thurston Dang
d644ab022a Update __sanitizer_get_allocated_begin to return const void*
D147005 introduced __sanitizer_get_allocated_begin, with a return
value of void*. This involved a few naughty casts that dropped the
const. This patch adds back the const qualifier.

Differential Revision: https://reviews.llvm.org/D147489
2023-04-04 00:43:36 +00:00
Thurston Dang
415b1cfd57 Add __sanitizer_get_allocated_begin API and implementations
This function will return the start of the allocation, if given a pointer that lies within an allocation. Otherwise, it returns NULL.

It will be useful for detecting dynamic TLS allocations in glibc >=2.25, which
uses malloc (see https://github.com/google/sanitizers/issues/1409#issuecomment-1214244142).

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D147005
2023-04-03 21:27:51 +00:00
Kirill Stoimenov
eb3be66028 [LSAN] Add GetUserAddr function which returns the user visible address of an internal pointer
For HWASAN this would be the tagged address. It is the same pointer when pointer tagging is not used. Coincidently this also fixes some test which rely on comparing pointers.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D143121
2023-02-02 00:39:00 +00:00
Kirill Stoimenov
e022ca8b6e [HWASAN] Implemented LSAN SetLsanTag and IgnoreObjectLocked
Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D141642
2023-01-17 17:59:17 -08:00
Kirill Stoimenov
c184423e70 [LSAN] More LSAN interface tweaking.
Main goal is to remove thread registry dependency from the interface because HWASAN is using its own code to manage threads.

Reviewed By: vitalybuka, kstoimenov

Differential Revision: https://reviews.llvm.org/D140039
2023-01-12 17:58:11 -08:00
Vitaly Buka
eb2db81eba Revert "[LSAN] More LSAN interface tweaking."
Breaks bots.
Also it's missing changes we discussed on review.

This reverts commit f001e50f955c3cdf2deb79e38a9fd19c9a781882.
This reverts commit 2924189233fdb724453ead4b94595107b1ce9cfa.
2023-01-12 17:32:40 -08:00
Kirill Stoimenov
2924189233 [LSAN] More LSAN interface tweaking.
Main goal is to remove thread registry dependency from the interface because HWASAN is using its own code to manage threads.

Reviewed By: vitalybuka, kstoimenov

Differential Revision: https://reviews.llvm.org/D140039
2023-01-12 23:44:08 +00:00
Florian Mayer
be366041fa [ASan] rename left/right to before/after.
left/right is a weird way to refer to address ordering.

Reviewed By: eugenis, MaskRay

Differential Revision: https://reviews.llvm.org/D132611
2022-09-06 13:25:15 -07:00
Vitaly Buka
12e137ab24 [NFC][sanitizer] Consolidate malloc hook invocations 2022-04-12 20:08:29 -07:00
Vitaly Buka
b84673b3f4 [NFC][sanitizer] Remove unnececary HOOK macros 2022-04-12 19:47:44 -07:00
Dmitry Vyukov
765921de5b sanitizer_common: prefix thread-safety macros with SANITIZER_
Currently we use very common names for macros like ACQUIRE/RELEASE,
which cause conflicts with system headers.
Prefix all macros with SANITIZER_ to avoid conflicts.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D116652
2022-01-07 15:11:00 +01:00
Kirill Stoimenov
ad56941a57 [ASan] Renamed SHADOW_XYZ to ASAN_SHADOW_XYZ.
Follow up from D115271.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D115293
2021-12-08 00:22:56 +00:00
Vitaly Buka
36e6a259c8 [NFC][sanitizer] Remove SetSoftRssLimitExceededCallback
According comments on D44404, something like that was the goal.

Reviewed By: morehouse, kstoimenov

Differential Revision: https://reviews.llvm.org/D114991
2021-12-02 14:37:02 -08:00
Vitaly Buka
d48d8670b5 [NFC][sanitizer] Rename RssLimitExceeded -> IsRssLimitExceeded 2021-12-02 12:52:00 -08:00
Vitaly Buka
07092ea6bd [asan] Fix GCC warning "left shift count >= width"
Fixes PR52385
2021-11-12 13:04:00 -08:00
Martin Liska
629b40dafa Fix -Wformat warnings reported by GCC.
Differential Revision: https://reviews.llvm.org/D113099
2021-11-04 08:51:43 +01:00
Vitaly Buka
d2df5ce294 [NFC][asan] Remove redundant functions 2021-09-30 19:38:23 -07:00
Dmitry Vyukov
0da172b176 sanitizer_common: add thread safety annotations
Enable clang Thread Safety Analysis for sanitizers:
https://clang.llvm.org/docs/ThreadSafetyAnalysis.html

Thread Safety Analysis can detect inconsistent locking,
deadlocks and data races. Without GUARDED_BY annotations
it has limited value. But this does all the heavy lifting
to enable analysis and allows to add GUARDED_BY incrementally.

Reviewed By: melver

Differential Revision: https://reviews.llvm.org/D105716
2021-07-12 11:46:49 +02:00
Dmitry Vyukov
92a3a2dc3e sanitizer_common: introduce kInvalidTid/kMainTid
Currently we have a bit of a mess related to tids:
 - sanitizers re-declare kInvalidTid multiple times
 - some call it kUnknownTid
 - implicit assumptions that main tid is 0
 - asan/memprof claim their tids need to fit into 24 bits,
   but this does not seem to be true anymore
 - inconsistent use of u32/int to store tids

Introduce kInvalidTid/kMainTid in sanitizer_common
and use them consistently.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D101428
2021-04-30 15:58:05 +02:00
Dan Liew
596d534ac3 [ASan] Stop blocking child thread progress from parent thread in pthread_create interceptor.
Previously in ASan's `pthread_create` interceptor we would block in the
`pthread_create` interceptor waiting for the child thread to start.

Unfortunately this has bad performance characteristics because the OS
scheduler doesn't know the relationship between the parent and child
thread (i.e. the parent thread cannot make progress until the child
thread makes progress) and may make the wrong scheduling decision which
stalls progress.

It turns out that ASan didn't use to block in this interceptor but was
changed to do so to try to address
http://llvm.org/bugs/show_bug.cgi?id=21621/.

In that bug the problem being addressed was a LeakSanitizer false
positive. That bug concerns a heap object being passed
as `arg` to `pthread_create`. If:

* The calling thread loses a live reference to the object (e.g.
  `pthread_create` finishes and the thread no longer has a live
  reference to the object).
* Leak checking is triggered.
* The child thread has not yet started (once it starts it will have a
  live reference).

then the heap object will incorrectly appear to be leaked.

This bug is covered by the `lsan/TestCases/leak_check_before_thread_started.cpp` test case.

In b029c5101fb49b3577a1c322f42ef9fc616f25bf ASan was changed to block
in `pthread_create()` until the child thread starts so that `arg` is
kept alive for the purposes of leaking check.

While this change "works" its problematic due to the performance
problems it causes. The change is also completely unnecessary if leak
checking is disabled (via detect_leaks runtime option or
CAN_SANITIZE_LEAKS compile time config).

This patch does two things:

1. Takes a different approach to solving the leak false positive by
   making LSan's leak checking mechanism treat the `arg` pointer of
   created but not started threads as reachable.  This is done by
   implementing the `ForEachRegisteredThreadContextCb` callback for
   ASan.

2. Removes the blocking behaviour in the ASan `pthread_create`
   interceptor.

rdar://problem/63537240

Differential Revision: https://reviews.llvm.org/D95184
2021-01-22 23:34:43 -08:00
Dan Liew
dd922bc2a6 [LSan] Introduce a callback mechanism to allow adding data reachable from ThreadContexts to the frontier.
This mechanism is intended to provide a way to treat the `arg` pointer
of a created (but not yet started) thread as reachable. In future
patches this will be implemented in `GetAdditionalThreadContextPtrs`.

A separate implementation of `GetAdditionalThreadContextPtrs` exists
for ASan and LSan runtimes because they need to be implemented
differently in future patches.

rdar://problem/63537240

Differential Revision: https://reviews.llvm.org/D95183
2021-01-22 19:26:02 -08:00
Vitaly Buka
a8a85166d8 Revert "[Asan] Accept __lsan_ignore_object for redzone pointer"
We still keep AddrIsInside.

This reverts commit 1d70984fa220f966ddcecd7906c5f10368fe1b93.
2020-09-16 00:34:43 -07:00
Vitaly Buka
b42fa0c040 Revert "[Asan] Fix false leak report"
Additional investigated confirmed that issue is not about
AddrIsInside, but missing registers.

This reverts commit 9d01612db48fa27d18c6320974b8d711572e5c67.
2020-09-16 00:26:32 -07:00
Vitaly Buka
943b0c8bff [NFC][Asan] Remove chunk pointer from metadata
kAllocBegMagic should be enough.
kAllocBegMagic is already set for the Secondary allocations.
kAllocBegMagic is good enough for the Primary, but it's even safer for
the Secondary allocator as all allocated block are from mmap.

Depends on D87646.

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D87647
2020-09-15 00:22:24 -07:00
Vitaly Buka
4540d3baad [NFC][Asan] Return uptr as before D87646 2020-09-15 00:16:55 -07:00