Commit afbfddd7 authored by Ben L. Titzer's avatar Ben L. Titzer Committed by Commit Bot

[wasm] Honor AllowCodegenFromStrings() for all WASM compile types.

R=clemensh@chromium.org

Bug: v8:6756
Change-Id: I3b25b89f3ead5c856be5c7ba3c7c236e595ce8de
Reviewed-on: https://chromium-review.googlesource.com/695524
Commit-Queue: Ben Titzer <titzer@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48333}
parent 23f761d3
......@@ -7917,7 +7917,10 @@ MaybeLocal<WasmCompiledModule> WasmCompiledModule::Compile(Isolate* isolate,
const uint8_t* start,
size_t length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::wasm::ErrorThrower thrower(i_isolate, "WasmCompiledModule::Deserialize()");
i::wasm::ErrorThrower thrower(i_isolate, "WasmCompiledModule::Compile()");
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
return MaybeLocal<WasmCompiledModule>();
}
i::MaybeHandle<i::JSObject> maybe_compiled = i::wasm::SyncCompile(
i_isolate, &thrower, i::wasm::ModuleWireBytes(start, start + length));
if (maybe_compiled.is_null()) return MaybeLocal<WasmCompiledModule>();
......
......@@ -852,10 +852,15 @@ bool DisallowCodegenFromStringsCallback(v8::Local<v8::Context> context,
RUNTIME_FUNCTION(Runtime_DisallowCodegenFromStrings) {
SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length());
DCHECK_EQ(1, args.length());
CONVERT_BOOLEAN_ARG_CHECKED(flag, 0);
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
v8_isolate->SetAllowCodeGenerationFromStringsCallback(
DisallowCodegenFromStringsCallback);
if (flag) {
v8_isolate->SetAllowCodeGenerationFromStringsCallback(
DisallowCodegenFromStringsCallback);
} else {
v8_isolate->SetAllowCodeGenerationFromStringsCallback(nullptr);
}
return isolate->heap()->undefined_value();
}
......
......@@ -613,7 +613,7 @@ namespace internal {
F(IsWasmCode, 1, 1) \
F(IsWasmTrapHandlerEnabled, 0, 1) \
F(GetWasmRecoveredTrapCount, 0, 1) \
F(DisallowCodegenFromStrings, 0, 1) \
F(DisallowCodegenFromStrings, 1, 1) \
F(ValidateWasmInstancesChain, 2, 1) \
F(ValidateWasmModuleState, 1, 1) \
F(ValidateWasmOrphanedInstance, 1, 1) \
......
......@@ -512,11 +512,6 @@ MaybeHandle<WasmModuleObject> SyncCompileTranslatedAsmJs(
MaybeHandle<WasmModuleObject> SyncCompile(Isolate* isolate,
ErrorThrower* thrower,
const ModuleWireBytes& bytes) {
if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) {
thrower->CompileError("Wasm code generation disallowed in this context");
return {};
}
// TODO(titzer): only make a copy of the bytes if SharedArrayBuffer
std::unique_ptr<byte[]> copy(new byte[bytes.length()]);
memcpy(copy.get(), bytes.start(), bytes.length());
......
......@@ -124,6 +124,22 @@ void WebAssemblyCompileStreaming(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
// Manually create a promise and reject it.
Local<Context> context = isolate->GetCurrentContext();
ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context));
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
return_value.Set(resolver->GetPromise());
i::wasm::ScheduledErrorThrower thrower(i_isolate,
"WebAssembly.compileStreaming()");
thrower.CompileError("Wasm code generation disallowed by embedder");
auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
CHECK_IMPLIES(!maybe.FromMaybe(false),
i_isolate->has_scheduled_exception());
return;
}
MicrotasksScope runs_microtasks(isolate, MicrotasksScope::kRunMicrotasks);
DCHECK_NOT_NULL(i_isolate->wasm_compile_streaming_callback());
i_isolate->wasm_compile_streaming_callback()(args);
......@@ -138,6 +154,10 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(isolate);
i::wasm::ScheduledErrorThrower thrower(i_isolate, "WebAssembly.compile()");
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
thrower.CompileError("Wasm code generation disallowed by embedder");
}
Local<Context> context = isolate->GetCurrentContext();
ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context));
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
......@@ -182,6 +202,11 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(isolate);
i::wasm::ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Module()");
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
thrower.CompileError("Wasm code generation disallowed by embedder");
return;
}
auto bytes = GetFirstArgumentAsBytes(args, &thrower);
if (thrower.error()) {
......
......@@ -508,23 +508,6 @@ bool False(v8::Local<v8::Context> context, v8::Local<v8::String> source) {
return false;
}
TEST(BlockWasmCodeGen) {
v8::internal::AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
ZoneBuffer buffer(&zone);
WasmSerializationTest::BuildWireBytes(&zone, &buffer);
Isolate* isolate = CcTest::InitIsolateOnce();
HandleScope scope(isolate);
testing::SetupIsolateForWasmModule(isolate);
CcTest::isolate()->SetAllowCodeGenerationFromStringsCallback(False);
ErrorThrower thrower(isolate, "block codegen");
MaybeHandle<WasmModuleObject> ret = wasm::SyncCompile(
isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()));
CHECK(ret.is_null());
CHECK(thrower.error());
}
TEST(BlockWasmCodeGenAtDeserialization) {
WasmSerializationTest test;
{
......
......@@ -550,7 +550,7 @@ var failWithMessage;
try {
success(result);
} catch (e) {
failWithMessage(e);
failWithMessage(String(e));
}
},
result => {
......
......@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --validate-asm --allow-natives-syntax
// Flags: --noexpose-wasm --validate-asm --allow-natives-syntax
// NOTE: This is in it's own file because it calls %DisallowCodegenFromStrings,
// NOTE: This is in its own file because it calls %DisallowCodegenFromStrings,
// which messes with the isolate's state.
(function testAsmWithWasmOff() {
%DisallowCodegenFromStrings();
%DisallowCodegenFromStrings(true);
function Module() {
'use asm';
function foo() {
......
// Copyright 2017 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: --expose-wasm --allow-natives-syntax
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
let kReturnValue = 19;
let buffer = (function CreateBuffer() {
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true);
builder.addFunction('main', kSig_i_v)
.addBody([kExprI32Const, kReturnValue])
.exportFunc();
return builder.toBuffer();
})();
%DisallowCodegenFromStrings(true);
async function SyncTestOk() {
print('sync module compile (ok)...');
%DisallowCodegenFromStrings(false);
let module = new WebAssembly.Module(buffer);
assertInstanceof(module, WebAssembly.Module);
}
async function SyncTestFail() {
print('sync module compile (fail)...');
%DisallowCodegenFromStrings(true);
try {
let module = new WebAssembly.Module(buffer);
assertUnreachable();
} catch (e) {
print(" " + e);
assertInstanceof(e, WebAssembly.CompileError);
}
}
async function AsyncTestOk() {
print('async module compile (ok)...');
%DisallowCodegenFromStrings(false);
let promise = WebAssembly.compile(buffer);
assertPromiseResult(
promise, module => assertInstanceof(module, WebAssembly.Module));
}
async function AsyncTestFail() {
print('async module compile (fail)...');
%DisallowCodegenFromStrings(true);
try {
let m = await WebAssembly.compile(buffer);
assertUnreachable();
} catch (e) {
print(" " + e);
assertInstanceof(e, WebAssembly.CompileError);
}
}
async function StreamingTestOk() {
print('streaming module compile (ok)...');
// TODO(titzer): compileStreaming must be supplied by embedder.
// (and it takes a response, not a buffer)
%DisallowCodegenFromStrings(false);
if ("Function" != typeof WebAssembly.compileStreaming) {
print(" no embedder for streaming compilation");
return;
}
let promise = WebAssembly.compileStreaming(buffer);
assertPromiseResult(
promise, module => assertInstanceof(module, WebAssembly.Module));
}
async function StreamingTestFail() {
print('streaming module compile (fail)...');
%DisallowCodegenFromStrings(true);
// TODO(titzer): compileStreaming must be supplied by embedder.
// (and it takes a response, not a buffer)
if ("Function" != typeof WebAssembly.compileStreaming) {
print(" no embedder for streaming compilation");
return;
}
try {
let m = await WebAssembly.compileStreaming(buffer);
assertUnreachable();
} catch (e) {
print(" " + e);
assertInstanceof(e, WebAssembly.CompileError);
}
}
async function RunAll() {
await SyncTestOk();
await SyncTestFail();
await AsyncTestOk();
await AsyncTestFail();
await StreamingTestOk();
await StreamingTestFail();
}
assertPromiseResult(RunAll());
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