diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 748179aa17a0..01a114ca4bc3 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -47,6 +47,7 @@ #include "mozilla/StaticPrefs_browser.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_fission.h" +#include "mozilla/StaticPrefs_javascript.h" #include "mozilla/StaticPrefs_media.h" #include "mozilla/StorageAccessAPIHelper.h" #include "mozilla/TelemetryIPC.h" @@ -2670,6 +2671,14 @@ mozilla::ipc::IPCResult ContentChild::RecvRemoteType( } // else "prealloc" or "web" type -> "Web Content" already set + // Turn off Spectre mitigations in isolated web content processes. + if (StaticPrefs::javascript_options_spectre_disable_for_isolated_content() && + (remoteTypePrefix == FISSION_WEB_REMOTE_TYPE || + remoteTypePrefix == SERVICEWORKER_REMOTE_TYPE || + remoteTypePrefix == WITH_COOP_COEP_REMOTE_TYPE)) { + JS::DisableSpectreMitigationsAfterInit(); + } + // Use the prefix to avoid URIs from Fission isolated processes. CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RemoteType, remoteTypePrefix); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 6e6087955c15..211f3bba0569 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -4225,6 +4225,25 @@ JS_PUBLIC_API bool JS_GetGlobalJitCompilerOption(JSContext* cx, return true; } +JS_PUBLIC_API void JS::DisableSpectreMitigationsAfterInit() { + // This is used to turn off Spectre mitigations in pre-allocated child + // processes used for isolated web content. Assert there's a single runtime + // and cancel off-thread compilations, to ensure we're not racing with any + // compilations. + JSContext* cx = TlsContext.get(); + MOZ_RELEASE_ASSERT(cx); + MOZ_RELEASE_ASSERT(JSRuntime::hasSingleLiveRuntime()); + MOZ_RELEASE_ASSERT(cx->runtime()->wasmInstances.lock()->empty()); + + CancelOffThreadIonCompile(cx->runtime()); + + jit::JitOptions.spectreIndexMasking = false; + jit::JitOptions.spectreObjectMitigations = false; + jit::JitOptions.spectreStringMitigations = false; + jit::JitOptions.spectreValueMasking = false; + jit::JitOptions.spectreJitToCxxCalls = false; +} + /************************************************************************/ #if !defined(STATIC_EXPORTABLE_JS_API) && !defined(STATIC_JS_API) && \ diff --git a/js/src/jsapi.h b/js/src/jsapi.h index a1998a08e5a0..31fe7cec75fc 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -840,6 +840,14 @@ extern JS_PUBLIC_API bool JS_GetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t* valueOut); +namespace JS { + +// Disable all Spectre mitigations for this process after creating the initial +// JSContext. Must be called on this context's thread. +extern JS_PUBLIC_API void DisableSpectreMitigationsAfterInit(); + +}; + /** * Convert a uint32_t index into a jsid. */ diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index be3cf6ea877a..46916d7fe67e 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -924,6 +924,7 @@ struct JSRuntime { public: static bool hasLiveRuntimes() { return liveRuntimesCount > 0; } + static bool hasSingleLiveRuntime() { return liveRuntimesCount == 1; } explicit JSRuntime(JSRuntime* parentRuntime); ~JSRuntime(); diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 879d80ff3658..e10bf731ab7b 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -7106,6 +7106,13 @@ do_not_use_directly: true #endif // !defined(JS_CODEGEN_MIPSXX) +# Separate pref to override the values of the Spectre-related prefs above for +# isolated web content processes, where we don't need these mitigations. +- name: javascript.options.spectre.disable_for_isolated_content + type: bool + value: false + mirror: always + # Whether to use the XPCOM thread pool for JS helper tasks. - name: javascript.options.external_thread_pool type: bool