diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h index eac5e0f1dae45ca423f035aa7fdcfd6d78982980..61d88114b1b38e6a8d6b4062cc2949c91c583067 100644 --- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h +++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h @@ -102,6 +102,12 @@ public: PersistInterval / ReserveCounter, FreeSlotsLength); Nmalloc = 0; } + + // Make sure the current thread's RandomState is configrued before use + if (getThreadLocals()->is_configured == false) { + return false; + } + // If the RandomState is calculated from getRandomUnsigned32, the value // of RandomState will never be 1, so we use RandomState == 1 to force // GWP_ASAN sample. 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 bbf251a90cdd055e1b9e112de62b92ec6803134b..de13f6a344904fc852f3333e0adacaea1daeeeba 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 @@ -42,6 +42,11 @@ namespace gwp_asan { void GuardedPoolAllocator::initPRNG() { getThreadLocals()->RandomState = static_cast(time(nullptr) + getThreadID()); + // OHOS_LOCAL begin +#if defined(__OHOS__) + getThreadLocals()->is_configured = true; +#endif + // OHOS_LOCAL end } void *GuardedPoolAllocator::map(size_t Size, const char *Name) const { diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h index 347fadb99632dfcaa0f4fa333fdb994c82561e5d..628ce7fc6024e1589f5027b53f486abde3933f1a 100644 --- a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h +++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h @@ -18,8 +18,16 @@ namespace gwp_asan { // the same cache line for performance reasons. These are the most touched // variables in GWP-ASan. struct ThreadLocalPackedVariables { + // OHOS_LOCAL begin +#if defined(__OHOS__) + constexpr ThreadLocalPackedVariables() + : RandomState(0xacd979ce), NextSampleCounter(0), RecursiveGuard(false), + is_configured(false) {} +#else constexpr ThreadLocalPackedVariables() : RandomState(0xacd979ce), NextSampleCounter(0), RecursiveGuard(false) {} +#endif + // OHOS_LOCAL end // Initialised to a magic constant so that an uninitialised GWP-ASan won't // regenerate its sample counter for as long as possible. The xorshift32() // algorithm used below results in getRandomUnsigned32(0xacd979ce) == @@ -27,15 +35,29 @@ struct ThreadLocalPackedVariables { uint32_t RandomState; // Thread-local decrementing counter that indicates that a given allocation // should be sampled when it reaches zero. + // OHOS_LOCAL begin +#if defined(__OHOS__) + uint32_t NextSampleCounter : 30; + // The mask is needed to silence conversion errors. + static const uint32_t NextSampleCounterMask = (1U << 30) - 1; +#else uint32_t NextSampleCounter : 31; // The mask is needed to silence conversion errors. static const uint32_t NextSampleCounterMask = (1U << 31) - 1; +#endif + // OHOS_LOCAL end // Guard against recursivity. Unwinders often contain complex behaviour that // may not be safe for the allocator (i.e. the unwinder calls dlopen(), // which calls malloc()). When recursive behaviour is detected, we will // automatically fall back to the supporting allocator to supply the // allocation. bool RecursiveGuard : 1; + // OHOS_LOCAL begin +#if defined(__OHOS__) + // Check if thread local GWP_ASAN is configured. + bool is_configured : 1; +#endif + // OHOS_LOCAL end }; static_assert(sizeof(ThreadLocalPackedVariables) == sizeof(uint64_t), "thread local data does not fit in a uint64_t");