From f257ed51adc1eb7644f74793bc388da9169a59b8 Mon Sep 17 00:00:00 2001 From: Matthias Liedtke Date: Wed, 26 Oct 2022 18:08:16 +0200 Subject: [PATCH] [wasm-gc] Fix missing instance type check for concrete casts from any The newly added cast instructions can cast from {any} type, resulting in the cast instructions with a concrete type having to also check if an object actually is a wasm object (and not e.g. a JS object) before loading the WasmTypeInfo from its map. Bug: v8:7748 Change-Id: Ia9c1d35fb9de016af4984883f1374fd5238ce6ea Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3981858 Reviewed-by: Manos Koukoutos Commit-Queue: Matthias Liedtke Cr-Commit-Position: refs/heads/main@{#83945} --- src/compiler/wasm-gc-lowering.cc | 13 +++++++++++++ src/wasm/baseline/liftoff-compiler.cc | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/compiler/wasm-gc-lowering.cc b/src/compiler/wasm-gc-lowering.cc index 6323bf44bd..9d9caae767 100644 --- a/src/compiler/wasm-gc-lowering.cc +++ b/src/compiler/wasm-gc-lowering.cc @@ -113,6 +113,13 @@ Reduction WasmGCLowering::ReduceWasmTypeCheck(Node* node) { gasm_.GotoIf(gasm_.TaggedEqual(map, rtt), &end_label, BranchHint::kTrue, gasm_.Int32Constant(1)); + // Check if map instance type identifies a wasm object. + if (config.from.is_reference_to(wasm::HeapType::kAny)) { + Node* is_wasm_obj = gasm_.IsDataRefMap(map); + gasm_.GotoIfNot(is_wasm_obj, &end_label, BranchHint::kTrue, + gasm_.Int32Constant(0)); + } + Node* type_info = gasm_.LoadWasmTypeInfo(map); DCHECK_GE(rtt_depth, 0); // If the depth of the rtt is known to be less that the minimum supertype @@ -179,6 +186,12 @@ Reduction WasmGCLowering::ReduceWasmTypeCast(Node* node) { // speedups. gasm_.GotoIf(gasm_.TaggedEqual(map, rtt), &end_label, BranchHint::kTrue); + // Check if map instance type identifies a wasm object. + if (config.from.is_reference_to(wasm::HeapType::kAny)) { + Node* is_wasm_obj = gasm_.IsDataRefMap(map); + gasm_.TrapUnless(is_wasm_obj, TrapId::kTrapIllegalCast); + } + Node* type_info = gasm_.LoadWasmTypeInfo(map); DCHECK_GE(rtt_depth, 0); // If the depth of the rtt is known to be less that the minimum supertype diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index e64f7ccf32..9502a0af32 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -5876,6 +5876,17 @@ class LiftoffCompiler { // rtt. __ emit_cond_jump(kEqual, &match, rtt_type.kind(), tmp1, rtt_reg, frozen); + if (obj_type.is_reference_to(HeapType::kAny)) { + // Check for map being a map for a wasm object (struct, array, func). + __ Load(LiftoffRegister(scratch2), tmp1, no_reg, + wasm::ObjectAccess::ToTagged(Map::kInstanceTypeOffset), + LoadType::kI32Load16U); + __ emit_i32_subi(scratch2, scratch2, FIRST_WASM_OBJECT_TYPE); + __ emit_i32_cond_jumpi(kUnsignedGreaterThan, no_match, scratch2, + LAST_WASM_OBJECT_TYPE - FIRST_WASM_OBJECT_TYPE, + frozen); + } + // Constant-time subtyping check: load exactly one candidate RTT from the // supertypes list. // Step 1: load the WasmTypeInfo into {tmp1}.