If `IsPreferenceSanitized(char*)` is called, it will call pref_Lookup which is not thread-safe. StaticPrefs use that function to check pref sanitization. Prefs are sanitized if they are a no-default-value string-type preference _or_ their name is in sRestrictFromWebContentProcesses. The first check is intended to catch prefs set dynamically, ones we don't know about and may want to sanitize. But Static Prefs we know all about. So we can omit that check for them. We only (in theory) need to check them against the blocklist. In practice: no Static Prefs are sanitized. If they were (and they were not mirror-never prefs), it would have exposed the bug that makes content processes crash on startup, because we would crash during initialization. That initialization happens while reading the prefs from the Shared Map - sanitized prefs can't be in the shared map. So we can take a shortcut and instead of building in support for Static Prefs to be initialized from the HashMap instead of the shared map (perhaps as simple as s/GetSharedPrefValue/GetPrefValue), we can just crash if someone adds a Static Pref to the list of things to be sanitized. Differential Revision: https://phabricator.services.mozilla.com/D189968
51 lines
2.9 KiB
C++
51 lines
2.9 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
// This file does not make sense on its own. It must be #included along with
|
|
// StaticPrefsListEnd.h in all headers that contribute prefs to the StaticPrefs
|
|
// namespace.
|
|
|
|
#include "StaticPrefsBase.h"
|
|
#include "Preferences.h"
|
|
#include "MainThreadUtils.h" // for NS_IsMainThread()
|
|
#include "nsXULAppAPI.h" // for XRE_IsContentProcess()
|
|
|
|
namespace mozilla {
|
|
namespace StaticPrefs {
|
|
|
|
// For mirrored prefs we generate an extern variable declaration and three
|
|
// getter declarations/definitions.
|
|
#define NEVER_PREF(name, cpp_type, default_value)
|
|
#define ALWAYS_PREF(name, base_id, full_id, cpp_type, default_value) \
|
|
extern cpp_type sMirror_##full_id; \
|
|
inline StripAtomic<cpp_type> full_id() { \
|
|
MOZ_DIAGNOSTIC_ASSERT(IsAtomic<cpp_type>::value || NS_IsMainThread(), \
|
|
"Non-atomic static pref '" name \
|
|
"' being accessed on background thread by getter"); \
|
|
return sMirror_##full_id; \
|
|
} \
|
|
inline const char* GetPrefName_##base_id() { return name; } \
|
|
inline StripAtomic<cpp_type> GetPrefDefault_##base_id() { \
|
|
return default_value; \
|
|
}
|
|
#define ALWAYS_DATAMUTEX_PREF(name, base_id, full_id, cpp_type, default_value) \
|
|
extern cpp_type sMirror_##full_id; \
|
|
inline cpp_type::ConstAutoLock full_id() { \
|
|
return sMirror_##full_id.ConstLock(); \
|
|
} \
|
|
inline const char* GetPrefName_##base_id() { return name; } \
|
|
inline StripAtomic<cpp_type> GetPrefDefault_##base_id() { \
|
|
return default_value; \
|
|
}
|
|
#define ONCE_PREF(name, base_id, full_id, cpp_type, default_value) \
|
|
extern cpp_type sMirror_##full_id; \
|
|
inline cpp_type full_id() { \
|
|
MaybeInitOncePrefs(); \
|
|
return sMirror_##full_id; \
|
|
} \
|
|
inline const char* GetPrefName_##base_id() { return name; } \
|
|
inline cpp_type GetPrefDefault_##base_id() { return default_value; }
|