chromium/base/allocator/partition_allocator/src/partition_alloc/tagging_unittest.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "partition_alloc/tagging.h"

#include <cstdint>

#include "partition_alloc/build_config.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/page_allocator.h"
#include "partition_alloc/partition_alloc_base/cpu.h"
#include "partition_alloc/partition_alloc_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) {}

TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementSafe) {}

#if PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)
// Size / alignment constraints are only enforced on 64-bit architectures.
TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeBadSz) {}

TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlyNoSz) {}

TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeRandomlyBadAlign) {}

TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementBadSz) {}

TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementNoSz) {}

TEST(PartitionAllocMemoryTaggingTest, TagMemoryRangeIncrementBadAlign) {}
#endif  // PA_BUILDFLAG(PA_ARCH_CPU_64_BITS)

#if PA_BUILDFLAG(HAS_MEMORY_TAGGING)
#if PA_BUILDFLAG(IS_ANDROID)
TEST(PartitionAllocMemoryTaggingTest,
     ChangeMemoryTaggingModeForAllThreadsPerProcess) {
  base::CPU cpu;
  // If the underlying platform does not support MTE, skip this test to avoid
  // hiding failures.
  if (!cpu.has_mte()) {
    GTEST_SKIP();
  }

  // The mode should be set to synchronous on startup by AndroidManifest.xml
  // for base_unittests.
  EXPECT_EQ(GetMemoryTaggingModeForCurrentThread(),
            TagViolationReportingMode::kSynchronous);

  // Skip changing to kDisabled, because scudo does not support enabling MTE
  // once it is disabled.
  bool success = ChangeMemoryTaggingModeForAllThreadsPerProcess(
      TagViolationReportingMode::kAsynchronous);
  EXPECT_TRUE(success);
  EXPECT_EQ(GetMemoryTaggingModeForCurrentThread(),
            TagViolationReportingMode::kAsynchronous);
  success = ChangeMemoryTaggingModeForAllThreadsPerProcess(
      TagViolationReportingMode::kSynchronous);
  EXPECT_TRUE(success);
  // End with mode changed back to synchronous.
  EXPECT_EQ(GetMemoryTaggingModeForCurrentThread(),
            TagViolationReportingMode::kSynchronous);
}
#endif  // PA_BUILDFLAG(IS_ANDROID)

TEST(PartitionAllocMemoryTaggingTest, ChangeMemoryTaggingModeForCurrentThread) {
  base::CPU cpu;
  // If the underlying platform does not support MTE, skip this test to avoid
  // hiding failures.
  if (!cpu.has_mte()) {
    GTEST_SKIP();
  }

  TagViolationReportingMode original_mode =
      GetMemoryTaggingModeForCurrentThread();

  ChangeMemoryTaggingModeForCurrentThread(TagViolationReportingMode::kDisabled);
  EXPECT_EQ(GetMemoryTaggingModeForCurrentThread(),
            TagViolationReportingMode::kDisabled);
  ChangeMemoryTaggingModeForCurrentThread(
      TagViolationReportingMode::kSynchronous);
  EXPECT_EQ(GetMemoryTaggingModeForCurrentThread(),
            TagViolationReportingMode::kSynchronous);
  ChangeMemoryTaggingModeForCurrentThread(
      TagViolationReportingMode::kAsynchronous);
  EXPECT_EQ(GetMemoryTaggingModeForCurrentThread(),
            TagViolationReportingMode::kAsynchronous);
  ChangeMemoryTaggingModeForCurrentThread(
      TagViolationReportingMode::kSynchronous);
  EXPECT_EQ(GetMemoryTaggingModeForCurrentThread(),
            TagViolationReportingMode::kSynchronous);
  ChangeMemoryTaggingModeForCurrentThread(TagViolationReportingMode::kDisabled);
  EXPECT_EQ(GetMemoryTaggingModeForCurrentThread(),
            TagViolationReportingMode::kDisabled);
  ChangeMemoryTaggingModeForCurrentThread(
      TagViolationReportingMode::kAsynchronous);
  EXPECT_EQ(GetMemoryTaggingModeForCurrentThread(),
            TagViolationReportingMode::kAsynchronous);

  // Restore mode to original.
  ChangeMemoryTaggingModeForCurrentThread(original_mode);
}
#endif  // PA_BUILDFLAG(HAS_MEMORY_TAGGING)

}  // namespace partition_alloc::internal