Reland "[sandbox] Sandboxify EmbedderDataSlots"
This is a reland of commit e1f585ed94
ExternalPointerTable issues have been fixed in
https://crrev.com/c/3849650 and https://crrev.com/c/3849376
Original change's description:
> [sandbox] Sandboxify EmbedderDataSlots
>
> Bug: v8:10391
> Change-Id: If85a308a6f6ed1b17d86f87b4911c82d2327ea72
> 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/+/3757341
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Commit-Queue: Samuel Groß <saelo@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#82623}
Bug: v8:10391
Change-Id: If77f6c10e81c30c2dfa6b33c788bc4a36e4da135
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/+/3852602
Commit-Queue: Samuel Groß <saelo@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82686}
This commit is contained in:
parent
4c8c8cacdf
commit
eca383c947
@ -8,6 +8,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <type_traits>
|
||||
|
||||
#include "v8-version.h" // NOLINT(build/include_directory)
|
||||
@ -380,7 +382,7 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = {
|
||||
#define PER_ISOLATE_EXTERNAL_POINTER_TAGS(V) \
|
||||
V(kForeignForeignAddressTag, unsandboxed, TAG(10)) \
|
||||
V(kNativeContextMicrotaskQueueTag, sandboxed, TAG(11)) \
|
||||
V(kEmbedderDataSlotPayloadTag, unsandboxed, TAG(12)) \
|
||||
V(kEmbedderDataSlotPayloadTag, sandboxed, TAG(12)) \
|
||||
V(kCodeEntryPointTag, unsandboxed, TAG(13)) \
|
||||
V(kExternalObjectValueTag, sandboxed, TAG(14)) \
|
||||
V(kCallHandlerInfoCallbackTag, sandboxed, TAG(15)) \
|
||||
@ -511,7 +513,7 @@ class Internals {
|
||||
static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize;
|
||||
static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize;
|
||||
static const int kEmbedderDataSlotSize = kApiSystemPointerSize;
|
||||
#ifdef V8_SANDBOXED_EXTERNAL_POINTERS
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
static const int kEmbedderDataSlotExternalPointerOffset = kApiTaggedSize;
|
||||
#else
|
||||
static const int kEmbedderDataSlotExternalPointerOffset = 0;
|
||||
@ -796,7 +798,11 @@ class Internals {
|
||||
internal::ExternalPointerHandle handle =
|
||||
ReadRawField<ExternalPointerHandle>(heap_object_ptr, offset);
|
||||
uint32_t index = handle >> kExternalPointerIndexShift;
|
||||
return table[index] & ~tag;
|
||||
std::atomic<internal::Address>* ptr =
|
||||
reinterpret_cast<std::atomic<internal::Address>*>(&table[index]);
|
||||
internal::Address entry =
|
||||
std::atomic_load_explicit(ptr, std::memory_order_relaxed);
|
||||
return entry & ~tag;
|
||||
}
|
||||
#endif
|
||||
return ReadRawField<Address>(heap_object_ptr, offset);
|
||||
|
@ -88,7 +88,7 @@ bool EmbedderDataSlot::ToAlignedPointer(Isolate* isolate,
|
||||
// are accessed this way only from the main thread via API during "mutator"
|
||||
// phase which is propely synched with GC (concurrent marker may still look
|
||||
// at the tagged part of the embedder slot but read-only access is ok).
|
||||
#ifdef V8_SANDBOXED_EXTERNAL_POINTERS
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
// The raw part must always contain a valid external pointer table index.
|
||||
*out_pointer = reinterpret_cast<void*>(
|
||||
ReadExternalPointerField<kEmbedderDataSlotPayloadTag>(
|
||||
@ -107,13 +107,13 @@ bool EmbedderDataSlot::ToAlignedPointer(Isolate* isolate,
|
||||
}
|
||||
*out_pointer = reinterpret_cast<void*>(raw_value);
|
||||
return HAS_SMI_TAG(raw_value);
|
||||
#endif // V8_SANDBOXED_EXTERNAL_POINTERS
|
||||
#endif // V8_ENABLE_SANDBOX
|
||||
}
|
||||
|
||||
bool EmbedderDataSlot::store_aligned_pointer(Isolate* isolate, void* ptr) {
|
||||
Address value = reinterpret_cast<Address>(ptr);
|
||||
if (!HAS_SMI_TAG(value)) return false;
|
||||
#ifdef V8_SANDBOXED_EXTERNAL_POINTERS
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
DCHECK_EQ(0, value & kExternalPointerTagMask);
|
||||
// This also mark the entry as alive until the next GC.
|
||||
InitExternalPointerField<kEmbedderDataSlotPayloadTag>(
|
||||
@ -123,7 +123,7 @@ bool EmbedderDataSlot::store_aligned_pointer(Isolate* isolate, void* ptr) {
|
||||
#else
|
||||
gc_safe_store(isolate, value);
|
||||
return true;
|
||||
#endif // V8_SANDBOXED_EXTERNAL_POINTERS
|
||||
#endif // V8_ENABLE_SANDBOX
|
||||
}
|
||||
|
||||
EmbedderDataSlot::RawData EmbedderDataSlot::load_raw(
|
||||
|
@ -32,7 +32,7 @@ class Object;
|
||||
class EmbedderDataSlot
|
||||
: public SlotBase<EmbedderDataSlot, Address, kTaggedSize> {
|
||||
public:
|
||||
#if defined(V8_SANDBOXED_EXTERNAL_POINTERS)
|
||||
#ifdef V8_ENABLE_SANDBOX
|
||||
// When the sandbox is enabled, an EmbedderDataSlot always contains a valid
|
||||
// external pointer table index (initially, zero) in it's "raw" part and a
|
||||
// valid tagged value in its 32-bit "tagged" part.
|
||||
@ -85,7 +85,7 @@ class EmbedderDataSlot
|
||||
// kExternalPointerOffset
|
||||
static constexpr int kTaggedPayloadOffset = 0;
|
||||
static constexpr int kExternalPointerOffset = 0;
|
||||
#endif // V8_SANDBOXED_EXTERNAL_POINTERS
|
||||
#endif // V8_ENABLE_SANDBOX
|
||||
|
||||
static constexpr int kRequiredPtrAlignment = kSmiTagSize;
|
||||
|
||||
@ -120,9 +120,9 @@ class EmbedderDataSlot
|
||||
// the pointer-like value. Note, that some Smis could still look like an
|
||||
// aligned pointers.
|
||||
// Returns true on success.
|
||||
// When sandboxed external pointers are enabled, calling this method when the
|
||||
// raw part of the slot does not contain valid external pointer table index
|
||||
// is undefined behaviour and most likely result in crashes.
|
||||
// When the sandbox is enabled, calling this method when the raw part of the
|
||||
// slot does not contain valid external pointer table index is undefined
|
||||
// behaviour and most likely result in crashes.
|
||||
V8_INLINE bool ToAlignedPointer(Isolate* isolate, void** out_result) const;
|
||||
|
||||
// Returns true if the pointer was successfully stored or false it the pointer
|
||||
|
Loading…
Reference in New Issue
Block a user