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) { ...@@ -2925,7 +2925,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
__ LoadExternalPointerField( __ LoadExternalPointerField(
signature, signature,
FieldOperand(foreign_signature, Foreign::kForeignAddressOffset), FieldOperand(foreign_signature, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag); kForeignForeignAddressTag, kScratchRegister);
foreign_signature = no_reg; foreign_signature = no_reg;
Register return_count = r8; Register return_count = r8;
__ movq(return_count, __ movq(return_count,
...@@ -3256,11 +3256,14 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3256,11 +3256,14 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
thread_in_wasm_flag_addr = no_reg; thread_in_wasm_flag_addr = no_reg;
Register function_entry = function_data; Register function_entry = function_data;
__ movq(function_entry, Register scratch = r12;
MemOperand(function_data, __ LoadExternalPointerField(
wasm::ObjectAccess::ToTagged( function_entry,
WasmExportedFunctionData::kForeignAddressOffset))); FieldOperand(function_data,
WasmExportedFunctionData::kForeignAddressOffset),
kForeignForeignAddressTag, scratch);
function_data = no_reg; function_data = no_reg;
scratch = no_reg;
// We set the indicating value for the GC to the proper one for Wasm call. // We set the indicating value for the GC to the proper one for Wasm call.
constexpr int kWasmCallGCScanSlotCount = 0; constexpr int kWasmCallGCScanSlotCount = 0;
...@@ -4120,7 +4123,7 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) { ...@@ -4120,7 +4123,7 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
__ LoadExternalPointerField( __ LoadExternalPointerField(
api_function_address, api_function_address,
FieldOperand(scratch, Foreign::kForeignAddressOffset), FieldOperand(scratch, Foreign::kForeignAddressOffset),
kForeignForeignAddressTag); kForeignForeignAddressTag, kScratchRegister);
// +3 is to skip prolog, return address and name handle. // +3 is to skip prolog, return address and name handle.
Operand return_value_operand( Operand return_value_operand(
......
...@@ -371,19 +371,27 @@ void TurboAssembler::SaveRegisters(RegList registers) { ...@@ -371,19 +371,27 @@ void TurboAssembler::SaveRegisters(RegList registers) {
} }
} }
void TurboAssembler::LoadExternalPointerField(Register destination, void TurboAssembler::LoadExternalPointerField(
Operand field_operand, Register destination, Operand field_operand, ExternalPointerTag tag,
ExternalPointerTag tag) { Register scratch, IsolateRootLocation isolateRootLocation) {
#ifdef V8_HEAP_SANDBOX #ifdef V8_HEAP_SANDBOX
LoadAddress(kScratchRegister, DCHECK(!field_operand.AddressUsesRegister(scratch));
ExternalReference::external_pointer_table_address(isolate())); if (isolateRootLocation == IsolateRootLocation::kInRootRegister) {
movq(kScratchRegister, DCHECK(root_array_available_);
Operand(kScratchRegister, Internals::kExternalPointerTableBufferOffset)); 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); movl(destination, field_operand);
movq(destination, Operand(kScratchRegister, destination, times_8, 0)); movq(destination, Operand(scratch, destination, times_8, 0));
if (tag != 0) { if (tag != 0) {
movq(kScratchRegister, Immediate64(tag)); movq(scratch, Immediate64(tag));
xorq(destination, kScratchRegister); xorq(destination, scratch);
} }
#else #else
movq(destination, field_operand); movq(destination, field_operand);
......
...@@ -592,10 +592,13 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler { ...@@ -592,10 +592,13 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// V8 Heap sandbox support // V8 Heap sandbox support
enum class IsolateRootLocation { kInScratchRegister, kInRootRegister };
// Loads a field containing off-heap pointer and does necessary decoding // Loads a field containing off-heap pointer and does necessary decoding
// if V8 heap sandbox is enabled. // if V8 heap sandbox is enabled.
void LoadExternalPointerField(Register destination, Operand field_operand, void LoadExternalPointerField(Register destination, Operand field_operand,
ExternalPointerTag tag); ExternalPointerTag tag, Register scratch,
IsolateRootLocation isolateRootLocation =
IsolateRootLocation::kInRootRegister);
protected: protected:
static const int kSmiShift = kSmiTagSize + kSmiShiftSize; static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
......
...@@ -3121,9 +3121,26 @@ Node* WasmGraphBuilder::BuildIndirectCall(uint32_t table_index, ...@@ -3121,9 +3121,26 @@ Node* WasmGraphBuilder::BuildIndirectCall(uint32_t table_index,
Node* WasmGraphBuilder::BuildLoadCallTargetFromExportedFunctionData( Node* WasmGraphBuilder::BuildLoadCallTargetFromExportedFunctionData(
Node* function_data) { 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( return gasm_->LoadFromObject(
MachineType::Pointer(), function_data, MachineType::Pointer(), function_data,
wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset)); wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset));
#endif
} }
// TODO(9495): Support CAPI function refs. // TODO(9495): Support CAPI function refs.
......
...@@ -76,6 +76,13 @@ class IsolateData final { ...@@ -76,6 +76,13 @@ class IsolateData final {
return kBuiltinsTableOffset - kIsolateRootBias; 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() { static constexpr int fast_c_call_caller_fp_offset() {
return kFastCCallCallerFPOffset - kIsolateRootBias; return kFastCCallCallerFPOffset - kIsolateRootBias;
} }
......
...@@ -1421,6 +1421,7 @@ Handle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData( ...@@ -1421,6 +1421,7 @@ Handle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
WasmExportedFunctionData::cast(AllocateRawWithImmortalMap( WasmExportedFunctionData::cast(AllocateRawWithImmortalMap(
map.instance_size(), AllocationType::kOld, map)); map.instance_size(), AllocationType::kOld, map));
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
result.AllocateExternalPointerEntries(isolate());
result.set_foreign_address(isolate(), call_target); result.set_foreign_address(isolate(), call_target);
result.set_ref(*ref); result.set_ref(*ref);
result.set_wrapper_code(*export_wrapper); result.set_wrapper_code(*export_wrapper);
......
...@@ -5688,10 +5688,21 @@ class LiftoffCompiler { ...@@ -5688,10 +5688,21 @@ class LiftoffCompiler {
} }
// Load the call target. // Load the call target.
__ bind(&load_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( __ Load(
target, func_data.gp(), no_reg, target, func_data.gp(), no_reg,
wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset), wasm::ObjectAccess::ToTagged(WasmFunctionData::kForeignAddressOffset),
kPointerLoadType, pinned); kPointerLoadType, pinned);
#endif
LiftoffRegister null_address = temp; LiftoffRegister null_address = temp;
__ LoadConstant(null_address, WasmValue::ForUintPtr(0)); __ LoadConstant(null_address, WasmValue::ForUintPtr(0));
__ emit_cond_jump(kUnequal, &perform_call, kRef, target.gp(), __ 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