You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
12 KiB
290 lines
12 KiB
1 year ago
|
commit b2c4ff8d5d8cdbf2487363a5b8d68b6485706069
|
||
|
Author: Richard Townsend <Richard.Townsend@arm.com>
|
||
|
Date: Thu May 18 22:51:36 2023 +0000
|
||
|
|
||
|
Reland "Reland "mte: refactor the tagging functions to use ifuncs""
|
||
|
|
||
|
This is a reland of commit 2321ea383c006149c3b496a515f54fb3aebdc34c
|
||
|
and a revert of commit adfb1c2c6ceb3daf210cef1e5688541ebc561e20. It
|
||
|
was reverted because of a problem with android-arm64 orderfile
|
||
|
generation, which is now resolved.
|
||
|
|
||
|
Original change's description:
|
||
|
> Reland "mte: refactor the tagging functions to use ifuncs"
|
||
|
>
|
||
|
> This was reverted due to a toolchain problem affecting ThinLTO,
|
||
|
> resolved in [1]
|
||
|
>
|
||
|
> [1] https://reviews.llvm.org/D144982
|
||
|
>
|
||
|
> This reverts commit 6c22e41fc3ffd305359f17b2423c37c2c976acf3.
|
||
|
>
|
||
|
> Bug: 1137393
|
||
|
> Change-Id: I991e12618f98cdf8b89ec83cad06e30ad60d332e
|
||
|
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4473870
|
||
|
> Reviewed-by: Keishi Hattori <keishi@chromium.org>
|
||
|
> Commit-Queue: Richard Townsend <richard.townsend@arm.com>
|
||
|
> Cr-Commit-Position: refs/heads/main@{#1135862}
|
||
|
|
||
|
Bug: 1137393, 1440531
|
||
|
Change-Id: I4cd1911a36cf55ee1c06e6ffda971866c93fa741
|
||
|
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4517702
|
||
|
Commit-Queue: Richard Townsend <richard.townsend@arm.com>
|
||
|
Reviewed-by: Keishi Hattori <keishi@chromium.org>
|
||
|
Cr-Commit-Position: refs/heads/main@{#1146244}
|
||
|
|
||
|
diff --git a/base/allocator/partition_allocator/partition_root.cc b/base/allocator/partition_allocator/partition_root.cc
|
||
|
index 486594e81f823..8ab37f6dec750 100644
|
||
|
--- a/base/allocator/partition_allocator/partition_root.cc
|
||
|
+++ b/base/allocator/partition_allocator/partition_root.cc
|
||
|
@@ -869,10 +869,6 @@ void PartitionRoot<thread_safe>::Init(PartitionOptions opts) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- // Swaps out the active no-op tagging intrinsics with MTE-capable ones, if
|
||
|
- // running on the right hardware.
|
||
|
- ::partition_alloc::internal::InitializeMTESupportIfNeeded();
|
||
|
-
|
||
|
#if BUILDFLAG(HAS_64_BIT_POINTERS)
|
||
|
// Reserve address space for partition alloc.
|
||
|
internal::PartitionAddressSpace::Init();
|
||
|
diff --git a/base/allocator/partition_allocator/tagging.cc b/base/allocator/partition_allocator/tagging.cc
|
||
|
index a8a74155de4e1..ea7ac2af82c88 100644
|
||
|
--- a/base/allocator/partition_allocator/tagging.cc
|
||
|
+++ b/base/allocator/partition_allocator/tagging.cc
|
||
|
@@ -12,7 +12,9 @@
|
||
|
|
||
|
#if PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
#include <arm_acle.h>
|
||
|
+#include <asm/hwcap.h>
|
||
|
#include <sys/auxv.h>
|
||
|
+#include <sys/ifunc.h>
|
||
|
#include <sys/prctl.h>
|
||
|
#define PR_SET_TAGGED_ADDR_CTRL 55
|
||
|
#define PR_GET_TAGGED_ADDR_CTRL 56
|
||
|
@@ -119,12 +121,6 @@ namespace {
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
-#if PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
-static bool HasCPUMemoryTaggingExtension() {
|
||
|
- return base::CPU::GetInstanceNoAllocation().has_mte();
|
||
|
-}
|
||
|
-#endif // PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
-
|
||
|
#if PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
void* TagRegionRandomlyForMTE(void* ptr, size_t sz, uint64_t mask) {
|
||
|
// Randomly tag a region (MTE-enabled systems only). The first 16-byte
|
||
|
@@ -166,7 +162,6 @@ void* RemaskVoidPtrForMTE(void* ptr) {
|
||
|
}
|
||
|
return nullptr;
|
||
|
}
|
||
|
-#endif
|
||
|
|
||
|
void* TagRegionIncrementNoOp(void* ptr, size_t sz) {
|
||
|
// Region parameters are checked even on non-MTE systems to check the
|
||
|
@@ -183,24 +178,49 @@ void* TagRegionRandomlyNoOp(void* ptr, size_t sz, uint64_t mask) {
|
||
|
void* RemaskVoidPtrNoOp(void* ptr) {
|
||
|
return ptr;
|
||
|
}
|
||
|
+#endif
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
-void InitializeMTESupportIfNeeded() {
|
||
|
#if PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
- if (HasCPUMemoryTaggingExtension()) {
|
||
|
- global_remask_void_ptr_fn = RemaskVoidPtrForMTE;
|
||
|
- global_tag_memory_range_increment_fn = TagRegionIncrementForMTE;
|
||
|
- global_tag_memory_range_randomly_fn = TagRegionRandomlyForMTE;
|
||
|
+using RemaskPtrInternalFn = void*(void* ptr);
|
||
|
+using TagMemoryRangeIncrementInternalFn = void*(void* ptr, size_t size);
|
||
|
+
|
||
|
+using TagMemoryRangeRandomlyInternalFn = void*(void* ptr,
|
||
|
+ size_t size,
|
||
|
+ uint64_t mask);
|
||
|
+
|
||
|
+extern "C" TagMemoryRangeIncrementInternalFn(
|
||
|
+ *ResolveTagMemoryRangeIncrement(uint64_t hwcap, struct __ifunc_arg_t* hw)) {
|
||
|
+ if ((hwcap & _IFUNC_ARG_HWCAP) && (hw->_hwcap2 & HWCAP2_MTE)) {
|
||
|
+ return TagRegionIncrementForMTE;
|
||
|
}
|
||
|
-#endif
|
||
|
+ return TagRegionIncrementNoOp;
|
||
|
+}
|
||
|
+
|
||
|
+extern "C" TagMemoryRangeRandomlyInternalFn(
|
||
|
+ *ResolveTagMemoryRandomly(uint64_t hwcap, struct __ifunc_arg_t* hw)) {
|
||
|
+ if ((hwcap & _IFUNC_ARG_HWCAP) && (hw->_hwcap2 & HWCAP2_MTE)) {
|
||
|
+ return TagRegionRandomlyForMTE;
|
||
|
+ }
|
||
|
+ return TagRegionRandomlyNoOp;
|
||
|
+}
|
||
|
+
|
||
|
+extern "C" RemaskPtrInternalFn(
|
||
|
+ *ResolveRemaskPointer(uint64_t hwcap, struct __ifunc_arg_t* hw)) {
|
||
|
+ if ((hwcap & _IFUNC_ARG_HWCAP) && (hw->_hwcap2 & HWCAP2_MTE)) {
|
||
|
+ return RemaskVoidPtrForMTE;
|
||
|
+ }
|
||
|
+ return RemaskVoidPtrNoOp;
|
||
|
}
|
||
|
|
||
|
-RemaskPtrInternalFn* global_remask_void_ptr_fn = RemaskVoidPtrNoOp;
|
||
|
-TagMemoryRangeIncrementInternalFn* global_tag_memory_range_increment_fn =
|
||
|
- TagRegionIncrementNoOp;
|
||
|
-TagMemoryRangeRandomlyInternalFn* global_tag_memory_range_randomly_fn =
|
||
|
- TagRegionRandomlyNoOp;
|
||
|
+void* TagMemoryRangeIncrementInternal(void* ptr, size_t size)
|
||
|
+ __attribute__((ifunc("ResolveTagMemoryRangeIncrement")));
|
||
|
+void* TagMemoryRangeRandomlyInternal(void* ptr, size_t size, uint64_t mask)
|
||
|
+ __attribute__((ifunc("ResolveTagMemoryRandomly")));
|
||
|
+void* RemaskPointerInternal(void* ptr)
|
||
|
+ __attribute__((ifunc("ResolveRemaskPointer")));
|
||
|
+#endif // PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
|
||
|
TagViolationReportingMode GetMemoryTaggingModeForCurrentThread() {
|
||
|
#if PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
diff --git a/base/allocator/partition_allocator/tagging.h b/base/allocator/partition_allocator/tagging.h
|
||
|
index af914452b1162..d49e062ce6319 100644
|
||
|
--- a/base/allocator/partition_allocator/tagging.h
|
||
|
+++ b/base/allocator/partition_allocator/tagging.h
|
||
|
@@ -55,32 +55,16 @@ void ChangeMemoryTaggingModeForAllThreadsPerProcess(TagViolationReportingMode);
|
||
|
PA_COMPONENT_EXPORT(PARTITION_ALLOC)
|
||
|
TagViolationReportingMode GetMemoryTaggingModeForCurrentThread();
|
||
|
|
||
|
-// Called by the partition allocator after initial startup, this detects MTE
|
||
|
-// support in the current CPU and replaces the active tagging intrinsics with
|
||
|
-// MTE versions if needed.
|
||
|
-PA_COMPONENT_EXPORT(PARTITION_ALLOC) void InitializeMTESupportIfNeeded();
|
||
|
-
|
||
|
-// These global function pointers hold the implementations of the tagging
|
||
|
-// intrinsics (TagMemoryRangeRandomly, TagMemoryRangeIncrement, RemaskPtr).
|
||
|
-// They are designed to be callable without taking a branch. They are initially
|
||
|
-// set to no-op functions in tagging.cc, but can be replaced with MTE-capable
|
||
|
-// ones through InitializeMTEIfNeeded(). This is conceptually similar to an
|
||
|
-// IFUNC, even though less secure. These function pointers were introduced to
|
||
|
-// support older Android releases. With the removal of support for Android M,
|
||
|
-// it became possible to use IFUNC instead.
|
||
|
-// TODO(bartekn): void* -> uintptr_t
|
||
|
-using RemaskPtrInternalFn = void*(void* ptr);
|
||
|
-using TagMemoryRangeIncrementInternalFn = void*(void* ptr, size_t size);
|
||
|
-
|
||
|
-using TagMemoryRangeRandomlyInternalFn = void*(void* ptr,
|
||
|
- size_t size,
|
||
|
- uint64_t mask);
|
||
|
-extern PA_COMPONENT_EXPORT(PARTITION_ALLOC)
|
||
|
- TagMemoryRangeRandomlyInternalFn* global_tag_memory_range_randomly_fn;
|
||
|
-extern PA_COMPONENT_EXPORT(PARTITION_ALLOC)
|
||
|
- TagMemoryRangeIncrementInternalFn* global_tag_memory_range_increment_fn;
|
||
|
-extern PA_COMPONENT_EXPORT(PARTITION_ALLOC)
|
||
|
- RemaskPtrInternalFn* global_remask_void_ptr_fn;
|
||
|
+// These forward-defined functions do not really exist in tagging.cc, they're resolved
|
||
|
+// by the dynamic linker to MTE-capable versions on the right hardware.
|
||
|
+#if PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
+PA_COMPONENT_EXPORT(PARTITION_ALLOC)
|
||
|
+void* TagMemoryRangeIncrementInternal(void* ptr, size_t size);
|
||
|
+PA_COMPONENT_EXPORT(PARTITION_ALLOC)
|
||
|
+void* TagMemoryRangeRandomlyInternal(void* ptr, size_t size, uint64_t mask);
|
||
|
+PA_COMPONENT_EXPORT(PARTITION_ALLOC)
|
||
|
+void* RemaskPointerInternal(void* ptr);
|
||
|
+#endif
|
||
|
|
||
|
// Increments the tag of the memory range ptr. Useful for provable revocations
|
||
|
// (e.g. free). Returns the pointer with the new tag. Ensures that the entire
|
||
|
@@ -90,7 +74,7 @@ extern PA_COMPONENT_EXPORT(PARTITION_ALLOC)
|
||
|
template <typename T>
|
||
|
PA_ALWAYS_INLINE T* TagMemoryRangeIncrement(T* ptr, size_t size) {
|
||
|
#if PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
- return reinterpret_cast<T*>(global_tag_memory_range_increment_fn(ptr, size));
|
||
|
+ return reinterpret_cast<T*>(TagMemoryRangeIncrementInternal(ptr, size));
|
||
|
#else
|
||
|
return ptr;
|
||
|
#endif
|
||
|
@@ -108,8 +92,7 @@ PA_ALWAYS_INLINE T* TagMemoryRangeRandomly(T* ptr,
|
||
|
size_t size,
|
||
|
uint64_t mask = 0u) {
|
||
|
#if PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
- return reinterpret_cast<T*>(
|
||
|
- global_tag_memory_range_randomly_fn(ptr, size, mask));
|
||
|
+ return reinterpret_cast<T*>(TagMemoryRangeRandomlyInternal(ptr, size, mask));
|
||
|
#else
|
||
|
return ptr;
|
||
|
#endif
|
||
|
@@ -124,7 +107,7 @@ PA_ALWAYS_INLINE void* TagMemoryRangeRandomly(uintptr_t ptr,
|
||
|
template <typename T>
|
||
|
PA_ALWAYS_INLINE T* TagPtr(T* ptr) {
|
||
|
#if PA_CONFIG(HAS_MEMORY_TAGGING)
|
||
|
- return reinterpret_cast<T*>(global_remask_void_ptr_fn(ptr));
|
||
|
+ return reinterpret_cast<T*>(RemaskPointerInternal(ptr));
|
||
|
#else
|
||
|
return ptr;
|
||
|
#endif
|
||
|
diff --git a/base/allocator/partition_allocator/tagging_unittest.cc b/base/allocator/partition_allocator/tagging_unittest.cc
|
||
|
index f3b8532a8f1f4..47f62ac000b43 100644
|
||
|
--- a/base/allocator/partition_allocator/tagging_unittest.cc
|
||
|
+++ b/base/allocator/partition_allocator/tagging_unittest.cc
|
||
|
@@ -16,7 +16,6 @@ namespace partition_alloc::internal {
|
||
|
|
||
|
// Check whether we can call the tagging intrinsics safely on all architectures.
|
||
|
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlySafe) {
|
||
|
- ::partition_alloc::internal::InitializeMTESupportIfNeeded();
|
||
|
uintptr_t buffer =
|
||
|
AllocPages(PageAllocationGranularity(), PageAllocationGranularity(),
|
||
|
PageAccessibilityConfiguration(
|
||
|
@@ -32,7 +31,6 @@ TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlySafe) {
|
||
|
}
|
||
|
|
||
|
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementSafe) {
|
||
|
- ::partition_alloc::internal::InitializeMTESupportIfNeeded();
|
||
|
base::CPU cpu;
|
||
|
uintptr_t buffer =
|
||
|
AllocPages(PageAllocationGranularity(), PageAllocationGranularity(),
|
||
|
@@ -54,7 +52,6 @@ TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementSafe) {
|
||
|
#if defined(ARCH_CPU_64_BITS)
|
||
|
// Size / alignment constraints are only enforced on 64-bit architectures.
|
||
|
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeBadSz) {
|
||
|
- ::partition_alloc::internal::InitializeMTESupportIfNeeded();
|
||
|
base::CPU cpu;
|
||
|
uintptr_t buffer =
|
||
|
AllocPages(PageAllocationGranularity(), PageAllocationGranularity(),
|
||
|
@@ -71,7 +68,6 @@ TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeBadSz) {
|
||
|
}
|
||
|
|
||
|
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlyNoSz) {
|
||
|
- ::partition_alloc::internal::InitializeMTESupportIfNeeded();
|
||
|
base::CPU cpu;
|
||
|
uintptr_t buffer =
|
||
|
AllocPages(PageAllocationGranularity(), PageAllocationGranularity(),
|
||
|
@@ -87,7 +83,6 @@ TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlyNoSz) {
|
||
|
}
|
||
|
|
||
|
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlyBadAlign) {
|
||
|
- ::partition_alloc::internal::InitializeMTESupportIfNeeded();
|
||
|
base::CPU cpu;
|
||
|
uintptr_t buffer =
|
||
|
AllocPages(PageAllocationGranularity(), PageAllocationGranularity(),
|
||
|
@@ -104,7 +99,6 @@ TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlyBadAlign) {
|
||
|
}
|
||
|
|
||
|
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementBadSz) {
|
||
|
- ::partition_alloc::internal::InitializeMTESupportIfNeeded();
|
||
|
base::CPU cpu;
|
||
|
uintptr_t buffer =
|
||
|
AllocPages(PageAllocationGranularity(), PageAllocationGranularity(),
|
||
|
@@ -120,7 +114,6 @@ TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementBadSz) {
|
||
|
}
|
||
|
|
||
|
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementNoSz) {
|
||
|
- ::partition_alloc::internal::InitializeMTESupportIfNeeded();
|
||
|
base::CPU cpu;
|
||
|
uintptr_t buffer =
|
||
|
AllocPages(PageAllocationGranularity(), PageAllocationGranularity(),
|
||
|
@@ -136,7 +129,6 @@ TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementNoSz) {
|
||
|
}
|
||
|
|
||
|
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementBadAlign) {
|
||
|
- ::partition_alloc::internal::InitializeMTESupportIfNeeded();
|
||
|
base::CPU cpu;
|
||
|
uintptr_t buffer =
|
||
|
AllocPages(PageAllocationGranularity(), PageAllocationGranularity(),
|