//===-- guarded_pool_allocator_posix.cpp ------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "gwp_asan/guarded_pool_allocator.h" #include "gwp_asan/utilities.h" #include #include #include #include #include #include #include #include #ifdef ANDROID #include #define PR_SET_VMA 0x53564d41 #define PR_SET_VMA_ANON_NAME 0 #endif // ANDROID void MaybeSetMappingName(void *Mapping, size_t Size, const char *Name) { #ifdef ANDROID prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, Mapping, Size, Name); #endif // ANDROID // Anonymous mapping names are only supported on Android. return; } namespace gwp_asan { void *GuardedPoolAllocator::mapMemory(size_t Size, const char *Name) const { void *Ptr = mmap(nullptr, Size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); Check(Ptr != MAP_FAILED, "Failed to map guarded pool allocator memory"); MaybeSetMappingName(Ptr, Size, Name); return Ptr; } void GuardedPoolAllocator::unmapMemory(void *Ptr, size_t Size, const char *Name) const { Check(munmap(Ptr, Size) == 0, "Failed to unmap guarded pool allocator memory."); MaybeSetMappingName(Ptr, Size, Name); } void GuardedPoolAllocator::markReadWrite(void *Ptr, size_t Size, const char *Name) const { Check(mprotect(Ptr, Size, PROT_READ | PROT_WRITE) == 0, "Failed to set guarded pool allocator memory at as RW."); MaybeSetMappingName(Ptr, Size, Name); } void GuardedPoolAllocator::markInaccessible(void *Ptr, size_t Size, const char *Name) const { // mmap() a PROT_NONE page over the address to release it to the system, if // we used mprotect() here the system would count pages in the quarantine // against the RSS. Check(mmap(Ptr, Size, PROT_NONE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0) != MAP_FAILED, "Failed to set guarded pool allocator memory as inaccessible."); MaybeSetMappingName(Ptr, Size, Name); } size_t GuardedPoolAllocator::getPlatformPageSize() { return sysconf(_SC_PAGESIZE); } void GuardedPoolAllocator::installAtFork() { auto Disable = []() { if (auto *S = getSingleton()) S->disable(); }; auto Enable = []() { if (auto *S = getSingleton()) S->enable(); }; pthread_atfork(Disable, Enable, Enable); } } // namespace gwp_asan