#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "gin/v8_platform_page_allocator.h"
#include "base/cpu.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "v8/include/v8-platform.h"
#if defined(ARCH_CPU_ARM64) && (OS_LINUX || OS_ANDROID)
#include "partition_alloc/arm_bti_test_functions.h"
#include "partition_alloc/page_allocator_constants.h"
#if BUILDFLAG(IS_POSIX)
#include <signal.h>
#include "testing/gtest/include/gtest/gtest-death-test.h"
#endif
#endif
namespace gin {
TEST(V8PlatformPageAllocatorTest, VerifyGetPageConfig) { … }
#if defined(ARCH_CPU_ARM64) && (OS_LINUX || OS_ANDROID)
#ifdef GTEST_HAS_DEATH_TEST
using BTITestFunction = int64_t (*)(int64_t);
using V8PlatformPageAllocatorBTIDeathTest =
::testing::TestWithParam<v8::PageAllocator::Permission>;
TEST_P(V8PlatformPageAllocatorBTIDeathTest, VerifyExecutablePagesAreProtected) {
const v8::PageAllocator::Permission permission_to_test = GetParam();
auto page_allocator = gin::PageAllocator();
auto const memory_size =
partition_alloc::internal::PageAllocationGranularity();
auto const memory_alignment =
partition_alloc::internal::PageAllocationGranularity();
char* const buffer = reinterpret_cast<char*>(page_allocator.AllocatePages(
nullptr, memory_size, memory_alignment,
v8::PageAllocator::Permission::kReadWriteExecute));
ptrdiff_t const function_range =
reinterpret_cast<char*>(arm_bti_test_function_end) -
reinterpret_cast<char*>(arm_bti_test_function);
ptrdiff_t const invalid_offset =
reinterpret_cast<char*>(arm_bti_test_function_invalid_offset) -
reinterpret_cast<char*>(arm_bti_test_function);
EXPECT_EQ(0u, ((uint64_t)buffer) % 4);
EXPECT_EQ(0u, ((uint64_t)function_range) % 4);
EXPECT_EQ(0u, ((uint64_t)invalid_offset) % 4);
memcpy(buffer, reinterpret_cast<void*>(arm_bti_test_function),
function_range);
page_allocator.SetPermissions(buffer, memory_size, permission_to_test);
BTITestFunction const bti_enabled_fn =
reinterpret_cast<BTITestFunction>(buffer);
EXPECT_EQ(bti_enabled_fn(15), 18);
BTITestFunction const bti_invalid_fn =
reinterpret_cast<BTITestFunction>(buffer + invalid_offset);
if (base::CPU::GetInstanceNoAllocation().has_bti()) {
#if BUILDFLAG(IS_POSIX)
EXPECT_EXIT({ bti_invalid_fn(15); }, testing::KilledBySignal(SIGILL),
"");
#endif
} else {
EXPECT_EQ(bti_invalid_fn(15), 17);
}
page_allocator.FreePages(buffer, memory_size);
}
INSTANTIATE_TEST_SUITE_P(
,
V8PlatformPageAllocatorBTIDeathTest,
testing::Values(v8::PageAllocator::Permission::kReadExecute,
v8::PageAllocator::Permission::kReadWriteExecute));
#endif
#endif
}