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

[sandbox] Don't use external pointer table for ArrayBuffers

ArrayBuffer backing stores will instead use the virtual memory cage and
be referenced through offsets rather than pointers when the sandbox is
enabled. This will be implemented in an independent CL.

Bug: v8:10391
Change-Id: Icc9781003e53c76dbbf4c84ee165151e4182da4b
Cq-Include-Trybots: luci.v8.try:v8_linux64_heap_sandbox_dbg_ng
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3086458Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Samuel Groß <saelo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76348}
parent 366b97a5
......@@ -141,15 +141,12 @@ using ExternalPointer_t = Address;
// the same time.
enum ExternalPointerTag : uint64_t {
kExternalPointerNullTag = 0x0000000000000000,
kArrayBufferBackingStoreTag = 0x00ff000000000000, // 0b000000011111111
kTypedArrayExternalPointerTag = 0x017f000000000000, // 0b000000101111111
kDataViewDataPointerTag = 0x01bf000000000000, // 0b000000110111111
kExternalStringResourceTag = 0x01df000000000000, // 0b000000111011111
kExternalStringResourceDataTag = 0x01ef000000000000, // 0b000000111101111
kForeignForeignAddressTag = 0x01f7000000000000, // 0b000000111110111
kNativeContextMicrotaskQueueTag = 0x01fb000000000000, // 0b000000111111011
kEmbedderDataSlotPayloadTag = 0x01fd000000000000, // 0b000000111111101
kCodeEntryPointTag = 0x01fe000000000000, // 0b000000111111110
kExternalStringResourceTag = 0x00ff000000000000, // 0b000000011111111
kExternalStringResourceDataTag = 0x017f000000000000, // 0b000000101111111
kForeignForeignAddressTag = 0x01bf000000000000, // 0b000000110111111
kNativeContextMicrotaskQueueTag = 0x01df000000000000, // 0b000000111011111
kEmbedderDataSlotPayloadTag = 0x01ef000000000000, // 0b000000111101111
kCodeEntryPointTag = 0x01f7000000000000, // 0b000000111110111
};
constexpr uint64_t kExternalPointerTagMask = 0xffff000000000000;
......
......@@ -102,7 +102,6 @@ BUILTIN(DataViewConstructor) {
// 13. Set O's [[ByteOffset]] internal slot to offset.
Handle<JSDataView>::cast(result)->set_byte_offset(view_byte_offset);
Handle<JSDataView>::cast(result)->AllocateExternalPointerEntries(isolate);
Handle<JSDataView>::cast(result)->set_data_pointer(
isolate,
static_cast<uint8_t*>(array_buffer->backing_store()) + view_byte_offset);
......
......@@ -65,9 +65,8 @@ TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer(
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kByteLengthOffset,
byte_length);
InitializeExternalPointerField(buffer, JSArrayBuffer::kBackingStoreOffset,
PointerConstant(nullptr),
kArrayBufferBackingStoreTag);
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kBackingStoreOffset,
PointerConstant(nullptr));
StoreObjectFieldNoWriteBarrier(buffer, JSArrayBuffer::kExtensionOffset,
IntPtrConstant(0));
for (int offset = JSArrayBuffer::kHeaderSize;
......@@ -404,12 +403,6 @@ void TypedArrayBuiltinsAssembler::DispatchTypedArrayByElementsKind(
BIND(&next);
}
void TypedArrayBuiltinsAssembler::AllocateJSTypedArrayExternalPointerEntry(
TNode<JSTypedArray> holder) {
InitializeExternalPointerField(
holder, IntPtrConstant(JSTypedArray::kExternalPointerOffset));
}
void TypedArrayBuiltinsAssembler::SetJSTypedArrayOnHeapDataPtr(
TNode<JSTypedArray> holder, TNode<ByteArray> base, TNode<UintPtrT> offset) {
offset = UintPtrAdd(UintPtrConstant(ByteArray::kHeaderSize - kHeapObjectTag),
......
......@@ -83,7 +83,6 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
void DispatchTypedArrayByElementsKind(
TNode<Word32T> elements_kind, const TypedArraySwitchCase& case_function);
void AllocateJSTypedArrayExternalPointerEntry(TNode<JSTypedArray> holder);
void SetJSTypedArrayOnHeapDataPtr(TNode<JSTypedArray> holder,
TNode<ByteArray> base,
TNode<UintPtrT> offset);
......
......@@ -62,7 +62,6 @@ transitioning macro AllocateTypedArray(implicit context: Context)(
typedArray.bit_field.is_length_tracking = isLengthTracking;
typedArray.bit_field.is_backed_by_rab =
IsResizableArrayBuffer(buffer) && !IsSharedArrayBuffer(buffer);
typed_array::AllocateJSTypedArrayExternalPointerEntry(typedArray);
if constexpr (isOnHeap) {
typed_array::SetJSTypedArrayOnHeapDataPtr(typedArray, elements, byteOffset);
} else {
......
......@@ -161,10 +161,6 @@ macro GetTypedArrayAccessor(elementsKind: ElementsKind): TypedArrayAccessor {
unreachable;
}
extern macro
TypedArrayBuiltinsAssembler::AllocateJSTypedArrayExternalPointerEntry(
JSTypedArray): void;
extern macro TypedArrayBuiltinsAssembler::SetJSTypedArrayOnHeapDataPtr(
JSTypedArray, ByteArray, uintptr): void;
extern macro TypedArrayBuiltinsAssembler::SetJSTypedArrayOffHeapDataPtr(
......
......@@ -13797,9 +13797,8 @@ void CodeStubAssembler::ThrowIfArrayBufferViewBufferIsDetached(
TNode<RawPtrT> CodeStubAssembler::LoadJSArrayBufferBackingStorePtr(
TNode<JSArrayBuffer> array_buffer) {
return LoadExternalPointerFromObject(array_buffer,
JSArrayBuffer::kBackingStoreOffset,
kArrayBufferBackingStoreTag);
return LoadObjectField<RawPtrT>(array_buffer,
JSArrayBuffer::kBackingStoreOffset);
}
TNode<JSArrayBuffer> CodeStubAssembler::LoadJSArrayBufferViewBuffer(
......
......@@ -1107,15 +1107,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<RawPtrT> LoadJSTypedArrayExternalPointerPtr(
TNode<JSTypedArray> holder) {
return LoadExternalPointerFromObject(holder,
JSTypedArray::kExternalPointerOffset,
kTypedArrayExternalPointerTag);
return LoadObjectField<RawPtrT>(holder,
JSTypedArray::kExternalPointerOffset);
}
void StoreJSTypedArrayExternalPointerPtr(TNode<JSTypedArray> holder,
TNode<RawPtrT> value) {
StoreExternalPointerToObject(holder, JSTypedArray::kExternalPointerOffset,
value, kTypedArrayExternalPointerTag);
StoreObjectFieldNoWriteBarrier<RawPtrT>(
holder, JSTypedArray::kExternalPointerOffset, value);
}
// Load value from current parent frame by given offset in bytes.
......
......@@ -416,19 +416,16 @@ FieldAccess AccessBuilder::ForJSTypedArrayBasePointer() {
// static
FieldAccess AccessBuilder::ForJSTypedArrayExternalPointer() {
FieldAccess access = {kTaggedBase,
FieldAccess access = {
kTaggedBase,
JSTypedArray::kExternalPointerOffset,
MaybeHandle<Name>(),
MaybeHandle<Map>(),
V8_HEAP_SANDBOX_BOOL ? Type::SandboxedExternalPointer()
: Type::ExternalPointer(),
Type::ExternalPointer(),
MachineType::Pointer(),
kNoWriteBarrier,
ConstFieldInfo::None(),
false,
#ifdef V8_HEAP_SANDBOX
kTypedArrayExternalPointerTag
#endif
};
return access;
}
......@@ -440,15 +437,11 @@ FieldAccess AccessBuilder::ForJSDataViewDataPointer() {
JSDataView::kDataPointerOffset,
MaybeHandle<Name>(),
MaybeHandle<Map>(),
V8_HEAP_SANDBOX_BOOL ? Type::SandboxedExternalPointer()
: Type::ExternalPointer(),
Type::ExternalPointer(),
MachineType::Pointer(),
kNoWriteBarrier,
ConstFieldInfo::None(),
false,
#ifdef V8_HEAP_SANDBOX
kDataViewDataPointerTag,
#endif
};
return access;
}
......
......@@ -2873,7 +2873,6 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
map, empty_byte_array(), buffer, byte_offset, byte_length));
JSTypedArray raw = *typed_array;
DisallowGarbageCollection no_gc;
raw.AllocateExternalPointerEntries(isolate());
raw.set_length(length);
raw.SetOffHeapDataPtr(isolate(), buffer->backing_store(), byte_offset);
raw.set_is_length_tracking(false);
......@@ -2888,7 +2887,6 @@ Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
isolate());
Handle<JSDataView> obj = Handle<JSDataView>::cast(NewJSArrayBufferView(
map, empty_fixed_array(), buffer, byte_offset, byte_length));
obj->AllocateExternalPointerEntries(isolate());
obj->set_data_pointer(
isolate(), static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
return obj;
......
......@@ -30,10 +30,6 @@ ACCESSORS(JSTypedArray, base_pointer, Object, kBasePointerOffset)
RELEASE_ACQUIRE_ACCESSORS(JSTypedArray, base_pointer, Object,
kBasePointerOffset)
void JSArrayBuffer::AllocateExternalPointerEntries(Isolate* isolate) {
InitExternalPointerField(kBackingStoreOffset, isolate);
}
size_t JSArrayBuffer::byte_length() const {
return ReadField<size_t>(kByteLengthOffset);
}
......@@ -43,27 +39,20 @@ void JSArrayBuffer::set_byte_length(size_t value) {
}
DEF_GETTER(JSArrayBuffer, backing_store, void*) {
Isolate* isolate = GetIsolateForHeapSandbox(*this);
Address value = ReadExternalPointerField(kBackingStoreOffset, isolate,
kArrayBufferBackingStoreTag);
return reinterpret_cast<void*>(value);
return reinterpret_cast<void*>(ReadField<Address>(kBackingStoreOffset));
}
void JSArrayBuffer::set_backing_store(Isolate* isolate, void* value) {
DCHECK(isolate->IsValidBackingStorePointer(value));
WriteExternalPointerField(kBackingStoreOffset, isolate,
reinterpret_cast<Address>(value),
kArrayBufferBackingStoreTag);
WriteField<Address>(kBackingStoreOffset, reinterpret_cast<Address>(value));
}
uint32_t JSArrayBuffer::GetBackingStoreRefForDeserialization() const {
return static_cast<uint32_t>(
ReadField<ExternalPointer_t>(kBackingStoreOffset));
return static_cast<uint32_t>(ReadField<Address>(kBackingStoreOffset));
}
void JSArrayBuffer::SetBackingStoreRefForSerialization(uint32_t ref) {
WriteField<ExternalPointer_t>(kBackingStoreOffset,
static_cast<ExternalPointer_t>(ref));
WriteField<Address>(kBackingStoreOffset, static_cast<Address>(ref));
}
ArrayBufferExtension* JSArrayBuffer::extension() const {
......@@ -239,10 +228,6 @@ size_t JSTypedArray::GetLength() const {
return GetLengthOrOutOfBounds(out_of_bounds);
}
void JSTypedArray::AllocateExternalPointerEntries(Isolate* isolate) {
InitExternalPointerField(kExternalPointerOffset, isolate);
}
size_t JSTypedArray::length() const {
DCHECK(!is_length_tracking());
DCHECK(!is_backed_by_rab());
......@@ -258,19 +243,16 @@ void JSTypedArray::set_length(size_t value) {
}
DEF_GETTER(JSTypedArray, external_pointer, Address) {
Isolate* isolate = GetIsolateForHeapSandbox(*this);
return ReadExternalPointerField(kExternalPointerOffset, isolate,
kTypedArrayExternalPointerTag);
return ReadField<Address>(kExternalPointerOffset);
}
DEF_GETTER(JSTypedArray, external_pointer_raw, ExternalPointer_t) {
return ReadField<ExternalPointer_t>(kExternalPointerOffset);
DEF_GETTER(JSTypedArray, external_pointer_raw, Address) {
return ReadField<Address>(kExternalPointerOffset);
}
void JSTypedArray::set_external_pointer(Isolate* isolate, Address value) {
DCHECK(isolate->IsValidBackingStorePointer(reinterpret_cast<void*>(value)));
WriteExternalPointerField(kExternalPointerOffset, isolate, value,
kTypedArrayExternalPointerTag);
WriteField<Address>(kExternalPointerOffset, value);
}
Address JSTypedArray::ExternalPointerCompensationForOnHeapArray(
......@@ -284,14 +266,12 @@ Address JSTypedArray::ExternalPointerCompensationForOnHeapArray(
uint32_t JSTypedArray::GetExternalBackingStoreRefForDeserialization() const {
DCHECK(!is_on_heap());
return static_cast<uint32_t>(
ReadField<ExternalPointer_t>(kExternalPointerOffset));
return static_cast<uint32_t>(ReadField<Address>(kExternalPointerOffset));
}
void JSTypedArray::SetExternalBackingStoreRefForSerialization(uint32_t ref) {
DCHECK(!is_on_heap());
WriteField<ExternalPointer_t>(kExternalPointerOffset,
static_cast<ExternalPointer_t>(ref));
WriteField<Address>(kExternalPointerOffset, static_cast<Address>(ref));
}
void JSTypedArray::RemoveExternalPointerCompensationForSerialization(
......@@ -392,20 +372,12 @@ MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
}
DEF_GETTER(JSDataView, data_pointer, void*) {
Isolate* isolate = GetIsolateForHeapSandbox(*this);
return reinterpret_cast<void*>(ReadExternalPointerField(
kDataPointerOffset, isolate, kDataViewDataPointerTag));
}
void JSDataView::AllocateExternalPointerEntries(Isolate* isolate) {
InitExternalPointerField(kDataPointerOffset, isolate);
return reinterpret_cast<void*>(ReadField<Address>(kDataPointerOffset));
}
void JSDataView::set_data_pointer(Isolate* isolate, void* value) {
DCHECK(isolate->IsValidBackingStorePointer(value));
WriteExternalPointerField(kDataPointerOffset, isolate,
reinterpret_cast<Address>(value),
kDataViewDataPointerTag);
WriteField<Address>(kDataPointerOffset, reinterpret_cast<Address>(value));
}
} // namespace internal
......
......@@ -55,7 +55,6 @@ void JSArrayBuffer::Setup(SharedFlag shared, ResizableFlag resizable,
SetEmbedderField(i, Smi::zero());
}
set_extension(nullptr);
AllocateExternalPointerEntries(GetIsolate());
if (!backing_store) {
set_backing_store(GetIsolate(), nullptr);
set_byte_length(0);
......
......@@ -32,12 +32,6 @@ class JSArrayBuffer
static constexpr size_t kMaxByteLength = kMaxSafeInteger;
#endif
// When soft sandbox is enabled, creates entries in external pointer table for
// all JSArrayBuffer's fields that require soft sandbox protection (backing
// store pointer, backing store length, etc.).
// When sandbox is not enabled, it's a no-op.
inline void AllocateExternalPointerEntries(Isolate* isolate);
// [byte_length]: length in bytes
DECL_PRIMITIVE_ACCESSORS(byte_length, size_t)
......@@ -283,12 +277,6 @@ class JSTypedArray
V8_EXPORT_PRIVATE Handle<JSArrayBuffer> GetBuffer();
// When soft sandbox is enabled, creates entries in external pointer table for
// all JSTypedArray's fields that require soft sandbox protection (external
// pointer, offset, length, etc.).
// When sandbox is not enabled, it's a no-op.
inline void AllocateExternalPointerEntries(Isolate* isolate);
// The `DataPtr` is `base_ptr + external_pointer`, and `base_ptr` is nullptr
// for off-heap typed arrays.
static constexpr bool kOffHeapDataPtrEqualsExternalPointer = true;
......@@ -392,12 +380,6 @@ class JSDataView
DECL_GETTER(data_pointer, void*)
inline void set_data_pointer(Isolate* isolate, void* value);
// When soft sandbox is enabled, creates entries in external pointer table for
// all JSDataView's fields that require soft sandbox protection (data pointer,
// offset, length, etc.).
// When sandbox is not enabled, it's a no-op.
inline void AllocateExternalPointerEntries(Isolate* isolate);
// Dispatched behavior.
DECL_PRINTER(JSDataView)
DECL_VERIFIER(JSDataView)
......
......@@ -61,7 +61,6 @@ void ContextDeserializer::SetupOffHeapArrayBufferBackingStores() {
for (Handle<JSArrayBuffer> buffer : new_off_heap_array_buffers()) {
uint32_t store_index = buffer->GetBackingStoreRefForDeserialization();
auto bs = backing_store(store_index);
buffer->AllocateExternalPointerEntries(isolate());
// TODO(v8:11111): Support RAB / GSAB.
CHECK(!buffer->is_resizable());
SharedFlag shared =
......
......@@ -482,7 +482,6 @@ void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
// a numbered reference to an already deserialized backing store.
backing_store = backing_stores_[store_index]->buffer_start();
}
data_view->AllocateExternalPointerEntries(main_thread_isolate());
data_view->set_data_pointer(
main_thread_isolate(),
reinterpret_cast<uint8_t*>(backing_store) + data_view->byte_offset());
......@@ -491,7 +490,6 @@ void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
// Fixup typed array pointers.
if (typed_array->is_on_heap()) {
Address raw_external_pointer = typed_array->external_pointer_raw();
typed_array->AllocateExternalPointerEntries(main_thread_isolate());
typed_array->SetOnHeapDataPtr(
main_thread_isolate(), HeapObject::cast(typed_array->base_pointer()),
raw_external_pointer);
......@@ -503,7 +501,6 @@ void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
auto start = backing_store
? reinterpret_cast<byte*>(backing_store->buffer_start())
: nullptr;
typed_array->AllocateExternalPointerEntries(main_thread_isolate());
typed_array->SetOffHeapDataPtr(main_thread_isolate(), start,
typed_array->byte_offset());
}
......@@ -513,7 +510,6 @@ void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
if (buffer->GetBackingStoreRefForDeserialization() != kNullRefSentinel) {
new_off_heap_array_buffers_.push_back(buffer);
} else {
buffer->AllocateExternalPointerEntries(main_thread_isolate());
buffer->set_backing_store(main_thread_isolate(), nullptr);
}
} else if (InstanceTypeChecker::IsBytecodeArray(instance_type)) {
......
......@@ -521,10 +521,6 @@ void Serializer::ObjectSerializer::SerializeJSArrayBuffer() {
ArrayBufferExtension* extension = buffer->extension();
// The embedder-allocated backing store only exists for the off-heap case.
#ifdef V8_HEAP_SANDBOX
uint32_t external_pointer_entry =
buffer->GetBackingStoreRefForDeserialization();
#endif
if (backing_store != nullptr) {
uint32_t ref = SerializeBackingStore(backing_store, byte_length);
buffer->SetBackingStoreRefForSerialization(ref);
......@@ -538,11 +534,7 @@ void Serializer::ObjectSerializer::SerializeJSArrayBuffer() {
SerializeObject();
#ifdef V8_HEAP_SANDBOX
buffer->SetBackingStoreRefForSerialization(external_pointer_entry);
#else
buffer->set_backing_store(isolate(), backing_store);
#endif
buffer->set_extension(extension);
}
......
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