зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1740263 - Block WASM code generation by CSP. r=lth,jandem
I put the CSP check in the 5 WASM function that V8 also uses: https://source.chromium.org/search?q=IsWasmCodegenAllowed Is there somewhere else we might be generating WASM code? Some kind of caching etc. Differential Revision: https://phabricator.services.mozilla.com/D141978
This commit is contained in:
Родитель
f13a5edf0d
Коммит
f05c922e89
|
@ -66,11 +66,22 @@ extern JS_PUBLIC_API void JS_DropPrincipals(JSContext* cx,
|
|||
// engine when determining, e.g., which stack frames to display in a backtrace.
|
||||
typedef bool (*JSSubsumesOp)(JSPrincipals* first, JSPrincipals* second);
|
||||
|
||||
namespace JS {
|
||||
enum class RuntimeCode { JS, WASM };
|
||||
} // namespace JS
|
||||
|
||||
/*
|
||||
* Used to check if a CSP instance wants to disable eval() and friends.
|
||||
* See JSContext::isRuntimeCodeGenEnabled() in vm/JSContext.cpp.
|
||||
*
|
||||
* `code` is the JavaScript source code passed to eval/Function, but nullptr
|
||||
* for Wasm.
|
||||
*
|
||||
* Returning `false` from this callback will prevent the execution/compilation
|
||||
* of the code.
|
||||
*/
|
||||
typedef bool (*JSCSPEvalChecker)(JSContext* cx, JS::HandleString code);
|
||||
typedef bool (*JSCSPEvalChecker)(JSContext* cx, JS::RuntimeCode kind,
|
||||
JS::HandleString code);
|
||||
|
||||
struct JSSecurityCallbacks {
|
||||
JSCSPEvalChecker contentSecurityPolicyAllows;
|
||||
|
|
|
@ -180,6 +180,7 @@ MSG_DEF(JSMSG_TOO_MANY_ARGUMENTS, 0, JSEXN_RANGEERR, "too many arguments pr
|
|||
// CSP
|
||||
MSG_DEF(JSMSG_CSP_BLOCKED_EVAL, 0, JSEXN_EVALERR, "call to eval() blocked by CSP")
|
||||
MSG_DEF(JSMSG_CSP_BLOCKED_FUNCTION, 0, JSEXN_EVALERR, "call to Function() blocked by CSP")
|
||||
MSG_DEF(JSMSG_CSP_BLOCKED_WASM, 1, JSEXN_WASMCOMPILEERROR, "call to {0}() blocked by CSP")
|
||||
|
||||
// Wrappers
|
||||
MSG_DEF(JSMSG_ACCESSOR_DEF_DENIED, 1, JSEXN_ERR, "Permission denied to define accessor property {0}")
|
||||
|
|
|
@ -238,7 +238,7 @@ static bool EvalKernel(JSContext* cx, HandleValue v, EvalType evalType,
|
|||
|
||||
// Steps 3-4.
|
||||
RootedString str(cx, v.toString());
|
||||
if (!cx->isRuntimeCodeGenEnabled(str)) {
|
||||
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, str)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_CSP_BLOCKED_EVAL);
|
||||
return false;
|
||||
|
|
|
@ -1188,12 +1188,13 @@ bool JSContext::isThrowingDebuggeeWouldRun() {
|
|||
JSEXN_DEBUGGEEWOULDRUN;
|
||||
}
|
||||
|
||||
bool JSContext::isRuntimeCodeGenEnabled(HandleString code) {
|
||||
bool JSContext::isRuntimeCodeGenEnabled(JS::RuntimeCode kind,
|
||||
HandleString code) {
|
||||
// Make sure that the CSP callback is installed and that it permits runtime
|
||||
// code generation.
|
||||
if (JSCSPEvalChecker allows =
|
||||
runtime()->securityCallbacks->contentSecurityPolicyAllows) {
|
||||
return allows(this, code);
|
||||
return allows(this, kind, code);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -819,8 +819,8 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext,
|
|||
inline bool runningWithTrustedPrincipals();
|
||||
|
||||
// Checks if the page's Content-Security-Policy (CSP) allows
|
||||
// runtime code generation "unsafe-eval".
|
||||
bool isRuntimeCodeGenEnabled(js::HandleString code);
|
||||
// runtime code generation "unsafe-eval", or "wasm-unsafe-eval" for Wasm.
|
||||
bool isRuntimeCodeGenEnabled(JS::RuntimeCode kind, js::HandleString code);
|
||||
|
||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
|
||||
size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
|
||||
|
|
|
@ -1621,7 +1621,7 @@ static bool CreateDynamicFunction(JSContext* cx, const CallArgs& args,
|
|||
}
|
||||
|
||||
// Block this call if security callbacks forbid it.
|
||||
if (!cx->isRuntimeCodeGenEnabled(functionText)) {
|
||||
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, functionText)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_CSP_BLOCKED_FUNCTION);
|
||||
return false;
|
||||
|
|
|
@ -1796,6 +1796,12 @@ bool WasmModuleObject::construct(JSContext* cx, unsigned argc, Value* vp) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_CSP_BLOCKED_WASM, "WebAssembly.Module");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!callArgs.requireAtLeast(cx, "WebAssembly.Module", 1)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -4729,6 +4735,12 @@ static bool WebAssembly_compile(JSContext* cx, unsigned argc, Value* vp) {
|
|||
|
||||
CallArgs callArgs = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_CSP_BLOCKED_WASM, "WebAssembly.compile");
|
||||
return RejectWithPendingException(cx, promise, callArgs);
|
||||
}
|
||||
|
||||
auto task = cx->make_unique<CompileBufferTask>(cx, promise);
|
||||
if (!task || !task->init(cx, callArgs.get(1), "WebAssembly.compile")) {
|
||||
return false;
|
||||
|
@ -4790,6 +4802,13 @@ static bool WebAssembly_instantiate(JSContext* cx, unsigned argc, Value* vp) {
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_CSP_BLOCKED_WASM,
|
||||
"WebAssembly.instantiate");
|
||||
return RejectWithPendingException(cx, promise, callArgs);
|
||||
}
|
||||
|
||||
auto task = cx->make_unique<CompileBufferTask>(cx, promise, importObj);
|
||||
if (!task || !task->init(cx, callArgs.get(2), "WebAssembly.instantiate")) {
|
||||
return false;
|
||||
|
@ -5361,6 +5380,13 @@ static bool WebAssembly_compileStreaming(JSContext* cx, unsigned argc,
|
|||
|
||||
CallArgs callArgs = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_CSP_BLOCKED_WASM,
|
||||
"WebAssembly.compileStreaming");
|
||||
return RejectWithPendingException(cx, promise, callArgs);
|
||||
}
|
||||
|
||||
if (!ResolveResponse(cx, callArgs, promise)) {
|
||||
return RejectWithPendingException(cx, promise, callArgs);
|
||||
}
|
||||
|
@ -5384,6 +5410,13 @@ static bool WebAssembly_instantiateStreaming(JSContext* cx, unsigned argc,
|
|||
|
||||
CallArgs callArgs = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_CSP_BLOCKED_WASM,
|
||||
"WebAssembly.instantiateStreaming");
|
||||
return RejectWithPendingException(cx, promise, callArgs);
|
||||
}
|
||||
|
||||
RootedObject firstArg(cx);
|
||||
RootedObject importObj(cx);
|
||||
if (!GetInstantiateArgs(cx, callArgs, &firstArg, &importObj)) {
|
||||
|
|
|
@ -265,6 +265,12 @@ JSObject* Module::createObject(JSContext* cx) const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::WASM, nullptr)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_CSP_BLOCKED_WASM, "WebAssembly.Module");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmModule));
|
||||
return WasmModuleObject::create(cx, *this, proto);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче