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

[sandbox] Refactor and sandboxify WasmContinuationObject::jmpbuf

This CL refactors WasmContinuationObject to have a direct
ExternalPointer to the jmpbuf structure instead of using a Foreign.
This in turn makes it possible to use a unique pointer tag for that
external pointer when the sandbox is enabled.

Bug: v8:10391, v8:12949
Change-Id: I25528bd8aaffb32dd617440d3ccb77d319894a38
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/+/3805061Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Samuel Groß <saelo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82238}
parent 5fe919f7
......@@ -388,7 +388,8 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = {
V(kAccessorInfoGetterTag, sandboxed, TAG(17)) \
V(kAccessorInfoJsGetterTag, sandboxed, TAG(18)) \
V(kAccessorInfoSetterTag, sandboxed, TAG(19)) \
V(kWasmInternalFunctionCallTargetTag, sandboxed, TAG(20))
V(kWasmInternalFunctionCallTargetTag, sandboxed, TAG(20)) \
V(kWasmContinuationJmpbufTag, sandboxed, TAG(21))
// All external pointer tags.
#define ALL_EXTERNAL_POINTER_TAGS(V) \
......
......@@ -3008,14 +3008,11 @@ void LoadJumpBuffer(MacroAssembler* masm, Register jmpbuf, bool load_pc) {
void SaveState(MacroAssembler* masm, Register active_continuation, Register tmp,
Label* suspend) {
Register foreign_jmpbuf = tmp;
__ LoadAnyTaggedField(
foreign_jmpbuf,
FieldOperand(active_continuation, WasmContinuationObject::kJmpbufOffset));
Register jmpbuf = foreign_jmpbuf;
Register jmpbuf = tmp;
__ LoadExternalPointerField(
jmpbuf, FieldOperand(foreign_jmpbuf, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag, kScratchRegister);
jmpbuf,
FieldOperand(active_continuation, WasmContinuationObject::kJmpbufOffset),
kWasmContinuationJmpbufTag, kScratchRegister);
FillJumpBuffer(masm, jmpbuf, suspend);
}
......@@ -3038,15 +3035,11 @@ void AllocateSuspender(MacroAssembler* masm, Register function_data,
}
void LoadTargetJumpBuffer(MacroAssembler* masm, Register target_continuation) {
Register foreign_jmpbuf = target_continuation;
__ LoadAnyTaggedField(
foreign_jmpbuf,
FieldOperand(target_continuation, WasmContinuationObject::kJmpbufOffset));
Register target_jmpbuf = foreign_jmpbuf;
Register target_jmpbuf = target_continuation;
__ LoadExternalPointerField(
target_jmpbuf,
FieldOperand(foreign_jmpbuf, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag, kScratchRegister);
FieldOperand(target_continuation, WasmContinuationObject::kJmpbufOffset),
kWasmContinuationJmpbufTag, kScratchRegister);
MemOperand GCScanSlotPlace =
MemOperand(rbp, BuiltinWasmWrapperConstants::kGCScanSlotCountOffset);
__ Move(GCScanSlotPlace, 0);
......@@ -3062,14 +3055,11 @@ void ReloadParentContinuation(MacroAssembler* masm, Register wasm_instance,
// Set a null pointer in the jump buffer's SP slot to indicate to the stack
// frame iterator that this stack is empty.
Register foreign_jmpbuf = kScratchRegister;
__ LoadAnyTaggedField(
foreign_jmpbuf,
FieldOperand(active_continuation, WasmContinuationObject::kJmpbufOffset));
Register jmpbuf = foreign_jmpbuf;
Register jmpbuf = kScratchRegister;
__ LoadExternalPointerField(
jmpbuf, FieldOperand(foreign_jmpbuf, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag, tmp2);
jmpbuf,
FieldOperand(active_continuation, WasmContinuationObject::kJmpbufOffset),
kWasmContinuationJmpbufTag, tmp2);
__ movq(Operand(jmpbuf, wasm::kJmpBufSpOffset), Immediate(kNullAddress));
Register parent = tmp2;
......@@ -3079,14 +3069,10 @@ void ReloadParentContinuation(MacroAssembler* masm, Register wasm_instance,
// Update active continuation root.
__ movq(masm->RootAsOperand(RootIndex::kActiveContinuation), parent);
foreign_jmpbuf = tmp1;
__ LoadAnyTaggedField(
foreign_jmpbuf,
FieldOperand(parent, WasmContinuationObject::kJmpbufOffset));
jmpbuf = foreign_jmpbuf;
jmpbuf = parent;
__ LoadExternalPointerField(
jmpbuf, FieldOperand(foreign_jmpbuf, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag, tmp2);
jmpbuf, FieldOperand(parent, WasmContinuationObject::kJmpbufOffset),
kWasmContinuationJmpbufTag, tmp1);
// Switch stack!
LoadJumpBuffer(masm, jmpbuf, false);
......@@ -4106,12 +4092,9 @@ void Builtins::Generate_WasmSuspend(MacroAssembler* masm) {
Register continuation = rcx;
__ LoadRoot(continuation, RootIndex::kActiveContinuation);
Register jmpbuf = rdx;
__ LoadAnyTaggedField(
jmpbuf,
FieldOperand(continuation, WasmContinuationObject::kJmpbufOffset));
__ LoadExternalPointerField(
jmpbuf, FieldOperand(jmpbuf, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag, r8);
jmpbuf, FieldOperand(continuation, WasmContinuationObject::kJmpbufOffset),
kWasmContinuationJmpbufTag, r8);
FillJumpBuffer(masm, jmpbuf, &resume);
__ StoreTaggedSignedField(
FieldOperand(suspender, WasmSuspenderObject::kStateOffset),
......@@ -4165,12 +4148,10 @@ void Builtins::Generate_WasmSuspend(MacroAssembler* masm) {
__ Pop(caller);
__ Pop(promise);
jmpbuf = caller;
__ LoadAnyTaggedField(
jmpbuf, FieldOperand(caller, WasmContinuationObject::kJmpbufOffset));
caller = no_reg;
__ LoadExternalPointerField(
jmpbuf, FieldOperand(jmpbuf, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag, r8);
jmpbuf, FieldOperand(caller, WasmContinuationObject::kJmpbufOffset),
kWasmContinuationJmpbufTag, r8);
caller = no_reg;
__ movq(kReturnRegister0, promise);
__ Move(GCScanSlotPlace, 0);
LoadJumpBuffer(masm, jmpbuf, true);
......@@ -4246,13 +4227,10 @@ void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
Register active_continuation = r9;
__ LoadRoot(active_continuation, RootIndex::kActiveContinuation);
Register current_jmpbuf = rax;
__ LoadAnyTaggedField(
current_jmpbuf,
FieldOperand(active_continuation, WasmContinuationObject::kJmpbufOffset));
__ LoadExternalPointerField(
current_jmpbuf,
FieldOperand(current_jmpbuf, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag, rdx);
FieldOperand(active_continuation, WasmContinuationObject::kJmpbufOffset),
kWasmContinuationJmpbufTag, rdx);
FillJumpBuffer(masm, current_jmpbuf, &suspend);
current_jmpbuf = no_reg;
......@@ -4301,13 +4279,10 @@ void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
// Load state from target jmpbuf (longjmp).
// -------------------------------------------
Register target_jmpbuf = rdi;
__ LoadAnyTaggedField(
target_jmpbuf,
FieldOperand(target_continuation, WasmContinuationObject::kJmpbufOffset));
__ LoadExternalPointerField(
target_jmpbuf,
FieldOperand(target_jmpbuf, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag, rax);
FieldOperand(target_continuation, WasmContinuationObject::kJmpbufOffset),
kWasmContinuationJmpbufTag, rax);
// Move resolved value to return register.
__ movq(kReturnRegister0, Operand(rbp, 3 * kSystemPointerSize));
__ Move(GCScanSlotPlace, 0);
......
......@@ -1892,6 +1892,19 @@ Handle<WasmStruct> Factory::NewWasmStruct(const wasm::StructType* type,
return handle(result, isolate());
}
Handle<WasmContinuationObject> Factory::NewWasmContinuationObject(
Address jmpbuf, Handle<Foreign> managed_stack, Handle<HeapObject> parent,
AllocationType allocation) {
Map map = *wasm_continuation_object_map();
auto result = WasmContinuationObject::cast(
AllocateRawWithImmortalMap(map.instance_size(), allocation, map));
result.AllocateExternalPointerEntries(isolate());
result.set_jmpbuf(isolate(), jmpbuf);
result.set_stack(*managed_stack);
result.set_parent(*parent);
return handle(result, isolate());
}
Handle<SharedFunctionInfo>
Factory::NewSharedFunctionInfoForWasmExportedFunction(
Handle<String> name, Handle<WasmExportedFunctionData> data) {
......
......@@ -672,6 +672,9 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<Object> NewWasmArrayFromElementSegment(
Handle<WasmInstanceObject> instance, const wasm::WasmElemSegment* segment,
uint32_t start_offset, uint32_t length, Handle<Map> map);
Handle<WasmContinuationObject> NewWasmContinuationObject(
Address jmpbuf, Handle<Foreign> managed_stack, Handle<HeapObject> parent,
AllocationType allocation = AllocationType::kYoung);
Handle<SharedFunctionInfo> NewSharedFunctionInfoForWasmExportedFunction(
Handle<String> name, Handle<WasmExportedFunctionData> data);
......
......@@ -69,7 +69,8 @@ namespace internal {
IF_WASM(V, WasmStruct) \
IF_WASM(V, WasmSuspenderObject) \
IF_WASM(V, WasmResumeData) \
IF_WASM(V, WasmTypeInfo)
IF_WASM(V, WasmTypeInfo) \
IF_WASM(V, WasmContinuationObject)
#define FORWARD_DECLARE(TypeName) class TypeName;
TYPED_VISITOR_ID_LIST(FORWARD_DECLARE)
......
......@@ -521,6 +521,8 @@ bool Heap::CreateInitialMaps() {
wasm_resume_data)
IF_WASM(ALLOCATE_MAP, WASM_TYPE_INFO_TYPE, kVariableSizeSentinel,
wasm_type_info)
IF_WASM(ALLOCATE_MAP, WASM_CONTINUATION_OBJECT_TYPE,
WasmContinuationObject::kSize, wasm_continuation_object)
ALLOCATE_MAP(WEAK_CELL_TYPE, WeakCell::kSize, weak_cell)
......
......@@ -389,6 +389,8 @@ VisitorId Map::GetVisitorId(Map map) {
return kVisitWasmArray;
case WASM_STRUCT_TYPE:
return kVisitWasmStruct;
case WASM_CONTINUATION_OBJECT_TYPE:
return kVisitWasmContinuationObject;
case WASM_TYPE_INFO_TYPE:
return kVisitWasmTypeInfo;
case WASM_INTERNAL_FUNCTION_TYPE:
......
......@@ -88,6 +88,7 @@ enum InstanceType : uint16_t;
IF_WASM(V, WasmStruct) \
IF_WASM(V, WasmSuspenderObject) \
IF_WASM(V, WasmTypeInfo) \
IF_WASM(V, WasmContinuationObject) \
V(WeakCell)
#define TORQUE_VISITOR_ID_LIST(V) \
......
......@@ -264,6 +264,7 @@ class ZoneForwardList;
IF_WASM(V, WasmTableObject) \
IF_WASM(V, WasmValueObject) \
IF_WASM(V, WasmSuspenderObject) \
IF_WASM(V, WasmContinuationObject) \
V(WeakFixedArray) \
V(WeakArrayList) \
V(WeakCell) \
......
......@@ -811,6 +811,24 @@ class WasmArray::BodyDescriptor final : public BodyDescriptorBase {
}
};
class WasmContinuationObject::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
UNREACHABLE();
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, int object_size,
ObjectVisitor* v) {
IteratePointers(obj, kStartOfStrongFieldsOffset, kEndOfStrongFieldsOffset,
v);
v->VisitExternalPointer(obj, obj.RawExternalPointerField(kJmpbufOffset),
kWasmContinuationJmpbufTag);
}
static inline int SizeOf(Map map, HeapObject object) { return kSize; }
};
class WasmStruct::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
......@@ -1174,6 +1192,8 @@ auto BodyDescriptorApply(InstanceType type, Args&&... args) {
return CALL_APPLY(WasmJSFunctionData);
case WASM_RESUME_DATA_TYPE:
return CALL_APPLY(WasmResumeData);
case WASM_CONTINUATION_OBJECT_TYPE:
return CALL_APPLY(WasmContinuationObject);
case WASM_STRUCT_TYPE:
return CALL_APPLY(WasmStruct);
case WASM_TYPE_INFO_TYPE:
......
......@@ -165,8 +165,6 @@ namespace internal {
V(_, TEMPLATE_OBJECT_DESCRIPTION_TYPE, TemplateObjectDescription, \
template_object_description) \
V(_, TUPLE2_TYPE, Tuple2, tuple2) \
IF_WASM(V, _, WASM_CONTINUATION_OBJECT_TYPE, WasmContinuationObject, \
wasm_continuation_object) \
IF_WASM(V, _, WASM_EXCEPTION_TAG_TYPE, WasmExceptionTag, wasm_exception_tag) \
IF_WASM(V, _, WASM_INDIRECT_FUNCTION_TABLE_TYPE, WasmIndirectFunctionTable, \
wasm_indirect_function_table)
......
......@@ -122,6 +122,7 @@ class Symbol;
IF_WASM(V, Map, wasm_js_function_data_map, WasmJSFunctionDataMap) \
IF_WASM(V, Map, wasm_resume_data_map, WasmResumeDataMap) \
IF_WASM(V, Map, wasm_type_info_map, WasmTypeInfoMap) \
IF_WASM(V, Map, wasm_continuation_object_map, WasmContinuationObjectMap) \
V(Map, weak_fixed_array_map, WeakFixedArrayMap) \
V(Map, weak_array_list_map, WeakArrayListMap) \
V(Map, ephemeron_hash_table_map, EphemeronHashTableMap) \
......
......@@ -640,6 +640,13 @@ void WasmArray::EncodeElementSizeInMap(int element_size, Map map) {
// static
int WasmArray::DecodeElementSizeFromMap(Map map) { return map.WasmByte1(); }
EXTERNAL_POINTER_ACCESSORS(WasmContinuationObject, jmpbuf, Address,
kJmpbufOffset, kWasmContinuationJmpbufTag)
void WasmContinuationObject::AllocateExternalPointerEntries(Isolate* isolate) {
InitExternalPointerField<kWasmContinuationJmpbufTag>(kJmpbufOffset, isolate);
}
#include "src/objects/object-macros-undef.h"
} // namespace internal
......
......@@ -1800,14 +1800,10 @@ Handle<WasmContinuationObject> WasmContinuationObject::New(
size_t external_size = stack->owned_size();
Handle<Foreign> managed_stack = Managed<wasm::StackMemory>::FromUniquePtr(
isolate, external_size, std::move(stack), allocation_type);
Handle<Foreign> foreign_jmpbuf = isolate->factory()->NewForeign(
reinterpret_cast<Address>(jmpbuf), allocation_type);
Handle<WasmContinuationObject> result =
Handle<WasmContinuationObject>::cast(isolate->factory()->NewStruct(
WASM_CONTINUATION_OBJECT_TYPE, allocation_type));
result->set_jmpbuf(*foreign_jmpbuf);
result->set_stack(*managed_stack);
result->set_parent(*parent);
isolate->factory()->NewWasmContinuationObject(
reinterpret_cast<Address>(jmpbuf), managed_stack, parent,
allocation_type);
return result;
}
......
......@@ -1025,7 +1025,7 @@ class WasmArray : public TorqueGeneratedWasmArray<WasmArray, WasmObject> {
// A wasm delimited continuation.
class WasmContinuationObject
: public TorqueGeneratedWasmContinuationObject<WasmContinuationObject,
Struct> {
HeapObject> {
public:
static Handle<WasmContinuationObject> New(
Isolate* isolate, std::unique_ptr<wasm::StackMemory> stack,
......@@ -1033,17 +1033,23 @@ class WasmContinuationObject
static Handle<WasmContinuationObject> New(
Isolate* isolate, Handle<WasmContinuationObject> parent);
DECL_EXTERNAL_POINTER_ACCESSORS(jmpbuf, Address);
DECL_PRINTER(WasmContinuationObject)
using BodyDescriptor = StructBodyDescriptor;
class BodyDescriptor;
private:
friend class Factory;
static Handle<WasmContinuationObject> New(
Isolate* isolate, std::unique_ptr<wasm::StackMemory> stack,
Handle<HeapObject> parent,
AllocationType allocation_type = AllocationType::kYoung);
TQ_OBJECT_CONSTRUCTORS(WasmContinuationObject)
inline void AllocateExternalPointerEntries(Isolate* isolate);
};
// The suspender object provides an API to suspend and resume wasm code using
......
......@@ -100,10 +100,10 @@ extern class WasmIndirectFunctionTable extends Struct {
refs: FixedArray;
}
extern class WasmContinuationObject extends Struct {
extern class WasmContinuationObject extends HeapObject {
stack: Foreign;
jmpbuf: Foreign; // Direct access to the stack's jump buffer.
parent: WasmContinuationObject|Undefined;
jmpbuf: ExternalPointer; // Direct access to the stack's jump buffer.
}
extern class WasmSuspenderObject extends JSObject {
......
This diff is collapsed.
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