[compiler-rt] 63ad087 - [GWP-ASan] Fuchsia specific mapping & utilities functions
Kostya Kortchinsky via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 31 10:23:13 PDT 2020
Author: Kostya Kortchinsky
Date: 2020-10-31T10:22:58-07:00
New Revision: 63ad0876567d7a782daedfe9f564942a37f063f5
URL: https://github.com/llvm/llvm-project/commit/63ad0876567d7a782daedfe9f564942a37f063f5
DIFF: https://github.com/llvm/llvm-project/commit/63ad0876567d7a782daedfe9f564942a37f063f5.diff
LOG: [GWP-ASan] Fuchsia specific mapping & utilities functions
This CL introduces the Fuchsia versions of the existing platform
specific functions.
For Fuchsia, we need to track the VMAR (https://fuchsia.dev/fuchsia-src/reference/kernel_objects/vm_address_region)
of the Guarded Pool mapping, and for this purpose I added some platform
specific data structure that remains empty on POSIX platforms.
`getThreadID` is not super useful for Fuchsia so it's just left as a
stub for now.
While testing the changes in my Fuchsia tree, I realized that
`guarded_pool_allocator_tls.h` should have closed the namespace before
including `GWP_ASAN_PLATFORM_TLS_HEADER`, otherwise drama ensues.
This was tested in g3, upstream LLVM, and Fuchsia (with local changes).
Differential Revision: https://reviews.llvm.org/D90483
Added:
compiler-rt/lib/gwp_asan/platform_specific/common_fuchsia.cpp
compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.cpp
compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.h
compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.h
compiler-rt/lib/gwp_asan/platform_specific/utilities_fuchsia.cpp
Modified:
compiler-rt/lib/gwp_asan/CMakeLists.txt
compiler-rt/lib/gwp_asan/guarded_pool_allocator.h
compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_tls.h
Removed:
################################################################################
diff --git a/compiler-rt/lib/gwp_asan/CMakeLists.txt b/compiler-rt/lib/gwp_asan/CMakeLists.txt
index df95cd302297..92f578585b54 100644
--- a/compiler-rt/lib/gwp_asan/CMakeLists.txt
+++ b/compiler-rt/lib/gwp_asan/CMakeLists.txt
@@ -22,6 +22,8 @@ set(GWP_ASAN_HEADERS
mutex.h
options.h
options.inc
+ platform_specific/guarded_pool_allocator_fuchsia.h
+ platform_specific/guarded_pool_allocator_posix.h
platform_specific/guarded_pool_allocator_tls.h
platform_specific/mutex_fuchsia.h
platform_specific/mutex_posix.h
diff --git a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h
index 5ce70e467c72..84ebda13955f 100644
--- a/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h
+++ b/compiler-rt/lib/gwp_asan/guarded_pool_allocator.h
@@ -13,6 +13,8 @@
#include "gwp_asan/definitions.h"
#include "gwp_asan/mutex.h"
#include "gwp_asan/options.h"
+#include "gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.h"
+#include "gwp_asan/platform_specific/guarded_pool_allocator_posix.h"
#include "gwp_asan/platform_specific/guarded_pool_allocator_tls.h"
#include "gwp_asan/stack_trace_compressor.h"
@@ -207,6 +209,9 @@ class GuardedPoolAllocator {
// the sample rate.
uint32_t AdjustedSampleRatePlusOne = 0;
+ // Additional platform specific data structure for the guarded pool mapping.
+ PlatformSpecificMapData GuardedPagePoolPlatformData = {};
+
class ScopedRecursiveGuard {
public:
ScopedRecursiveGuard() { getThreadLocals()->RecursiveGuard = true; }
diff --git a/compiler-rt/lib/gwp_asan/platform_specific/common_fuchsia.cpp b/compiler-rt/lib/gwp_asan/platform_specific/common_fuchsia.cpp
new file mode 100644
index 000000000000..b469ef87d70f
--- /dev/null
+++ b/compiler-rt/lib/gwp_asan/platform_specific/common_fuchsia.cpp
@@ -0,0 +1,15 @@
+//===-- common_fuchsia.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/common.h"
+
+namespace gwp_asan {
+// This is only used for AllocationTrace.ThreadID and allocation traces are not
+// yet supported on Fuchsia.
+uint64_t getThreadID() { return kInvalidThreadID; }
+} // namespace gwp_asan
diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.cpp b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.cpp
new file mode 100644
index 000000000000..f58d4b104b39
--- /dev/null
+++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.cpp
@@ -0,0 +1,103 @@
+//===-- guarded_pool_allocator_fuchsia.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 <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include <zircon/limits.h>
+#include <zircon/process.h>
+#include <zircon/syscalls.h>
+
+namespace gwp_asan {
+void GuardedPoolAllocator::initPRNG() {
+ _zx_cprng_draw(&getThreadLocals()->RandomState, sizeof(uint32_t));
+}
+
+void *GuardedPoolAllocator::map(size_t Size, const char *Name) const {
+ assert((Size % State.PageSize) == 0);
+ zx_handle_t Vmo;
+ zx_status_t Status = _zx_vmo_create(Size, 0, &Vmo);
+ Check(Status == ZX_OK, "Failed to create Vmo");
+ _zx_object_set_property(Vmo, ZX_PROP_NAME, Name, strlen(Name));
+ zx_vaddr_t Addr;
+ Status = _zx_vmar_map(_zx_vmar_root_self(),
+ ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_ALLOW_FAULTS,
+ 0, Vmo, 0, Size, &Addr);
+ Check(Status == ZX_OK, "Vmo mapping failed");
+ _zx_handle_close(Vmo);
+ return reinterpret_cast<void *>(Addr);
+}
+
+void GuardedPoolAllocator::unmap(void *Ptr, size_t Size) const {
+ assert((reinterpret_cast<uintptr_t>(Ptr) % State.PageSize) == 0);
+ assert((Size % State.PageSize) == 0);
+ zx_status_t Status = _zx_vmar_unmap(_zx_vmar_root_self(),
+ reinterpret_cast<zx_vaddr_t>(Ptr), Size);
+ Check(Status == ZX_OK, "Vmo unmapping failed");
+}
+
+void *GuardedPoolAllocator::reserveGuardedPool(size_t Size) {
+ assert((Size % State.PageSize) == 0);
+ zx_vaddr_t Addr;
+ const zx_status_t Status = _zx_vmar_allocate(
+ _zx_vmar_root_self(),
+ ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC, 0,
+ Size, &GuardedPagePoolPlatformData.Vmar, &Addr);
+ Check(Status == ZX_OK, "Failed to reserve guarded pool allocator memory");
+ _zx_object_set_property(GuardedPagePoolPlatformData.Vmar, ZX_PROP_NAME,
+ kGwpAsanGuardPageName, strlen(kGwpAsanGuardPageName));
+ return reinterpret_cast<void *>(Addr);
+}
+
+void GuardedPoolAllocator::unreserveGuardedPool() {
+ const zx_handle_t Vmar = GuardedPagePoolPlatformData.Vmar;
+ assert(Vmar != ZX_HANDLE_INVALID && Vmar != _zx_vmar_root_self());
+ Check(_zx_vmar_destroy(Vmar) == ZX_OK, "Failed to destroy a vmar");
+ Check(_zx_handle_close(Vmar) == ZX_OK, "Failed to close a vmar");
+ GuardedPagePoolPlatformData.Vmar = ZX_HANDLE_INVALID;
+}
+
+void GuardedPoolAllocator::allocateInGuardedPool(void *Ptr, size_t Size) const {
+ assert((reinterpret_cast<uintptr_t>(Ptr) % State.PageSize) == 0);
+ assert((Size % State.PageSize) == 0);
+ zx_handle_t Vmo;
+ zx_status_t Status = _zx_vmo_create(Size, 0, &Vmo);
+ Check(Status == ZX_OK, "Failed to create vmo");
+ _zx_object_set_property(Vmo, ZX_PROP_NAME, kGwpAsanAliveSlotName,
+ strlen(kGwpAsanAliveSlotName));
+ const zx_handle_t Vmar = GuardedPagePoolPlatformData.Vmar;
+ assert(Vmar != ZX_HANDLE_INVALID && Vmar != _zx_vmar_root_self());
+ const size_t Offset =
+ reinterpret_cast<uintptr_t>(Ptr) - State.GuardedPagePool;
+ zx_vaddr_t P;
+ Status = _zx_vmar_map(Vmar,
+ ZX_VM_PERM_READ | ZX_VM_PERM_WRITE |
+ ZX_VM_ALLOW_FAULTS | ZX_VM_SPECIFIC,
+ Offset, Vmo, 0, Size, &P);
+ Check(Status == ZX_OK, "Vmo mapping failed");
+ _zx_handle_close(Vmo);
+}
+
+void GuardedPoolAllocator::deallocateInGuardedPool(void *Ptr,
+ size_t Size) const {
+ assert((reinterpret_cast<uintptr_t>(Ptr) % State.PageSize) == 0);
+ assert((Size % State.PageSize) == 0);
+ const zx_handle_t Vmar = GuardedPagePoolPlatformData.Vmar;
+ assert(Vmar != ZX_HANDLE_INVALID && Vmar != _zx_vmar_root_self());
+ const zx_status_t Status =
+ _zx_vmar_unmap(Vmar, reinterpret_cast<zx_vaddr_t>(Ptr), Size);
+ Check(Status == ZX_OK, "Vmar unmapping failed");
+}
+
+size_t GuardedPoolAllocator::getPlatformPageSize() { return ZX_PAGE_SIZE; }
+
+void GuardedPoolAllocator::installAtFork() {}
+} // namespace gwp_asan
diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.h b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.h
new file mode 100644
index 000000000000..fbd7d3aa67af
--- /dev/null
+++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_fuchsia.h
@@ -0,0 +1,22 @@
+//===-- guarded_pool_allocator_fuchsia.h ------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__Fuchsia__)
+#ifndef GWP_ASAN_GUARDED_POOL_ALLOCATOR_FUCHSIA_H_
+#define GWP_ASAN_GUARDED_POOL_ALLOCATOR_FUCHSIA_H_
+
+#include <zircon/types.h>
+
+namespace gwp_asan {
+struct PlatformSpecificMapData {
+ zx_handle_t Vmar;
+};
+} // namespace gwp_asan
+
+#endif // GWP_ASAN_GUARDED_POOL_ALLOCATOR_FUCHSIA_H_
+#endif // defined(__Fuchsia__)
diff --git a/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.h b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.h
new file mode 100644
index 000000000000..7f4ba0d8ccd1
--- /dev/null
+++ b/compiler-rt/lib/gwp_asan/platform_specific/guarded_pool_allocator_posix.h
@@ -0,0 +1,18 @@
+//===-- guarded_pool_allocator_posix.h --------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__unix__)
+#ifndef GWP_ASAN_GUARDED_POOL_ALLOCATOR_POSIX_H_
+#define GWP_ASAN_GUARDED_POOL_ALLOCATOR_POSIX_H_
+
+namespace gwp_asan {
+struct PlatformSpecificMapData {};
+} // namespace gwp_asan
+
+#endif // GWP_ASAN_GUARDED_POOL_ALLOCATOR_POSIX_H_
+#endif // defined(__unix__)
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 28b37e7f1d87..3e2055db3dc5 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
@@ -39,15 +39,17 @@ struct ThreadLocalPackedVariables {
};
static_assert(sizeof(ThreadLocalPackedVariables) == sizeof(uint64_t),
"thread local data does not fit in a uint64_t");
+} // namespace gwp_asan
#ifdef GWP_ASAN_PLATFORM_TLS_HEADER
#include GWP_ASAN_PLATFORM_TLS_HEADER
#else
+namespace gwp_asan {
inline ThreadLocalPackedVariables *getThreadLocals() {
alignas(8) static GWP_ASAN_TLS_INITIAL_EXEC ThreadLocalPackedVariables Locals;
return &Locals;
}
-#endif
} // namespace gwp_asan
+#endif // GWP_ASAN_PLATFORM_TLS_HEADER
#endif // GWP_ASAN_GUARDED_POOL_ALLOCATOR_TLS_H_
diff --git a/compiler-rt/lib/gwp_asan/platform_specific/utilities_fuchsia.cpp b/compiler-rt/lib/gwp_asan/platform_specific/utilities_fuchsia.cpp
new file mode 100644
index 000000000000..bc9d3a4462a2
--- /dev/null
+++ b/compiler-rt/lib/gwp_asan/platform_specific/utilities_fuchsia.cpp
@@ -0,0 +1,19 @@
+//===-- utilities_fuchsia.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/utilities.h"
+
+#include <string.h>
+#include <zircon/sanitizer.h>
+
+namespace gwp_asan {
+void die(const char *Message) {
+ __sanitizer_log_write(Message, strlen(Message));
+ __builtin_trap();
+}
+} // namespace gwp_asan
More information about the llvm-commits
mailing list