Reland "Reland "[sandbox] Sandboxify EmbedderDataSlots""

This is a reland of commit eca383c947

More DCHECK failures have been fixed with https://crrev.com/c/3857423

Original change's description:
> 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}

Bug: v8:10391
Change-Id: Id982c022e50004e903851b160d30fc8767280e5b
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/+/3854679
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Samuel Groß <saelo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82767}
This commit is contained in:
Samuel Groß 2022-08-25 14:24:48 +02:00 committed by V8 LUCI CQ
parent 918b46afb4
commit e710981f3a
3 changed files with 18 additions and 12 deletions

View File

@ -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);

View File

@ -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);
// When the sandbox is enabled, the external pointer handles in
// EmbedderDataSlots are lazily initialized: initially they contain the null
@ -126,7 +126,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(

View File

@ -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