Commit 883db26e authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Update signature map on indirect calls

The code was already there, but there was a bug in it: Because of the
missing reference, we were only updating a *copy* of the signature map,
hence the update had no effect.
This intentially is a minimal CL, in order to allow for easy
backmerging.
More mitigations and tests are coming in a separate CL.

R=titzer@chromium.org

Change-Id: Ifb462093f4b8f4d5380b6774636537c67c2b676c
Reviewed-on: https://chromium-review.googlesource.com/570278Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46664}
parent 527f541f
......@@ -2321,7 +2321,7 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t sig_index, Node** args,
Int32Constant(kPointerSizeLog2)),
Int32Constant(fixed_offset)),
*effect_, *control_);
auto map = const_cast<wasm::SignatureMap&>(
auto& map = const_cast<wasm::SignatureMap&>(
module_->module->function_tables[0].map);
Node* sig_match = graph()->NewNode(
machine->WordEqual(), load_sig,
......
......@@ -388,7 +388,7 @@ void wasm::UpdateDispatchTables(Isolate* isolate,
// a dangling pointer in the signature map.
Handle<WasmInstanceObject> instance(
WasmInstanceObject::cast(dispatch_tables->get(i)), isolate);
auto func_table = instance->module()->function_tables[table_index];
auto& func_table = instance->module()->function_tables[table_index];
uint32_t sig_index = func_table.map.FindOrInsert(function->sig);
signature_table->set(index, Smi::FromInt(static_cast<int>(sig_index)));
function_table->set(index, *code);
......
......@@ -23,7 +23,7 @@ let instance0 = new WebAssembly.Instance(module0);
let builder1 = new WasmModuleBuilder();
builder1.setName('module_1');
builder1.addFunction('main', kSig_i_i).addBody([0]);
builder1.addFunction('main', kSig_i_v).addBody([kExprUnreachable]);
builder1.addImportedTable('z', 'table');
builder1.addFunctionTableInit(0, false, [0], true);
let module1 = new WebAssembly.Module(builder1.toBuffer());
......
......@@ -568,3 +568,37 @@ function js_div(a, b) { return (a / b) | 0; }
}
}
})();
(function InitImportedTableSignatureMismatch() {
// instance0 exports a function table and a main function which indirectly
// calls a function from the table.
let builder0 = new WasmModuleBuilder();
builder0.setName('module_0');
let sig_index = builder0.addType(kSig_i_v);
builder0.addFunction('main', kSig_i_i)
.addBody([
kExprGetLocal, 0, // -
kExprCallIndirect, sig_index, kTableZero
])
.exportAs('main');
builder0.setFunctionTableLength(3);
builder0.addExportOfKind('table', kExternalTable);
let module0 = new WebAssembly.Module(builder0.toBuffer());
let instance0 = new WebAssembly.Instance(module0);
// instance1 imports the table and adds a function to it.
let builder1 = new WasmModuleBuilder();
builder1.setName('module_1');
builder1.addFunction('f', kSig_i_i).addBody([kExprGetLocal, 0]);
builder1.addImportedTable('z', 'table');
builder1.addFunctionTableInit(0, false, [0], true);
let module1 = new WebAssembly.Module(builder1.toBuffer());
let instance1 =
new WebAssembly.Instance(module1, {z: {table: instance0.exports.table}});
// Calling the main method on instance0 should fail, because the signature of
// the added function does not match.
assertThrows(
() => instance0.exports.main(0), WebAssembly.RuntimeError,
/signature mismatch/);
})();
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