summaryrefslogtreecommitdiff
path: root/chromium/components/site_isolation
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-09-29 16:16:15 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-11-09 10:04:06 +0000
commita95a7417ad456115a1ef2da4bb8320531c0821f1 (patch)
treeedcd59279e486d2fd4a8f88a7ed025bcf925c6e6 /chromium/components/site_isolation
parent33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (diff)
downloadqtwebengine-chromium-a95a7417ad456115a1ef2da4bb8320531c0821f1.tar.gz
BASELINE: Update Chromium to 106.0.5249.126
Change-Id: Ib0bb21c437a7d1686e21c33f2d329f2ac425b7ab Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/438936 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/site_isolation')
-rw-r--r--chromium/components/site_isolation/features.cc3
-rw-r--r--chromium/components/site_isolation/features.h1
-rw-r--r--chromium/components/site_isolation/site_isolation_policy.cc195
-rw-r--r--chromium/components/site_isolation/site_isolation_policy.h6
-rw-r--r--chromium/components/site_isolation/site_isolation_policy_unittest.cc41
5 files changed, 159 insertions, 87 deletions
diff --git a/chromium/components/site_isolation/features.cc b/chromium/components/site_isolation/features.cc
index 0ee83daecb7..ab631cda2ce 100644
--- a/chromium/components/site_isolation/features.cc
+++ b/chromium/components/site_isolation/features.cc
@@ -9,6 +9,9 @@
namespace site_isolation {
namespace features {
+const base::Feature kCacheSiteIsolationMemoryThreshold{
+ "CacheSiteIsolationMemoryThreshold", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls a mode for dynamically process-isolating sites where the user has
// entered a password. This is intended to be used primarily when full site
// isolation is turned off. To check whether this mode is enabled, use
diff --git a/chromium/components/site_isolation/features.h b/chromium/components/site_isolation/features.h
index 90ed4a2bde6..ff8bdfb0d84 100644
--- a/chromium/components/site_isolation/features.h
+++ b/chromium/components/site_isolation/features.h
@@ -10,6 +10,7 @@
namespace site_isolation {
namespace features {
+extern const base::Feature kCacheSiteIsolationMemoryThreshold;
extern const base::Feature kSiteIsolationForPasswordSites;
extern const base::Feature kSiteIsolationForOAuthSites;
extern const base::Feature kSiteIsolationMemoryThresholds;
diff --git a/chromium/components/site_isolation/site_isolation_policy.cc b/chromium/components/site_isolation/site_isolation_policy.cc
index 4ed12c9ae26..2825c37c13a 100644
--- a/chromium/components/site_isolation/site_isolation_policy.cc
+++ b/chromium/components/site_isolation/site_isolation_policy.cc
@@ -5,6 +5,7 @@
#include "components/site_isolation/site_isolation_policy.h"
#include "base/containers/contains.h"
+#include "base/feature_list.h"
#include "base/json/values_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
@@ -28,6 +29,88 @@ namespace {
using IsolatedOriginSource =
content::ChildProcessSecurityPolicy::IsolatedOriginSource;
+bool g_disallow_memory_threshold_caching = false;
+
+bool ShouldCacheMemoryThresholdDecision() {
+ return base::FeatureList::IsEnabled(
+ features::kCacheSiteIsolationMemoryThreshold);
+}
+
+struct IsolationDisableDecisions {
+ bool should_disable_strict;
+ bool should_disable_partial;
+};
+
+bool ShouldDisableSiteIsolationDueToMemorySlow(
+ content::SiteIsolationMode site_isolation_mode) {
+ // The memory threshold behavior differs for desktop and Android:
+ // - Android uses a 1900MB default threshold for partial site isolation modes
+ // and a 3200MB default threshold for strict site isolation. See docs in
+ // https://crbug.com/849815. The thresholds roughly correspond to 2GB+ and
+ // 4GB+ devices and are lower to account for memory carveouts, which
+ // reduce the amount of memory seen by AmountOfPhysicalMemoryMB(). Both
+ // partial and strict site isolation thresholds can be overridden via
+ // params defined in a kSiteIsolationMemoryThresholds field trial.
+ // - Desktop does not enforce a default memory threshold, but for now we
+ // still support a threshold defined via a kSiteIsolationMemoryThresholds
+ // field trial. The trial typically carries the threshold in a param; if
+ // it doesn't, use a default that's slightly higher than 1GB (see
+ // https://crbug.com/844118).
+ int default_memory_threshold_mb;
+#if BUILDFLAG(IS_ANDROID)
+ if (site_isolation_mode == content::SiteIsolationMode::kStrictSiteIsolation) {
+ default_memory_threshold_mb = 3200;
+ } else {
+ default_memory_threshold_mb = 1900;
+ }
+#else
+ default_memory_threshold_mb = 1077;
+#endif
+
+ if (base::FeatureList::IsEnabled(features::kSiteIsolationMemoryThresholds)) {
+ std::string param_name;
+ switch (site_isolation_mode) {
+ case content::SiteIsolationMode::kStrictSiteIsolation:
+ param_name = features::kStrictSiteIsolationMemoryThresholdParamName;
+ break;
+ case content::SiteIsolationMode::kPartialSiteIsolation:
+ param_name = features::kPartialSiteIsolationMemoryThresholdParamName;
+ break;
+ }
+ int memory_threshold_mb = base::GetFieldTrialParamByFeatureAsInt(
+ features::kSiteIsolationMemoryThresholds, param_name,
+ default_memory_threshold_mb);
+ return base::SysInfo::AmountOfPhysicalMemoryMB() <= memory_threshold_mb;
+ }
+
+#if BUILDFLAG(IS_ANDROID)
+ if (base::SysInfo::AmountOfPhysicalMemoryMB() <=
+ default_memory_threshold_mb) {
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+IsolationDisableDecisions MakeBothDecisions() {
+ IsolationDisableDecisions result{
+ .should_disable_strict = ShouldDisableSiteIsolationDueToMemorySlow(
+ content::SiteIsolationMode::kStrictSiteIsolation),
+ .should_disable_partial = ShouldDisableSiteIsolationDueToMemorySlow(
+ content::SiteIsolationMode::kPartialSiteIsolation)};
+ return result;
+}
+
+bool CachedDisableSiteIsolation(
+ content::SiteIsolationMode site_isolation_mode) {
+ static const IsolationDisableDecisions decisions = MakeBothDecisions();
+ if (site_isolation_mode == content::SiteIsolationMode::kStrictSiteIsolation) {
+ return decisions.should_disable_strict;
+ }
+ return decisions.should_disable_partial;
+}
+
} // namespace
// static
@@ -101,54 +184,12 @@ bool SiteIsolationPolicy::IsEnterprisePolicyApplicable() {
// static
bool SiteIsolationPolicy::ShouldDisableSiteIsolationDueToMemoryThreshold(
content::SiteIsolationMode site_isolation_mode) {
- // The memory threshold behavior differs for desktop and Android:
- // - Android uses a 1900MB default threshold for partial site isolation modes
- // and a 3200MB default threshold for strict site isolation. See docs in
- // https://crbug.com/849815. The thresholds roughly correspond to 2GB+ and
- // 4GB+ devices and are lower to account for memory carveouts, which
- // reduce the amount of memory seen by AmountOfPhysicalMemoryMB(). Both
- // partial and strict site isolation thresholds can be overridden via
- // params defined in a kSiteIsolationMemoryThresholds field trial.
- // - Desktop does not enforce a default memory threshold, but for now we
- // still support a threshold defined via a kSiteIsolationMemoryThresholds
- // field trial. The trial typically carries the threshold in a param; if
- // it doesn't, use a default that's slightly higher than 1GB (see
- // https://crbug.com/844118).
- int default_memory_threshold_mb;
-#if BUILDFLAG(IS_ANDROID)
- if (site_isolation_mode == content::SiteIsolationMode::kStrictSiteIsolation) {
- default_memory_threshold_mb = 3200;
- } else {
- default_memory_threshold_mb = 1900;
+ static const bool cache_memory_threshold_decision =
+ ShouldCacheMemoryThresholdDecision();
+ if (!g_disallow_memory_threshold_caching && cache_memory_threshold_decision) {
+ return CachedDisableSiteIsolation(site_isolation_mode);
}
-#else
- default_memory_threshold_mb = 1077;
-#endif
-
- if (base::FeatureList::IsEnabled(features::kSiteIsolationMemoryThresholds)) {
- std::string param_name;
- switch (site_isolation_mode) {
- case content::SiteIsolationMode::kStrictSiteIsolation:
- param_name = features::kStrictSiteIsolationMemoryThresholdParamName;
- break;
- case content::SiteIsolationMode::kPartialSiteIsolation:
- param_name = features::kPartialSiteIsolationMemoryThresholdParamName;
- break;
- }
- int memory_threshold_mb = base::GetFieldTrialParamByFeatureAsInt(
- features::kSiteIsolationMemoryThresholds, param_name,
- default_memory_threshold_mb);
- return base::SysInfo::AmountOfPhysicalMemoryMB() <= memory_threshold_mb;
- }
-
-#if BUILDFLAG(IS_ANDROID)
- if (base::SysInfo::AmountOfPhysicalMemoryMB() <=
- default_memory_threshold_mb) {
- return true;
- }
-#endif
-
- return false;
+ return ShouldDisableSiteIsolationDueToMemorySlow(site_isolation_mode);
}
// static
@@ -234,9 +275,9 @@ void SiteIsolationPolicy::ApplyPersistedIsolatedOrigins(
// they can be used if password-triggered isolation is re-enabled later.
if (IsIsolationForPasswordSitesEnabled()) {
std::vector<url::Origin> origins;
- for (const auto& value : user_prefs::UserPrefs::Get(browser_context)
- ->GetList(prefs::kUserTriggeredIsolatedOrigins)
- ->GetListDeprecated()) {
+ for (const auto& value :
+ user_prefs::UserPrefs::Get(browser_context)
+ ->GetValueList(prefs::kUserTriggeredIsolatedOrigins)) {
origins.push_back(url::Origin::Create(GURL(value.GetString())));
}
@@ -257,33 +298,31 @@ void SiteIsolationPolicy::ApplyPersistedIsolatedOrigins(
std::vector<std::string> expired_entries;
auto* pref_service = user_prefs::UserPrefs::Get(browser_context);
- auto* dict =
- pref_service->GetDictionary(prefs::kWebTriggeredIsolatedOrigins);
- if (dict) {
- for (auto site_time_pair : dict->DictItems()) {
- // Only isolate origins that haven't expired.
- absl::optional<base::Time> timestamp =
- base::ValueToTime(site_time_pair.second);
- base::TimeDelta expiration_timeout =
- ::features::
- kSiteIsolationForCrossOriginOpenerPolicyExpirationTimeoutParam
- .Get();
- if (timestamp.has_value() &&
- base::Time::Now() - timestamp.value() <= expiration_timeout) {
- origins.push_back(url::Origin::Create(GURL(site_time_pair.first)));
- } else {
- expired_entries.push_back(site_time_pair.first);
- }
- }
- // Remove expired entries (as well as those with an invalid timestamp).
- if (!expired_entries.empty()) {
- DictionaryPrefUpdate update(pref_service,
- prefs::kWebTriggeredIsolatedOrigins);
- base::Value* updated_dict = update.Get();
- for (const auto& entry : expired_entries)
- updated_dict->RemoveKey(entry);
+ const auto& dict =
+ pref_service->GetValueDict(prefs::kWebTriggeredIsolatedOrigins);
+ for (auto site_time_pair : dict) {
+ // Only isolate origins that haven't expired.
+ absl::optional<base::Time> timestamp =
+ base::ValueToTime(site_time_pair.second);
+ base::TimeDelta expiration_timeout =
+ ::features::
+ kSiteIsolationForCrossOriginOpenerPolicyExpirationTimeoutParam
+ .Get();
+ if (timestamp.has_value() &&
+ base::Time::Now() - timestamp.value() <= expiration_timeout) {
+ origins.push_back(url::Origin::Create(GURL(site_time_pair.first)));
+ } else {
+ expired_entries.push_back(site_time_pair.first);
}
}
+ // Remove expired entries (as well as those with an invalid timestamp).
+ if (!expired_entries.empty()) {
+ DictionaryPrefUpdate update(pref_service,
+ prefs::kWebTriggeredIsolatedOrigins);
+ base::Value* updated_dict = update.Get();
+ for (const auto& entry : expired_entries)
+ updated_dict->RemoveKey(entry);
+ }
if (!origins.empty()) {
policy->AddFutureIsolatedOrigins(
@@ -356,4 +395,10 @@ bool SiteIsolationPolicy::ShouldPdfCompositorBeEnabledForOopifs() {
#endif
}
+// static
+void SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(
+ bool disallow_caching) {
+ g_disallow_memory_threshold_caching = disallow_caching;
+}
+
} // namespace site_isolation
diff --git a/chromium/components/site_isolation/site_isolation_policy.h b/chromium/components/site_isolation/site_isolation_policy.h
index 25d698ae4d6..2ee1408c189 100644
--- a/chromium/components/site_isolation/site_isolation_policy.h
+++ b/chromium/components/site_isolation/site_isolation_policy.h
@@ -89,6 +89,12 @@ class SiteIsolationPolicy {
// process iframes (OOPIF's) to print properly.
static bool ShouldPdfCompositorBeEnabledForOopifs();
+ // When set to true bypasses the caching of the results of
+ // ShouldDisableSiteIsolationDueToMemoryThreshold(). Setting to false reverts
+ // to the default behavior (caching is controlled by a base::Feature).
+ static void SetDisallowMemoryThresholdCachingForTesting(
+ bool disallow_caching);
+
private:
// Helpers for implementing PersistIsolatedOrigin().
static void PersistUserTriggeredIsolatedOrigin(
diff --git a/chromium/components/site_isolation/site_isolation_policy_unittest.cc b/chromium/components/site_isolation/site_isolation_policy_unittest.cc
index 9ed07c030dd..4b5e258993d 100644
--- a/chromium/components/site_isolation/site_isolation_policy_unittest.cc
+++ b/chromium/components/site_isolation/site_isolation_policy_unittest.cc
@@ -13,7 +13,6 @@
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_entropy_provider.h"
#include "base/test/scoped_feature_list.h"
-#include "base/test/scoped_field_trial_list_resetter.h"
#include "base/time/time.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
@@ -156,9 +155,9 @@ class WebTriggeredIsolatedOriginsPolicyTest : public SiteIsolationPolicyTest {
std::vector<std::string> GetStoredOrigins() {
std::vector<std::string> origins;
- auto* dict = user_prefs::UserPrefs::Get(browser_context())
- ->GetDictionary(prefs::kWebTriggeredIsolatedOrigins);
- for (auto pair : dict->DictItems())
+ const auto& dict = user_prefs::UserPrefs::Get(browser_context())
+ ->GetValueDict(prefs::kWebTriggeredIsolatedOrigins);
+ for (auto pair : dict)
origins.push_back(pair.first);
return origins;
}
@@ -692,8 +691,9 @@ INSTANTIATE_TEST_SUITE_P(
// or disabled state.
class PasswordSiteIsolationFieldTrialTest : public BaseSiteIsolationTest {
public:
- explicit PasswordSiteIsolationFieldTrialTest(bool should_enable)
- : field_trial_list_(std::make_unique<base::MockEntropyProvider>()) {
+ explicit PasswordSiteIsolationFieldTrialTest(bool should_enable) {
+ empty_feature_scope_.InitWithEmptyFeatureAndFieldTrialLists();
+
const std::string kTrialName = "PasswordSiteIsolation";
const std::string kGroupName = "FooGroup"; // unused
scoped_refptr<base::FieldTrial> trial =
@@ -728,12 +728,20 @@ class PasswordSiteIsolationFieldTrialTest : public BaseSiteIsolationTest {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableLowEndDeviceMode);
EXPECT_EQ(512, base::SysInfo::AmountOfPhysicalMemoryMB());
+ SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(true);
+ }
+
+ void TearDown() override {
+ SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(false);
}
protected:
- base::test::ScopedFieldTrialListResetter trial_list_resetter_;
+ // |empty_feature_scope_| is used to prepare an environment with empty
+ // features and field trial lists.
+ base::test::ScopedFeatureList empty_feature_scope_;
+ // |feature_list_| is used to enable and disable features for
+ // PasswordSiteIsolationFieldTrialTest.
base::test::ScopedFeatureList feature_list_;
- base::FieldTrialList field_trial_list_;
};
class EnabledPasswordSiteIsolationFieldTrialTest
@@ -900,8 +908,9 @@ TEST_F(DisabledPasswordSiteIsolationFieldTrialTest,
// or disabled state.
class StrictOriginIsolationFieldTrialTest : public BaseSiteIsolationTest {
public:
- explicit StrictOriginIsolationFieldTrialTest(bool should_enable)
- : field_trial_list_(std::make_unique<base::MockEntropyProvider>()) {
+ explicit StrictOriginIsolationFieldTrialTest(bool should_enable) {
+ empty_feature_scope_.InitWithEmptyFeatureAndFieldTrialLists();
+
const std::string kTrialName = "StrictOriginIsolation";
const std::string kGroupName = "FooGroup"; // unused
scoped_refptr<base::FieldTrial> trial =
@@ -936,12 +945,20 @@ class StrictOriginIsolationFieldTrialTest : public BaseSiteIsolationTest {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableLowEndDeviceMode);
EXPECT_EQ(512, base::SysInfo::AmountOfPhysicalMemoryMB());
+ SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(true);
+ }
+
+ void TearDown() override {
+ SiteIsolationPolicy::SetDisallowMemoryThresholdCachingForTesting(false);
}
protected:
- base::test::ScopedFieldTrialListResetter trial_list_resetter_;
+ // |empty_feature_scope_| is used to prepare an environment with empty
+ // features and field trial lists.
+ base::test::ScopedFeatureList empty_feature_scope_;
+ // |feature_list_| is used to enable and disable features for
+ // StrictOriginIsolationFieldTrialTest.
base::test::ScopedFeatureList feature_list_;
- base::FieldTrialList field_trial_list_;
};
class EnabledStrictOriginIsolationFieldTrialTest