1 //===-- guarded_pool_allocator_posix.cpp ------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "gwp_asan/guarded_pool_allocator.h"
15 #include <sys/syscall.h>
16 #include <sys/types.h>
21 void *GuardedPoolAllocator::mapMemory(size_t Size) const {
23 mmap(nullptr, Size, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
25 if (Ptr == MAP_FAILED) {
26 Printf("Failed to map guarded pool allocator memory, errno: %d\n", errno);
27 Printf(" mmap(nullptr, %zu, ...) failed.\n", Size);
33 void GuardedPoolAllocator::markReadWrite(void *Ptr, size_t Size) const {
34 if (mprotect(Ptr, Size, PROT_READ | PROT_WRITE) != 0) {
35 Printf("Failed to set guarded pool allocator memory at as RW, errno: %d\n",
37 Printf(" mprotect(%p, %zu, RW) failed.\n", Ptr, Size);
42 void GuardedPoolAllocator::markInaccessible(void *Ptr, size_t Size) const {
43 // mmap() a PROT_NONE page over the address to release it to the system, if
44 // we used mprotect() here the system would count pages in the quarantine
46 if (mmap(Ptr, Size, PROT_NONE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1,
48 Printf("Failed to set guarded pool allocator memory as inaccessible, "
51 Printf(" mmap(%p, %zu, NONE, ...) failed.\n", Ptr, Size);
56 size_t GuardedPoolAllocator::getPlatformPageSize() {
57 return sysconf(_SC_PAGESIZE);
60 struct sigaction PreviousHandler;
62 static void sigSegvHandler(int sig, siginfo_t *info, void *ucontext) {
63 gwp_asan::GuardedPoolAllocator::reportError(
64 reinterpret_cast<uintptr_t>(info->si_addr));
66 // Process any previous handlers.
67 if (PreviousHandler.sa_flags & SA_SIGINFO) {
68 PreviousHandler.sa_sigaction(sig, info, ucontext);
69 } else if (PreviousHandler.sa_handler == SIG_IGN ||
70 PreviousHandler.sa_handler == SIG_DFL) {
71 // If the previous handler was the default handler, or was ignoring this
72 // signal, install the default handler and re-raise the signal in order to
73 // get a core dump and terminate this process.
74 signal(SIGSEGV, SIG_DFL);
77 PreviousHandler.sa_handler(sig);
81 void GuardedPoolAllocator::installSignalHandlers() {
82 struct sigaction Action;
83 Action.sa_sigaction = sigSegvHandler;
84 Action.sa_flags = SA_SIGINFO;
85 sigaction(SIGSEGV, &Action, &PreviousHandler);
88 uint64_t GuardedPoolAllocator::getThreadID() {
90 return syscall(SYS_gettid);
92 return kInvalidThreadID;
96 } // namespace gwp_asan