Commit 5e44cc79 authored by mtrofin's avatar mtrofin Committed by Commit bot

[wasm] Enable content policy for wasm compilation.

Make wasm code generation (including deserialization) aware of
allow_codegen_callback - if one were set by the host - akin to what we
do for `eval`.

This allows web pages that opt out of unsafe-eval to also opt out of
wasm scenarios.

BUG=v8:5869

Review-Url: https://codereview.chromium.org/2646713002
Cr-Commit-Position: refs/heads/master@{#42519}
parent 26c4a9cc
......@@ -249,9 +249,13 @@ std::unique_ptr<ScriptData> WasmCompiledModuleSerializer::SerializeWasmModule(
MaybeHandle<FixedArray> WasmCompiledModuleSerializer::DeserializeWasmModule(
Isolate* isolate, ScriptData* data, Vector<const byte> wire_bytes) {
MaybeHandle<FixedArray> nothing;
if (!wasm::IsWasmCodegenAllowed(isolate, isolate->native_context())) {
return nothing;
}
SerializedCodeData::SanityCheckResult sanity_check_result =
SerializedCodeData::CHECK_SUCCESS;
MaybeHandle<FixedArray> nothing;
const SerializedCodeData scd = SerializedCodeData::FromCachedData(
isolate, data, 0, &sanity_check_result);
......
......@@ -2183,12 +2183,23 @@ Handle<Script> wasm::GetScript(Handle<JSObject> instance) {
return handle(compiled_module->script());
}
bool wasm::IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) {
return isolate->allow_code_gen_callback() == nullptr ||
isolate->allow_code_gen_callback()(v8::Utils::ToLocal(context));
}
// TODO(clemensh): origin can be inferred from asm_js_script; remove it.
MaybeHandle<WasmModuleObject> wasm::CreateModuleObjectFromBytes(
Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower,
ModuleOrigin origin, Handle<Script> asm_js_script,
Vector<const byte> asm_js_offset_table_bytes) {
MaybeHandle<WasmModuleObject> nothing;
if (!IsWasmCodegenAllowed(isolate, isolate->native_context())) {
thrower->CompileError("Wasm code generation disallowed in this context");
return nothing;
}
ModuleResult result = DecodeWasmModule(isolate, start, end, false, origin);
if (result.failed()) {
if (result.val) delete result.val;
......
......@@ -399,6 +399,9 @@ V8_EXPORT_PRIVATE MaybeHandle<WasmModuleObject> CreateModuleObjectFromBytes(
ModuleOrigin origin, Handle<Script> asm_js_script,
Vector<const byte> asm_offset_table);
V8_EXPORT_PRIVATE bool IsWasmCodegenAllowed(Isolate* isolate,
Handle<Context> context);
V8_EXPORT_PRIVATE Handle<JSArray> GetImports(Isolate* isolate,
Handle<WasmModuleObject> module);
V8_EXPORT_PRIVATE Handle<JSArray> GetExports(Isolate* isolate,
......
......@@ -218,6 +218,18 @@ class WasmSerializationTest {
SetUp();
}
static void BuildWireBytes(Zone* zone, ZoneBuffer* buffer) {
WasmModuleBuilder* builder = new (zone) WasmModuleBuilder(zone);
TestSignatures sigs;
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
byte code[] = {WASM_GET_LOCAL(0), kExprI32Const, 1, kExprI32Add};
EMIT_CODE_WITH_END(f, code);
f->ExportAs(CStrVector(kFunctionName));
builder->WriteTo(*buffer);
}
void ClearSerializedData() {
serialized_bytes_.first = nullptr;
serialized_bytes_.second = 0;
......@@ -279,6 +291,8 @@ class WasmSerializationTest {
TearDown();
}
v8::Isolate* current_isolate_v8() { return current_isolate_v8_; }
private:
static const char* kFunctionName;
......@@ -291,19 +305,9 @@ class WasmSerializationTest {
return serialized_bytes_;
}
v8::Isolate* current_isolate_v8() { return current_isolate_v8_; }
void SetUp() {
WasmModuleBuilder* builder = new (zone()) WasmModuleBuilder(zone());
TestSignatures sigs;
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
byte code[] = {WASM_GET_LOCAL(0), kExprI32Const, 1, kExprI32Add};
EMIT_CODE_WITH_END(f, code);
f->ExportAs(CStrVector(kFunctionName));
ZoneBuffer buffer(&zone_);
builder->WriteTo(buffer);
WasmSerializationTest::BuildWireBytes(zone(), &buffer);
Isolate* serialization_isolate = CcTest::InitIsolateOnce();
ErrorThrower thrower(serialization_isolate, "");
......@@ -419,6 +423,40 @@ TEST(DeserializeWireBytesAndSerializedDataInvalid) {
Cleanup();
}
bool False(v8::Local<v8::Context> context) { 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::CreateModuleObjectFromBytes(
isolate, buffer.begin(), buffer.end(), &thrower,
wasm::ModuleOrigin::kWasmOrigin, Handle<v8::internal::Script>::null(),
Vector<const byte>::empty());
CcTest::isolate()->SetAllowCodeGenerationFromStringsCallback(nullptr);
CHECK(ret.is_null());
CHECK(thrower.error());
}
TEST(BlockWasmCodeGenAtDeserialization) {
WasmSerializationTest test;
{
HandleScope scope(test.current_isolate());
test.current_isolate_v8()->SetAllowCodeGenerationFromStringsCallback(False);
v8::MaybeLocal<v8::WasmCompiledModule> nothing = test.Deserialize();
CHECK(nothing.IsEmpty());
}
Cleanup(test.current_isolate());
Cleanup();
}
TEST(MemorySize) {
{
// Initial memory size is 16, see wasm-module-builder.cc
......
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