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

[sandbox][x64] Fix heap sandbox after wasm changes

The heap sandbox mode was broken after the introduction of
WasmExportedFunctionData objects due to missing external pointer
handling. This CL implements that.

Bug: v8:10391
Change-Id: Icc6a2944b68f475c40b6431ab26400c35083b7bb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2862771Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Samuel Groß <saelo@google.com>
Cr-Commit-Position: refs/heads/master@{#74415}
parent 5bdfd84e
......@@ -2925,7 +2925,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
__ LoadExternalPointerField(
signature,
FieldOperand(foreign_signature, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag);
kForeignForeignAddressTag, kScratchRegister);
foreign_signature = no_reg;
Register return_count = r8;
__ movq(return_count,
......@@ -3256,11 +3256,14 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
thread_in_wasm_flag_addr = no_reg;
Register function_entry = function_data;
__ movq(function_entry,
MemOperand(function_data,
wasm::ObjectAccess::ToTagged(
WasmExportedFunctionData::kForeignAddressOffset)));
Register scratch = r12;
__ LoadExternalPointerField(
function_entry,
FieldOperand(function_data,
WasmExportedFunctionData::kForeignAddressOffset),
kForeignForeignAddressTag, scratch);
function_data = no_reg;
scratch = no_reg;
// We set the indicating value for the GC to the proper one for Wasm call.
constexpr int kWasmCallGCScanSlotCount = 0;
......@@ -4120,7 +4123,7 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
__ LoadExternalPointerField(
api_function_address,
FieldOperand(scratch, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag);
kForeignForeignAddressTag, kScratchRegister);
// +3 is to skip prolog, return address and name handle.
Operand return_value_operand(
......
......@@ -371,19 +371,27 @@ void TurboAssembler::SaveRegisters(RegList registers) {
}
}
void TurboAssembler::LoadExternalPointerField(Register destination,
Operand field_operand,
ExternalPointerTag tag) {
void TurboAssembler::LoadExternalPointerField(
Register destination, Operand field_operand, ExternalPointerTag tag,
Register scratch, IsolateRootLocation isolateRootLocation) {
#ifdef V8_HEAP_SANDBOX
LoadAddress(kScratchRegister,
ExternalReference::external_pointer_table_address(isolate()));
movq(kScratchRegister,
Operand(kScratchRegister, Internals::kExternalPointerTableBufferOffset));
DCHECK(!field_operand.AddressUsesRegister(scratch));
if (isolateRootLocation == IsolateRootLocation::kInRootRegister) {
DCHECK(root_array_available_);
movq(scratch, Operand(kRootRegister,
IsolateData::external_pointer_table_offset() +
Internals::kExternalPointerTableBufferOffset));
} else {
DCHECK(isolateRootLocation == IsolateRootLocation::kInScratchRegister);
movq(scratch,
Operand(scratch, IsolateData::external_pointer_table_offset() +
Internals::kExternalPointerTableBufferOffset));
}
movl(destination, field_operand);
movq(destination, Operand(kScratchRegister, destination, times_8, 0));
movq(destination, Operand(scratch, destination, times_8, 0));
if (tag != 0) {
movq(kScratchRegister, Immediate64(tag));
xorq(destination, kScratchRegister);
movq(scratch, Immediate64(tag));
xorq(destination, scratch);
}
#else
movq(destination, field_operand);
......
......@@ -592,10 +592,13 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
// ---------------------------------------------------------------------------
// V8 Heap sandbox support
enum class IsolateRootLocation { kInScratchRegister, kInRootRegister };
// Loads a field containing off-heap pointer and does necessary decoding
// if V8 heap sandbox is enabled.
void LoadExternalPointerField(Register destination, Operand field_operand,
ExternalPointerTag tag);
ExternalPointerTag tag, Register scratch,
IsolateRootLocation isolateRootLocation =
IsolateRootLocation::kInRootRegister);
protected:
static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
......
......@@ -3121,9 +3121,26 @@ Node* WasmGraphBuilder::BuildIndirectCall(uint32_t table_index,
Node* WasmGraphBuilder::BuildLoadCallTargetFromExportedFunctionData(
Node* function_data) {
// TODO(saelo) move this code into a common LoadExternalPointer routine?
#ifdef V8_HEAP_SANDBOX
Node* index = gasm_->LoadFromObject(
MachineType::Pointer(), function_data,
wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset));
Node* isolate_root = BuildLoadIsolateRoot();
Node* table =
gasm_->LoadFromObject(MachineType::Pointer(), isolate_root,
IsolateData::external_pointer_table_offset() +
Internals::kExternalPointerTableBufferOffset);
Node* offset = gasm_->Int32Mul(index, gasm_->Int32Constant(8));
Node* decoded_ptr = gasm_->Load(MachineType::Pointer(), table, offset);
Node* tag = gasm_->IntPtrConstant(kForeignForeignAddressTag);
return gasm_->WordXor(decoded_ptr, tag);
#else
return gasm_->LoadFromObject(
MachineType::Pointer(), function_data,
wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset));
#endif
}
// TODO(9495): Support CAPI function refs.
......
......@@ -76,6 +76,13 @@ class IsolateData final {
return kBuiltinsTableOffset - kIsolateRootBias;
}
// Root-register-relative offset of the external pointer table.
#ifdef V8_HEAP_SANDBOX
static constexpr int external_pointer_table_offset() {
return kExternalPointerTableOffset - kIsolateRootBias;
}
#endif
static constexpr int fast_c_call_caller_fp_offset() {
return kFastCCallCallerFPOffset - kIsolateRootBias;
}
......
......@@ -1421,6 +1421,7 @@ Handle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
WasmExportedFunctionData::cast(AllocateRawWithImmortalMap(
map.instance_size(), AllocationType::kOld, map));
DisallowGarbageCollection no_gc;
result.AllocateExternalPointerEntries(isolate());
result.set_foreign_address(isolate(), call_target);
result.set_ref(*ref);
result.set_wrapper_code(*export_wrapper);
......
......@@ -5688,10 +5688,21 @@ class LiftoffCompiler {
}
// Load the call target.
__ bind(&load_target);
#ifdef V8_HEAP_SANDBOX
LOAD_INSTANCE_FIELD(temp.gp(), IsolateRoot, kSystemPointerSize, pinned);
__ LoadExternalPointerField(
target.gp(),
FieldOperand(func_data.gp(), WasmFunctionData::kForeignAddressOffset),
kForeignForeignAddressTag, temp.gp(),
TurboAssembler::IsolateRootLocation::kInScratchRegister);
#else
__ Load(
target, func_data.gp(), no_reg,
wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset),
kPointerLoadType, pinned);
#endif
LiftoffRegister null_address = temp;
__ LoadConstant(null_address, WasmValue::ForUintPtr(0));
__ emit_cond_jump(kUnequal, &perform_call, kRef, target.gp(),
......
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