Bug 1752332: Add preferences that control whether we send user data and/or crash r=KrisWright

Depends on D141418

Differential Revision: https://phabricator.services.mozilla.com/D141419
This commit is contained in:
Tom Ritter 2022-04-20 20:21:47 +00:00
Родитель 9b9b78005e
Коммит 59092e70b4
5 изменённых файлов: 53 добавлений и 8 удалений

Просмотреть файл

@ -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<ContentParent>
@ -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<SandboxBrokerPolicyFactory>();
#endif

Просмотреть файл

@ -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<bool, Relaxed> sOmitBlocklistedPrefValues(false);
Atomic<bool, Relaxed> sCrashOnBlocklistedPref(false);
} // namespace mozilla
// This file contains the C wrappers for the C++ static pref getters, as used

Просмотреть файл

@ -536,6 +536,9 @@ class Preferences final : public nsIPrefService,
static bool InitStaticMembers();
};
extern Atomic<bool, Relaxed> sOmitBlocklistedPrefValues;
extern Atomic<bool, Relaxed> sCrashOnBlocklistedPref;
bool ShouldSanitizePreference(const char* aPref, bool aIsDestWebContentProcess);
} // namespace mozilla

Просмотреть файл

@ -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."
#---------------------------------------------------------------------------

Просмотреть файл

@ -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<cpp_type> full_id() { \
if (!XRE_IsParentProcess() && IsString<cpp_type>::value) { \
if (!XRE_IsParentProcess() && IsString<cpp_type>::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<cpp_type>::value) { \
if (!XRE_IsParentProcess() && IsString<cpp_type>::value && \
sCrashOnBlocklistedPref) { \
MOZ_DIAGNOSTIC_ASSERT( \
!ShouldSanitizePreference(name, XRE_IsContentProcess()), \
"Should not access the preference '" name "' in Content Processes"); \