f3737bbb12
As sandboxed pointers are now default-enabled when the sandbox is enabled, it is no longer possible to deactivate the sandbox at runtime. This CL therefore removes all the logic that was required to support a sandbox that could be disabled at runtime, moves the initialization of the sandbox into V8::Initialize, and deprecates V8::InitializeSandbox. This change also makes the sandbox initialization deterministic if FLAG_random_seed is supplied. Bug: v8:10391 Change-Id: Ibd49f7c251b7c58c642f18a551ecc2c391740970 Cq-Include-Trybots: luci.v8.try:v8_linux64_heap_sandbox_dbg_ng,v8_linux_arm64_sim_heap_sandbox_dbg_ng Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3762583 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Commit-Queue: Samuel Groß <saelo@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/main@{#81746}
136 lines
3.7 KiB
C++
136 lines
3.7 KiB
C++
// Copyright 2021 the V8 project 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 "src/sandbox/sandbox.h"
|
|
|
|
#include <vector>
|
|
|
|
#include "src/base/virtual-address-space.h"
|
|
#include "test/unittests/test-utils.h"
|
|
|
|
#ifdef V8_ENABLE_SANDBOX
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
TEST(SandboxTest, Initialization) {
|
|
base::VirtualAddressSpace vas;
|
|
|
|
Sandbox sandbox;
|
|
|
|
EXPECT_FALSE(sandbox.is_initialized());
|
|
EXPECT_FALSE(sandbox.is_partially_reserved());
|
|
EXPECT_EQ(sandbox.size(), 0UL);
|
|
|
|
sandbox.Initialize(&vas);
|
|
|
|
EXPECT_TRUE(sandbox.is_initialized());
|
|
EXPECT_NE(sandbox.base(), 0UL);
|
|
EXPECT_GT(sandbox.size(), 0UL);
|
|
|
|
sandbox.TearDown();
|
|
|
|
EXPECT_FALSE(sandbox.is_initialized());
|
|
}
|
|
|
|
TEST(SandboxTest, InitializationWithSize) {
|
|
base::VirtualAddressSpace vas;
|
|
// This test only works if virtual memory subspaces can be allocated.
|
|
if (!vas.CanAllocateSubspaces()) return;
|
|
|
|
Sandbox sandbox;
|
|
size_t size = 8ULL * GB;
|
|
const bool use_guard_regions = false;
|
|
sandbox.Initialize(&vas, size, use_guard_regions);
|
|
|
|
EXPECT_TRUE(sandbox.is_initialized());
|
|
EXPECT_FALSE(sandbox.is_partially_reserved());
|
|
EXPECT_EQ(sandbox.size(), size);
|
|
|
|
sandbox.TearDown();
|
|
}
|
|
|
|
TEST(SandboxTest, PartiallyReservedSandboxInitialization) {
|
|
base::VirtualAddressSpace vas;
|
|
Sandbox sandbox;
|
|
// Total size of the sandbox.
|
|
size_t size = kSandboxSize;
|
|
// Size of the virtual memory that is actually reserved at the start of the
|
|
// sandbox.
|
|
size_t reserved_size = 2 * vas.allocation_granularity();
|
|
EXPECT_TRUE(
|
|
sandbox.InitializeAsPartiallyReservedSandbox(&vas, size, reserved_size));
|
|
|
|
EXPECT_TRUE(sandbox.is_initialized());
|
|
EXPECT_TRUE(sandbox.is_partially_reserved());
|
|
EXPECT_NE(sandbox.base(), 0UL);
|
|
EXPECT_EQ(sandbox.size(), size);
|
|
|
|
sandbox.TearDown();
|
|
|
|
EXPECT_FALSE(sandbox.is_initialized());
|
|
}
|
|
|
|
TEST(SandboxTest, Contains) {
|
|
base::VirtualAddressSpace vas;
|
|
Sandbox sandbox;
|
|
sandbox.Initialize(&vas);
|
|
|
|
Address base = sandbox.base();
|
|
size_t size = sandbox.size();
|
|
base::RandomNumberGenerator rng(::testing::FLAGS_gtest_random_seed);
|
|
|
|
EXPECT_TRUE(sandbox.Contains(base));
|
|
EXPECT_TRUE(sandbox.Contains(base + size - 1));
|
|
for (int i = 0; i < 10; i++) {
|
|
size_t offset = rng.NextInt64() % size;
|
|
EXPECT_TRUE(sandbox.Contains(base + offset));
|
|
}
|
|
|
|
EXPECT_FALSE(sandbox.Contains(base - 1));
|
|
EXPECT_FALSE(sandbox.Contains(base + size));
|
|
for (int i = 0; i < 10; i++) {
|
|
Address addr = rng.NextInt64();
|
|
if (addr < base || addr >= base + size) {
|
|
EXPECT_FALSE(sandbox.Contains(addr));
|
|
}
|
|
}
|
|
|
|
sandbox.TearDown();
|
|
}
|
|
|
|
TEST(SandboxTest, PageAllocation) {
|
|
base::VirtualAddressSpace root_vas;
|
|
Sandbox sandbox;
|
|
sandbox.Initialize(&root_vas);
|
|
|
|
const size_t kAllocatinSizesInPages[] = {1, 1, 2, 3, 5, 8, 13, 21, 34};
|
|
constexpr int kNumAllocations = arraysize(kAllocatinSizesInPages);
|
|
|
|
VirtualAddressSpace* vas = sandbox.address_space();
|
|
size_t allocation_granularity = vas->allocation_granularity();
|
|
std::vector<Address> allocations;
|
|
for (int i = 0; i < kNumAllocations; i++) {
|
|
size_t length = allocation_granularity * kAllocatinSizesInPages[i];
|
|
size_t alignment = allocation_granularity;
|
|
Address ptr = vas->AllocatePages(VirtualAddressSpace::kNoHint, length,
|
|
alignment, PagePermissions::kNoAccess);
|
|
EXPECT_NE(ptr, kNullAddress);
|
|
EXPECT_TRUE(sandbox.Contains(ptr));
|
|
allocations.push_back(ptr);
|
|
}
|
|
|
|
for (int i = 0; i < kNumAllocations; i++) {
|
|
size_t length = allocation_granularity * kAllocatinSizesInPages[i];
|
|
vas->FreePages(allocations[i], length);
|
|
}
|
|
|
|
sandbox.TearDown();
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|
|
|
|
#endif // V8_ENABLE_SANDBOX
|