Commit e1f585ed authored by Samuel Groß's avatar Samuel Groß Committed by V8 LUCI CQ

[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/+/3757341Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Samuel Groß <saelo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82623}
parent d7efb963
......@@ -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)) \
......@@ -513,7 +515,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;
......@@ -798,7 +800,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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment