Commit 9318e064 authored by Paul Semel's avatar Paul Semel Committed by V8 LUCI CQ

[wasm][csp] Add support for `SetErrorMessageForWasmCodeGeneration`

This adds support for a better error message when wasm code generation
is not allowed. Chrome will use this new API here: https://chromium-review.googlesource.com/c/chromium/src/+/3738183.

Bug: chromium:1255058
Change-Id: I8c9639c4fd08d1dff0a5a2fc6a8360f40a7e140e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3740721Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Paul Semel <paulsemel@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81573}
parent 8aa97d5a
......@@ -244,6 +244,12 @@ class V8_EXPORT Context : public Data {
*/
void SetErrorMessageForCodeGenerationFromStrings(Local<String> message);
/**
* Sets the error description for the exception that is thrown when
* wasm code generation is not allowed.
*/
void SetErrorMessageForWasmCodeGeneration(Local<String> message);
/**
* Return data that was previously attached to the context snapshot via
* SnapshotCreator, and removes the reference to it.
......
......@@ -6557,6 +6557,12 @@ void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
context->set_error_message_for_code_gen_from_strings(*error_handle);
}
void Context::SetErrorMessageForWasmCodeGeneration(Local<String> error) {
i::Handle<i::Context> context = Utils::OpenHandle(this);
i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
context->set_error_message_for_wasm_code_gen(*error_handle);
}
void Context::SetAbortScriptExecution(
Context::AbortScriptExecutionCallback callback) {
i::Handle<i::Context> context = Utils::OpenHandle(this);
......
......@@ -441,6 +441,14 @@ Handle<Object> Context::ErrorMessageForCodeGenerationFromStrings() {
"Code generation from strings disallowed for this context");
}
Handle<Object> Context::ErrorMessageForWasmCodeGeneration() {
Isolate* isolate = GetIsolate();
Handle<Object> result(error_message_for_wasm_code_gen(), isolate);
if (!result->IsUndefined(isolate)) return result;
return isolate->factory()->NewStringFromStaticChars(
"Wasm code generation disallowed by embedder");
}
#define COMPARE_NAME(index, type, name) \
if (string->IsOneByteEqualTo(base::StaticCharVector(#name))) return index;
......
......@@ -113,6 +113,8 @@ enum ContextLookupFlags {
V(EMPTY_FUNCTION_INDEX, JSFunction, empty_function) \
V(ERROR_MESSAGE_FOR_CODE_GEN_FROM_STRINGS_INDEX, Object, \
error_message_for_code_gen_from_strings) \
V(ERROR_MESSAGE_FOR_WASM_CODE_GEN_INDEX, Object, \
error_message_for_wasm_code_gen) \
V(ERRORS_THROWN_INDEX, Smi, errors_thrown) \
V(EXTRAS_BINDING_OBJECT_INDEX, JSObject, extras_binding_object) \
V(FAST_ALIASED_ARGUMENTS_MAP_INDEX, Map, fast_aliased_arguments_map) \
......@@ -630,6 +632,7 @@ class Context : public TorqueGeneratedContext<Context, HeapObject> {
inline bool HasSameSecurityTokenAs(Context that) const;
Handle<Object> ErrorMessageForCodeGenerationFromStrings();
Handle<Object> ErrorMessageForWasmCodeGeneration();
static int IntrinsicIndexForName(Handle<String> name);
static int IntrinsicIndexForName(const unsigned char* name, int length);
......
......@@ -524,8 +524,11 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
HandleScope scope(isolate);
ScheduledErrorThrower thrower(i_isolate, kAPIMethodName);
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
thrower.CompileError("Wasm code generation disallowed by embedder");
i::Handle<i::Context> native_context = i_isolate->native_context();
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, native_context)) {
i::Handle<i::String> error =
i::wasm::ErrorStringForCodegen(i_isolate, native_context);
thrower.CompileError("%s", error->ToCString().get());
}
Local<Context> context = isolate->GetCurrentContext();
......@@ -601,8 +604,11 @@ void WebAssemblyCompileStreaming(
auto resolver = std::make_shared<AsyncCompilationResolver>(isolate, context,
promise_resolver);
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
thrower.CompileError("Wasm code generation disallowed by embedder");
i::Handle<i::Context> native_context = i_isolate->native_context();
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, native_context)) {
i::Handle<i::String> error =
i::wasm::ErrorStringForCodegen(i_isolate, native_context);
thrower.CompileError("%s", error->ToCString().get());
resolver->OnCompilationFailed(thrower.Reify());
return;
}
......@@ -710,8 +716,11 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
thrower.TypeError("WebAssembly.Module must be invoked with 'new'");
return;
}
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
thrower.CompileError("Wasm code generation disallowed by embedder");
i::Handle<i::Context> native_context = i_isolate->native_context();
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, native_context)) {
i::Handle<i::String> error =
i::wasm::ErrorStringForCodegen(i_isolate, native_context);
thrower.CompileError("%s", error->ToCString().get());
return;
}
......@@ -894,8 +903,11 @@ void WebAssemblyInstantiateStreaming(
std::unique_ptr<i::wasm::InstantiationResultResolver> resolver(
new InstantiateModuleResultResolver(isolate, context, result_resolver));
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
thrower.CompileError("Wasm code generation disallowed by embedder");
i::Handle<i::Context> native_context = i_isolate->native_context();
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, native_context)) {
i::Handle<i::String> error =
i::wasm::ErrorStringForCodegen(i_isolate, native_context);
thrower.CompileError("%s", error->ToCString().get());
resolver->OnInstantiationFailed(thrower.Reify());
return;
}
......@@ -1019,8 +1031,11 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
// The first parameter is a buffer source, we have to check if we are allowed
// to compile it.
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
thrower.CompileError("Wasm code generation disallowed by embedder");
i::Handle<i::Context> native_context = i_isolate->native_context();
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, native_context)) {
i::Handle<i::String> error =
i::wasm::ErrorStringForCodegen(i_isolate, native_context);
thrower.CompileError("%s", error->ToCString().get());
compilation_resolver->OnCompilationFailed(thrower.Reify());
return;
}
......
......@@ -255,6 +255,13 @@ bool IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context) {
v8::Utils::ToLocal(isolate->factory()->empty_string()));
}
Handle<String> ErrorStringForCodegen(Isolate* isolate,
Handle<Context> context) {
Handle<Object> error = context->ErrorMessageForWasmCodeGeneration();
DCHECK(!error.is_null());
return Object::NoSideEffectsToString(isolate, error);
}
namespace {
// Converts the given {type} into a string representation that can be used in
......
......@@ -714,6 +714,8 @@ std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name);
V8_EXPORT_PRIVATE bool IsWasmCodegenAllowed(Isolate* isolate,
Handle<Context> context);
V8_EXPORT_PRIVATE Handle<String> ErrorStringForCodegen(Isolate* isolate,
Handle<Context> context);
Handle<JSObject> GetTypeForFunction(Isolate* isolate, const FunctionSig* sig,
bool for_exception = false);
......
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