[wasm][interpreter] Check signature before getting code

On indirect function calls, if the corresponding table entry is empty,
we cannot call {GetCodeFromStartAddress}. In that case, the signature
check will fail anyway, so perform the signature check first, and only
get the code object if the check succeeds.

R=mstarzinger@chromium.org

Bug: chromium:831463
Change-Id: Iead949e4c12502b1a2a3949db2dabab4a184a1e7
Reviewed-on: https://chromium-review.googlesource.com/1005005
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52542}
This commit is contained in:
Clemens Hammacher 2018-04-11 10:37:51 +02:00 committed by Commit Bot
parent 3953955aab
commit be1a231625
2 changed files with 26 additions and 4 deletions

View File

@ -2408,14 +2408,14 @@ class ThreadImpl {
Handle<WasmInstanceObject> instance;
{
IndirectFunctionTableEntry entry(*instance_object_, entry_index);
instance = handle(entry.instance(), isolate);
code = isolate->wasm_engine()->code_manager()->GetCodeFromStartAddress(
entry.target());
// Signature check.
if (entry.sig_id() != static_cast<int32_t>(expected_sig_id)) {
return {ExternalCallResult::SIGNATURE_MISMATCH};
}
instance = handle(entry.instance(), isolate);
code = isolate->wasm_engine()->code_manager()->GetCodeFromStartAddress(
entry.target());
}
// Call either an internal or external WASM function.

View File

@ -0,0 +1,22 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --wasm-interpret-all
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
const builder = new WasmModuleBuilder();
const sig = builder.addType(kSig_i_i);
builder.addFunction('call', kSig_i_v)
.addBody([
kExprI32Const, 0, kExprI32Const, 0, kExprCallIndirect, sig, kTableZero
])
.exportAs('call');
builder.addImportedTable('imp', 'table');
const table = new WebAssembly.Table({element: 'anyfunc', initial: 1});
const instance = builder.instantiate({imp: {table: table}});
assertThrows(
() => instance.exports.call(), WebAssembly.RuntimeError,
/function signature mismatch/);