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.
chromium/SOURCES/chromium-115-revert-ifunc.p...

290 lines
12 KiB

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(),