diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 81c0471ede49..6b6fba7edc79 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -79,6 +79,7 @@ #include "mozilla/Components.h" #include "mozilla/Sprintf.h" #include "mozilla/StaticPrefs_dom.h" +#include "mozilla/StaticPrefs_fission.h" #include "mozilla/StaticPrefs_media.h" #include "mozilla/StaticPrefs_widget.h" #include "mozilla/StyleSheet.h" @@ -647,6 +648,23 @@ static const char* sObserverTopics[] = { "network:socket-process-crashed", }; +static const char kFissionEnforceBlockList[] = + "fission.enforceBlocklistedPrefsInSubprocesses"; +static const char kFissionOmitBlockListValues[] = + "fission.omitBlocklistedPrefsInSubprocesses"; + +static void OnFissionBlocklistPrefChange(const char* aPref, void* aData) { + if (strcmp(aPref, kFissionEnforceBlockList) == 0) { + sCrashOnBlocklistedPref = + StaticPrefs::fission_enforceBlocklistedPrefsInSubprocesses(); + } else if (strcmp(aPref, kFissionOmitBlockListValues) == 0) { + sOmitBlocklistedPrefValues = + StaticPrefs::fission_omitBlocklistedPrefsInSubprocesses(); + } else { + MOZ_CRASH("Unknown pref passed to callback"); + } +} + // PreallocateProcess is called by the PreallocatedProcessManager. // ContentParent then takes this process back within GetNewOrUsedBrowserProcess. /*static*/ already_AddRefed @@ -676,6 +694,11 @@ void ContentParent::StartUp() { BackgroundChild::Startup(); ClientManager::Startup(); + Preferences::RegisterCallbackAndCall(&OnFissionBlocklistPrefChange, + kFissionEnforceBlockList); + Preferences::RegisterCallbackAndCall(&OnFissionBlocklistPrefChange, + kFissionOmitBlockListValues); + #if defined(XP_LINUX) && defined(MOZ_SANDBOX) sSandboxBrokerPolicyFactory = MakeUnique(); #endif diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index 57498a556fe2..b713d5a0c199 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -517,7 +517,7 @@ class Pref { MOZ_ASSERT(aKind == PrefValueKind::Default ? HasDefaultValue() : HasUserValue()); - if (!XRE_IsParentProcess() && + if (!XRE_IsParentProcess() && sCrashOnBlocklistedPref && ShouldSanitizePreference(Name(), XRE_IsContentProcess())) { MOZ_CRASH_UNSAFE_PRINTF( "Should not access the preference '%s' in the Content Processes", @@ -533,7 +533,7 @@ class Pref { MOZ_ASSERT(aKind == PrefValueKind::Default ? HasDefaultValue() : HasUserValue()); - if (!XRE_IsParentProcess() && + if (!XRE_IsParentProcess() && sCrashOnBlocklistedPref && ShouldSanitizePreference(Name(), XRE_IsContentProcess())) { MOZ_CRASH_UNSAFE_PRINTF( "Should not access the preference '%s' in the Content Processes", @@ -550,7 +550,7 @@ class Pref { MOZ_ASSERT(aKind == PrefValueKind::Default ? HasDefaultValue() : HasUserValue()); - if (!XRE_IsParentProcess() && + if (!XRE_IsParentProcess() && sCrashOnBlocklistedPref && ShouldSanitizePreference(Name(), XRE_IsContentProcess())) { MOZ_CRASH_UNSAFE_PRINTF( "Should not access the preference '%s' in the Content Processes", @@ -583,7 +583,8 @@ class Pref { aDomPref->defaultValue() = Nothing(); } - if (mHasUserValue && !aDomPref->isSanitized()) { + if (mHasUserValue && + !(aDomPref->isSanitized() && sOmitBlocklistedPrefValues)) { aDomPref->userValue() = Some(dom::PrefValue()); mUserValue.ToDomPrefValue(Type(), &aDomPref->userValue().ref()); } else { @@ -591,7 +592,8 @@ class Pref { } MOZ_ASSERT(aDomPref->defaultValue().isNothing() || - aDomPref->userValue().isNothing() || mIsSanitized || + aDomPref->userValue().isNothing() || + (mIsSanitized && sOmitBlocklistedPrefValues) || (aDomPref->defaultValue().ref().type() == aDomPref->userValue().ref().type())); } @@ -829,7 +831,7 @@ class Pref { } aStr.Append(':'); - if (mHasUserValue && !aSanitizeUserValue) { + if (mHasUserValue && !(aSanitizeUserValue && sOmitBlocklistedPrefValues)) { mUserValue.SerializeAndAppend(Type(), aStr); } aStr.Append('\n'); @@ -5766,6 +5768,9 @@ bool ShouldSanitizePreference(const char* aPref, return Preferences::IsSanitized(aPref); } +Atomic sOmitBlocklistedPrefValues(false); +Atomic sCrashOnBlocklistedPref(false); + } // namespace mozilla // This file contains the C wrappers for the C++ static pref getters, as used diff --git a/modules/libpref/Preferences.h b/modules/libpref/Preferences.h index 96d85d6fa5a2..58b7430ed29e 100644 --- a/modules/libpref/Preferences.h +++ b/modules/libpref/Preferences.h @@ -536,6 +536,9 @@ class Preferences final : public nsIPrefService, static bool InitStaticMembers(); }; +extern Atomic sOmitBlocklistedPrefValues; +extern Atomic sCrashOnBlocklistedPref; + bool ShouldSanitizePreference(const char* aPref, bool aIsDestWebContentProcess); } // namespace mozilla diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 7b0ddf8196ea..763a349356c8 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -4697,6 +4697,18 @@ value: @IS_ANDROID@ mirror: always +# If true, do not send blocklisted preference values to the subprocess +- name: fission.omitBlocklistedPrefsInSubprocesses + type: RelaxedAtomicBool + value: false + mirror: always + +# If true, crash when a blocklisted preference is accessed in a subprocess +- name: fission.enforceBlocklistedPrefsInSubprocesses + type: RelaxedAtomicBool + value: false + mirror: always + #--------------------------------------------------------------------------- # Prefs starting with "font." #--------------------------------------------------------------------------- diff --git a/modules/libpref/init/StaticPrefListBegin.h b/modules/libpref/init/StaticPrefListBegin.h index 2f37185b8ad1..8af91795549b 100644 --- a/modules/libpref/init/StaticPrefListBegin.h +++ b/modules/libpref/init/StaticPrefListBegin.h @@ -22,7 +22,8 @@ namespace StaticPrefs { #define ALWAYS_PREF(name, base_id, full_id, cpp_type, default_value) \ extern cpp_type sMirror_##full_id; \ inline StripAtomic full_id() { \ - if (!XRE_IsParentProcess() && IsString::value) { \ + if (!XRE_IsParentProcess() && IsString::value && \ + sCrashOnBlocklistedPref) { \ MOZ_DIAGNOSTIC_ASSERT( \ !ShouldSanitizePreference(name, XRE_IsContentProcess()), \ "Should not access the preference '" name "' in Content Processes"); \ @@ -40,7 +41,8 @@ namespace StaticPrefs { extern cpp_type sMirror_##full_id; \ inline cpp_type full_id() { \ MaybeInitOncePrefs(); \ - if (!XRE_IsParentProcess() && IsString::value) { \ + if (!XRE_IsParentProcess() && IsString::value && \ + sCrashOnBlocklistedPref) { \ MOZ_DIAGNOSTIC_ASSERT( \ !ShouldSanitizePreference(name, XRE_IsContentProcess()), \ "Should not access the preference '" name "' in Content Processes"); \