parent
1f8fd846d2
commit
1579239c98
@ -0,0 +1,289 @@
|
||||
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(),
|
Loading…
Reference in new issue