v8/test/unittests/sandbox/sandbox-unittest.cc
Samuel Groß f3737bbb12 [sandbox] Initialize sandbox during V8::Initialize
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}
2022-07-15 09:29:32 +00:00

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