blob: 3fe0b86d403d9931e84a94faee28bc61c4237601 [file] [log] [blame]
// Copyright 2022 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.
#ifndef V8_SANDBOX_TESTING_H_
#define V8_SANDBOX_TESTING_H_
#include "src/common/globals.h"
#include "src/objects/instance-type.h"
namespace v8 {
namespace internal {
#ifdef V8_ENABLE_SANDBOX
// Infrastructure for testing the security properties of the sandbox.
class SandboxTesting : public AllStatic {
public:
// The different sandbox testing modes.
enum class Mode {
// Sandbox testing is not active.
kDisabled,
// Mode for demonstrating and validating sandbox bypasses.
// In this mode, a read-only page is allocated during startup at a random
// address outside of the sandbox. Only access violations on this page (the
// "target page") are treated as sandbox bypasses, everything else is
// filtered out by the crash filter.
kForTesting,
// Mode for fuzzing the sandbox.
// In this mode, the sandbox crash filter is installed and filters out all
// crashes that do not represent sandbox violations.
kForFuzzing,
};
// Enable sandbox testing mode.
//
// This will initialize the sandbox crash filter. The crash filter is a
// signal handler for a number of fatal signals (e.g. SIGSEGV and SIGBUS) that
// filters out all crashes that are not considered "sandbox violations".
// Examples of such "safe" crahses (in the context of the sandbox) are memory
// access violations inside the sandbox address space or access violations
// that always lead to an immediate crash (for example, an access to a
// non-canonical address which may be the result of a tag mismatch in one of
// the sandbox's pointer tables). On the other hand, if the crash represents
// a legitimate sandbox violation, the signal is forwarded to the original
// signal handler which will report the crash appropriately.
//
// Currently supported on Linux only.
V8_EXPORT_PRIVATE static void Enable(Mode mode);
// Returns whether sandbox testing mode is enabled.
static bool IsEnabled() { return mode_ != Mode::kDisabled; }
#ifdef V8_ENABLE_MEMORY_CORRUPTION_API
// A JavaScript API that emulates typical exploit primitives.
//
// This can be used for testing the sandbox, for example to write regression
// tests for bugs in the sandbox or to develop fuzzers.
V8_EXPORT_PRIVATE static void InstallMemoryCorruptionApiIfEnabled(
Isolate* isolate);
#endif // V8_ENABLE_MEMORY_CORRUPTION_API
// The current sandbox testing mode.
static Mode mode() { return mode_; }
// If sandbox testing mode is enabled, returns the address of the target page
// that needs to be written to to demonstrate a sandbox bypass.
static Address target_page_base() { return target_page_base_; }
// If sandbox testing mode is enabled, returns the size of the target page
// that needs to be written to to demonstrate a sandbox bypass.
static Address target_page_size() { return target_page_size_; }
// Returns true if the access violation happened inside the target page.
static bool IsInsideTargetPage(Address faultaddr);
// Returns a mapping of instance types to known field offsets. This is useful
// mainly for the Sandbox.getFieldOffsetOf API which provides access to
// internal field offsets of HeapObject to JavaScript.
using FieldOffsets = std::unordered_map<std::string, int>;
using FieldOffsetMap = std::unordered_map<InstanceType, FieldOffsets>;
static FieldOffsetMap& GetFieldOffsetMap();
private:
static Mode mode_;
static Address target_page_base_;
static size_t target_page_size_;
};
#endif // V8_ENABLE_SANDBOX
} // namespace internal
} // namespace v8
#endif // V8_SANDBOX_TESTING_H_