aboutsummaryrefslogtreecommitdiff
path: root/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp')
-rw-r--r--compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.cpp109
1 files changed, 49 insertions, 60 deletions
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 8bc0aefeec44..a8767a4cb808 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
@@ -7,90 +7,79 @@
//===----------------------------------------------------------------------===//
#include "gwp_asan/guarded_pool_allocator.h"
+#include "gwp_asan/utilities.h"
-#include <stdlib.h>
+#include <assert.h>
#include <errno.h>
#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/mman.h>
-#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
-namespace gwp_asan {
+#ifdef ANDROID
+#include <sys/prctl.h>
+#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;
+}
-void *GuardedPoolAllocator::mapMemory(size_t Size) const {
+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);
-
- if (Ptr == MAP_FAILED) {
- Printf("Failed to map guarded pool allocator memory, errno: %d\n", errno);
- Printf(" mmap(nullptr, %zu, ...) failed.\n", Size);
- exit(EXIT_FAILURE);
- }
+ Check(Ptr != MAP_FAILED, "Failed to map guarded pool allocator memory");
+ MaybeSetMappingName(Ptr, Size, Name);
return Ptr;
}
-void GuardedPoolAllocator::markReadWrite(void *Ptr, size_t Size) const {
- if (mprotect(Ptr, Size, PROT_READ | PROT_WRITE) != 0) {
- Printf("Failed to set guarded pool allocator memory at as RW, errno: %d\n",
- errno);
- Printf(" mprotect(%p, %zu, RW) failed.\n", Ptr, Size);
- exit(EXIT_FAILURE);
- }
+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::markInaccessible(void *Ptr, size_t Size) const {
+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.
- if (mmap(Ptr, Size, PROT_NONE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1,
- 0) == MAP_FAILED) {
- Printf("Failed to set guarded pool allocator memory as inaccessible, "
- "errno: %d\n",
- errno);
- Printf(" mmap(%p, %zu, NONE, ...) failed.\n", Ptr, Size);
- exit(EXIT_FAILURE);
- }
+ 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);
}
-struct sigaction PreviousHandler;
-
-static void sigSegvHandler(int sig, siginfo_t *info, void *ucontext) {
- gwp_asan::GuardedPoolAllocator::reportError(
- reinterpret_cast<uintptr_t>(info->si_addr));
-
- // Process any previous handlers.
- if (PreviousHandler.sa_flags & SA_SIGINFO) {
- PreviousHandler.sa_sigaction(sig, info, ucontext);
- } else if (PreviousHandler.sa_handler == SIG_IGN ||
- PreviousHandler.sa_handler == SIG_DFL) {
- // If the previous handler was the default handler, or was ignoring this
- // signal, install the default handler and re-raise the signal in order to
- // get a core dump and terminate this process.
- signal(SIGSEGV, SIG_DFL);
- raise(SIGSEGV);
- } else {
- PreviousHandler.sa_handler(sig);
- }
-}
-
-void GuardedPoolAllocator::installSignalHandlers() {
- struct sigaction Action;
- Action.sa_sigaction = sigSegvHandler;
- Action.sa_flags = SA_SIGINFO;
- sigaction(SIGSEGV, &Action, &PreviousHandler);
-}
-
-uint64_t GuardedPoolAllocator::getThreadID() {
-#ifdef SYS_gettid
- return syscall(SYS_gettid);
-#else
- return kInvalidThreadID;
-#endif
+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