Most sanitizers don't support static linking. One primary reason is the
incompatibility with interceptors. `GetTlsSize` is another reason.
asan/memprof use `__interception::DoesNotSupportStaticLinking`
(`_DYNAMIC` reference) to reject -static at link time. Port this
detector to other sanitizers. dfsan actually supports -static for
certain cases. Don't touch dfsan.
This is preparation for performance optimization.
We need to highlight that this is very specific lock, and should not be
used for other purposes.
Add `fork_child` parameter to distinguish processes after fork.
Prior to this, we would check if the end of the allocator cache was located
before the end of the chunk passed to the tls check. However, if the actual
allocator cache comes after the end of the chunk, then the sub in the
`end - params->allocator_caches[i]` bit overflows. Since the resulting type
is an unsigned uptr, this is not UB, but if the signed result would be a
negative value (ie. `end < params->allocator_caches[i]`) then this will
actually result in a very large unsigned value much bigger than the compared
`sizeof(AllocatorCache)` which will almost always be true. This can cause
ScanRangeForPointers to accept incorrect values: a begin pointing to some
address, and `params->allocator_caches[i]` pointing to some much larger
address way past the end of the chunk which can result in a page fault/stack overflow.
Differential Revision: https://reviews.llvm.org/D159518
When scanning over TLS regions, we attempt to check if one of the regions is
one of the thread_local allocator caches which would be located in one of the
TLS blocks pointer to by the DTV. This is to prevent marking a pointer that was
allocated by the primary allocator (from a thread_local cache) as reachable. The
check is a simple bounds check to see if the allocator cache is within the
bounds of one of the TLS block we're iterating over, but it looks like the check
for the end of the cache is slightly incorrect.
Differential Revision: https://reviews.llvm.org/D156015
This patch uses similar allocator configuration to Asan, i.e. dynamic
allocator start address (~(uptr)0) and 128 GB allocator size.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D152895
Before this patch when running HWASAN on x86_64 with with memory tagging support we got a bunch of false memory leak reports. The reason for that is that the heuristic used to detect if an 8 bytes could be a user pointer was not valid when memory tagging is used as the top byte could contain non-zero information.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D155338
The method cache stashes a mask in the high bits under some circumstances:
689525d556/runtime/objc-cache.mm (L589)
I'm hitting this now on macOS 13.4 arm64, so we can no longer rely on OBJC_FAST_IS_RW to identify potential pointers that need to be transformed
Differential Revision: https://reviews.llvm.org/D153471
Currently if a program calls sigaction very early (before non-lazy sanitizer
initialization, in particular if .preinit_array initialization is not enabled),
then sigaction will wrongly fail since the interceptor is not initialized yet.
In all other interceptors we do lazy runtime initialization for this reason,
but we don't do it in the signal interceptors.
Do lazy runtime initialization in signal interceptors as well.
Reviewed By: melver
Differential Revision: https://reviews.llvm.org/D155188
Usually root_regions size is small so unlikey
this change will provide a noticable difference.
However it's easy to make sure that even with
large number of root_regions it works reasonably
fast.
Differential Revision: https://reviews.llvm.org/D151781
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
__sanitizer_get_current_allocated_bytes had as body, but allocator
caches were not registered to collect stats. It's done by
SizeClassAllocator64LocalCache::Init().
Reviewed By: thurston
Differential Revision: https://reviews.llvm.org/D151355
Most uses of ALIAS() are in conjunction with WRAPPER_NAME().
Simplify the code and just make ALIAS() turn its argument into a string
(similar to Linux kernel's __alias macro). This in turn allows removing
WRAPPER_NAME().
NFC.
Reviewed By: dvyukov
Differential Revision: https://reviews.llvm.org/D151216
Previously lsan would not invoke hooks on reallocations.
An accompanying regression test is included in sanitizer_common.
This change also moves hook calls to a location where subsequent
calls (via an external caller) to __sanitizer_get_allocated_size
via hooks will return a valid size.
This allows a faster version of __sanitizer_get_allocated_size
to be implemented, which can skip checks.
Test to ensure RunFreeHooks' call order will come with
__sanitizer_get_allocated_size_fast
Differential Revision: https://reviews.llvm.org/D151175
Bionic uses pthread_exit to set retval, when GLIBC does not.
This cause double call to Finish. Rather then tracking this difference
on interceptor size, we can just relax precondition. It does not make
a difference.
This is more RAM and CPU efficient than allocating entire page per
context, and this approach is used by other sanitizers already.
With the patch "create_thread_loop2.cpp.tmp 5000" is 30% faster.
Comment "No lock needed" in CurrentThreadContext was wrong.
Concurent ThreadRegistry::CreateThread can resize and relocate
ThreadRegistry::threads_ the same time CurrentThreadContext reads it.
To mitigate lock cost we store ThreadContext* instead of tid in
THREADLOCAL cache, we can tid from the ThreadContext*.
Reviewed By: kstoimenov, MaskRay
Differential Revision: https://reviews.llvm.org/D148281