diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-09-29 16:16:15 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-11-09 10:04:06 +0000 |
commit | a95a7417ad456115a1ef2da4bb8320531c0821f1 (patch) | |
tree | edcd59279e486d2fd4a8f88a7ed025bcf925c6e6 /chromium/components/site_isolation | |
parent | 33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (diff) | |
download | qtwebengine-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')
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 |