diff --git a/compiler-rt/lib/gwp_asan/CMakeLists.txt b/compiler-rt/lib/gwp_asan/CMakeLists.txt index 27d67036ed56d0ec7803d8debe9881ffb5e8fffd..c79ea4427b0c4bca409415478e64c7930a834b43 100644 --- a/compiler-rt/lib/gwp_asan/CMakeLists.txt +++ b/compiler-rt/lib/gwp_asan/CMakeLists.txt @@ -41,6 +41,11 @@ set(GWP_ASAN_HEADERS set(GWP_ASAN_CFLAGS ${SANITIZER_COMMON_CFLAGS} -fno-rtti -fno-exceptions -nostdinc++ -pthread -fno-omit-frame-pointer) append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC GWP_ASAN_CFLAGS) +# OHOS_LOCAL begin +if(OHOS) +list(APPEND GWP_ASAN_CFLAGS -fno-emulated-tls) +endif() +# OHOS_LOCAL end # append_list_if(COMPILER_RT_HAS_SANITIZER_COMMON ${SANITIZER_COMMON_CFLAGS} GWP_ASAN_CFLAGS) # Remove -stdlib= which is unused when passing -nostdinc++. diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp index 5bf1284e1f896f81a5b7164408294cf457da1df4..ef3923eb788db8fae739cbe6c8d4e13c4736f444 100644 --- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp +++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.cpp @@ -120,6 +120,13 @@ void GuardedPoolAllocator::enable() { BacktraceMutex.unlock(); } +// OHOS_LOCAL begin +void GuardedPoolAllocator::enableAtFork() { + PoolMutex.unlockAtFork(); + BacktraceMutex.unlockAtFork(); +} +// OHOS_LOCAL end + void GuardedPoolAllocator::iterate(void *Base, size_t Size, iterate_callback Cb, void *Arg) { uintptr_t Start = reinterpret_cast(Base); diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h index 152028acd822c28c96b9d8ebc6192f57aa469e30..f1086651395f12f4df0d05945efe83b5363c46c3 100644 --- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h +++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h @@ -63,6 +63,7 @@ public: // to allocate memory, until enable() is called. void disable(); void enable(); + void enableAtFork(); // OHOS_LOCAL typedef void (*iterate_callback)(uintptr_t base, size_t size, void *arg); // Execute the callback Cb for every allocation the lies in [Base, Base + diff --git a/compiler-rt/lib/gwp_asan/mutex.h b/compiler-rt/lib/gwp_asan/mutex.h index 34b91a2880ddcfc12fae4b939cb59a7454f76526..299eae6719ea79dd67cb8c992b00906f81867a95 100644 --- a/compiler-rt/lib/gwp_asan/mutex.h +++ b/compiler-rt/lib/gwp_asan/mutex.h @@ -25,6 +25,7 @@ public: bool tryLock(); // Unlock the mutex. void unlock(); + void unlockAtFork(); // OHOS_LOCAL }; class ScopedLock { diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp index 149b74238f0d98f3ad2a22d7a90e700116159583..f2db40aa3cb9647883df4344cdacc7320560b4b3 100644 --- a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp +++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp @@ -106,7 +106,13 @@ void GuardedPoolAllocator::installAtFork() { }; auto Enable = []() { if (auto *S = getSingleton()) +// OHOS_LOCAL begin +#if defined(__OHOS__) + S->enableAtFork(); +#else S->enable(); +#endif +// OHOS_LOCAL end }; pthread_atfork(Disable, Enable, Enable); } diff --git a/compiler-rt/lib/gwp_asan/platform_specific/mutex_posix.cpp b/compiler-rt/lib/gwp_asan/platform_specific/mutex_posix.cpp index 8bd405e1074cb39f7ce3a54cd53f5c49845e4e88..a3ee11c0e78ae0ea462a7da22d93d16834822cfa 100644 --- a/compiler-rt/lib/gwp_asan/platform_specific/mutex_posix.cpp +++ b/compiler-rt/lib/gwp_asan/platform_specific/mutex_posix.cpp @@ -27,4 +27,16 @@ void Mutex::unlock() { // Remove warning for non-debug builds. (void)Status; } + +// OHOS_LOCAL begin +// 1、OHOS uses recursive locks to avoid deadlock, such as this call chain: +// `gwp_asan malloc -> find double free -> get lock -> trigger segv -> +// segv handler -> malloc -> gwp_asan malloc` +// 2、It will be failed to unlock recursive lock after fork because tid changes, +// so we just create a new recursive lock here. +void Mutex::unlockAtFork() { + Mu = {{{PTHREAD_MUTEX_RECURSIVE}}}; +} +// OHOS_LOCAL end + } // namespace gwp_asan