blob: 59a701d7db2721830ebe57b392c6c8e121efda95 [file] [log] [blame]
// Copyright (c) 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/allocator/partition_allocator/tagging.h"
#include <cstdint>
#include "base/allocator/partition_allocator/page_allocator.h"
#include "base/allocator/partition_allocator/partition_alloc_base/cpu.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace partition_alloc::internal {
// Check whether we can call the tagging intrinsics safely on all architectures.
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlySafe) {
uintptr_t buffer = AllocPages(
PageAllocationGranularity(), PageAllocationGranularity(),
PageAccessibilityConfiguration::kReadWriteTagged, PageTag::kChromium);
EXPECT_TRUE(buffer);
uintptr_t bufferp =
TagMemoryRangeRandomly(buffer, 4 * kMemTagGranuleSize, 0u);
EXPECT_TRUE(bufferp);
int* buffer0 = reinterpret_cast<int*>(bufferp);
*buffer0 = 42;
EXPECT_EQ(42, *buffer0);
FreePages(buffer, PageAllocationGranularity());
}
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementSafe) {
base::CPU cpu;
uintptr_t buffer = AllocPages(
PageAllocationGranularity(), PageAllocationGranularity(),
PageAccessibilityConfiguration::kReadWriteTagged, PageTag::kChromium);
EXPECT_TRUE(buffer);
uintptr_t bufferp = TagMemoryRangeIncrement(buffer, 4 * kMemTagGranuleSize);
EXPECT_TRUE(bufferp);
int* buffer0 = reinterpret_cast<int*>(bufferp);
*buffer0 = 42;
EXPECT_EQ(42, *buffer0);
if (cpu.has_mte()) {
EXPECT_NE(bufferp, buffer);
}
FreePages(buffer, PageAllocationGranularity());
}
#if defined(ARCH_CPU_64_BITS)
// Size / alignment constraints are only enforced on 64-bit architectures.
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeBadSz) {
base::CPU cpu;
uintptr_t buffer = AllocPages(
PageAllocationGranularity(), PageAllocationGranularity(),
PageAccessibilityConfiguration::kReadWriteTagged, PageTag::kChromium);
EXPECT_TRUE(buffer);
uintptr_t bufferp =
TagMemoryRangeRandomly(buffer, 4 * kMemTagGranuleSize - 1, 0u);
if (cpu.has_mte()) {
EXPECT_EQ(bufferp, 0u);
}
FreePages(buffer, PageAllocationGranularity());
}
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlyNoSz) {
base::CPU cpu;
uintptr_t buffer = AllocPages(
PageAllocationGranularity(), PageAllocationGranularity(),
PageAccessibilityConfiguration::kReadWriteTagged, PageTag::kChromium);
EXPECT_TRUE(buffer);
uintptr_t bufferp = TagMemoryRangeRandomly(buffer, 0, 0u);
if (cpu.has_mte()) {
EXPECT_EQ(bufferp, 0u);
}
FreePages(buffer, PageAllocationGranularity());
}
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlyBadAlign) {
base::CPU cpu;
uintptr_t buffer = AllocPages(
PageAllocationGranularity(), PageAllocationGranularity(),
PageAccessibilityConfiguration::kReadWriteTagged, PageTag::kChromium);
EXPECT_TRUE(buffer);
uintptr_t bufferp =
TagMemoryRangeRandomly(buffer - 1, 4 * kMemTagGranuleSize, 0u);
if (cpu.has_mte()) {
EXPECT_EQ(bufferp, 0u);
}
FreePages(buffer, PageAllocationGranularity());
}
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementBadSz) {
base::CPU cpu;
uintptr_t buffer = AllocPages(
PageAllocationGranularity(), PageAllocationGranularity(),
PageAccessibilityConfiguration::kReadWriteTagged, PageTag::kChromium);
EXPECT_TRUE(buffer);
uintptr_t bufferp =
TagMemoryRangeIncrement(buffer, 4 * kMemTagGranuleSize - 1);
if (cpu.has_mte()) {
EXPECT_EQ(bufferp, 0u);
}
FreePages(buffer, PageAllocationGranularity());
}
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementNoSz) {
base::CPU cpu;
uintptr_t buffer = AllocPages(
PageAllocationGranularity(), PageAllocationGranularity(),
PageAccessibilityConfiguration::kReadWriteTagged, PageTag::kChromium);
EXPECT_TRUE(buffer);
uintptr_t bufferp = TagMemoryRangeIncrement(buffer, 0);
if (cpu.has_mte()) {
EXPECT_EQ(bufferp, 0u);
}
FreePages(buffer, PageAllocationGranularity());
}
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementBadAlign) {
base::CPU cpu;
uintptr_t buffer = AllocPages(
PageAllocationGranularity(), PageAllocationGranularity(),
PageAccessibilityConfiguration::kReadWriteTagged, PageTag::kChromium);
EXPECT_TRUE(buffer);
uintptr_t bufferp =
TagMemoryRangeIncrement(buffer - 1, 4 * kMemTagGranuleSize);
if (cpu.has_mte()) {
EXPECT_EQ(bufferp, 0u);
}
FreePages(buffer, PageAllocationGranularity());
}
#endif // defined(ARCH_CPU_64_BITS)
} // namespace partition_alloc::internal