Commit 30dc7319 authored by W. James MacLean's avatar W. James MacLean Committed by Commit Bot

Convert from storing lowest BrowsingInstanceID to keeping all in a set.

At present ChildProcessSecurityPolicyImpl::SecurityState stores only a
single BrowsingInstanceID (the lowest) even though its associated
process may contain multiple BrowsingInstances. This may lead
CanAccessDataForOrigin to consider the wrong BrowsingInstance when
performing its checks for opt-in isolated origins.

This CL converts SecurityState to track an ordered set of all the
BrowsingInstanceIDs so that they can all be checked.
CanAccessDataForOrigin is modified to return 'true' if *any*
BrowsingInstance in the set would allow the access, otherwise it returns
'false', and logs the failure reasons for each of the BrowsingInstances.

This CL also includes delayed cleanup of BrowsingInstance state from
ChildProcessSecurityPolicy when BrowsingInstances are deleted. This
avoids memory leaks but may pose a small risk of renderer kills. We will
monitor the CanAccessDataForOrigin crash keys to see if such cases
occur in practice.

Bug: 1135539
Change-Id: Icb7d25a84601b378c0c495a19266cd013667136a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2446370Reviewed-by: default avatarJesse Doherty <jwd@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Reviewed-by: default avatarCharlie Reis <creis@chromium.org>
Reviewed-by: default avatarAaron Colwell <acolwell@chromium.org>
Commit-Queue: James MacLean <wjmaclean@chromium.org>
Cr-Commit-Position: refs/heads/master@{#819830}
parent 3f0257f6
...@@ -214,7 +214,8 @@ BrowsingInstance::~BrowsingInstance() { ...@@ -214,7 +214,8 @@ BrowsingInstance::~BrowsingInstance() {
// Remove any origin isolation opt-ins related to this instance. // Remove any origin isolation opt-ins related to this instance.
ChildProcessSecurityPolicyImpl* policy = ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance(); ChildProcessSecurityPolicyImpl::GetInstance();
policy->RemoveOptInIsolatedOriginsForBrowsingInstance(isolation_context_); policy->RemoveOptInIsolatedOriginsForBrowsingInstance(
isolation_context_.browsing_instance_id());
} }
SiteInfo BrowsingInstance::ComputeSiteInfoForURL( SiteInfo BrowsingInstance::ComputeSiteInfoForURL(
......
...@@ -364,9 +364,9 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl ...@@ -364,9 +364,9 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
url::Origin* result); url::Origin* result);
// Removes any origin isolation opt-in entries associated with the // Removes any origin isolation opt-in entries associated with the
// |isolation_context| of the BrowsingInstance. // |browsing_instance_id| of the BrowsingInstance.
void RemoveOptInIsolatedOriginsForBrowsingInstance( void RemoveOptInIsolatedOriginsForBrowsingInstance(
const IsolationContext& isolation_context); const BrowsingInstanceId& browsing_instance_id);
// Registers |origin|'s isolation status with respect to the BrowsingInstance // Registers |origin|'s isolation status with respect to the BrowsingInstance
// associated with |isolation_context|. If it has already been registered, // associated with |isolation_context|. If it has already been registered,
...@@ -784,6 +784,10 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl ...@@ -784,6 +784,10 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
void RemoveProcessReferenceLocked(int child_id) void RemoveProcessReferenceLocked(int child_id)
EXCLUSIVE_LOCKS_REQUIRED(lock_); EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Internal helper for RemoveOptInIsolatedOriginsForBrowsingInstance().
void RemoveOptInIsolatedOriginsForBrowsingInstanceInternal(
const BrowsingInstanceId browsing_instance_id);
// Creates the value to place in the "killed_process_origin_lock" crash key // Creates the value to place in the "killed_process_origin_lock" crash key
// based on the contents of |security_state|. // based on the contents of |security_state|.
static std::string GetKilledProcessOriginLock( static std::string GetKilledProcessOriginLock(
......
...@@ -80,15 +80,17 @@ class NavigationEntryTest : public testing::Test { ...@@ -80,15 +80,17 @@ class NavigationEntryTest : public testing::Test {
void TearDown() override {} void TearDown() override {}
private:
BrowserTaskEnvironment task_environment_;
TestBrowserContext browser_context_;
protected: protected:
// Destructors for SiteInstances must run before |task_environment_| shuts
// down.
std::unique_ptr<NavigationEntryImpl> entry1_; std::unique_ptr<NavigationEntryImpl> entry1_;
std::unique_ptr<NavigationEntryImpl> entry2_; std::unique_ptr<NavigationEntryImpl> entry2_;
// SiteInstances are deleted when their NavigationEntries are gone. // SiteInstances are deleted when their NavigationEntries are gone.
scoped_refptr<SiteInstanceImpl> instance_; scoped_refptr<SiteInstanceImpl> instance_;
private:
BrowserTaskEnvironment task_environment_;
TestBrowserContext browser_context_;
}; };
// Test unique ID accessors // Test unique ID accessors
......
...@@ -296,18 +296,33 @@ std::string FrameTreeVisualizer::GetName(SiteInstance* site_instance) { ...@@ -296,18 +296,33 @@ std::string FrameTreeVisualizer::GetName(SiteInstance* site_instance) {
Shell* OpenPopup(const ToRenderFrameHost& opener, Shell* OpenPopup(const ToRenderFrameHost& opener,
const GURL& url, const GURL& url,
const std::string& name) { const std::string& name) {
return OpenPopup(opener, url, name, "", true);
}
Shell* OpenPopup(const ToRenderFrameHost& opener,
const GURL& url,
const std::string& name,
const std::string& features,
bool expect_return_from_window_open) {
TestNavigationObserver observer(url); TestNavigationObserver observer(url);
observer.StartWatchingNewWebContents(); observer.StartWatchingNewWebContents();
ShellAddedObserver new_shell_observer; ShellAddedObserver new_shell_observer;
bool did_create_popup = false; bool did_create_popup = false;
bool did_execute_script = ExecuteScriptAndExtractBool( std::string popup_script =
opener,
"window.domAutomationController.send(" "window.domAutomationController.send("
" !!window.open('" + url.spec() + "', '" + name + "'));", " !!window.open('" +
&did_create_popup); url.spec() + "', '" + name + "', '" + features + "'));";
if (!did_execute_script || !did_create_popup) bool did_execute_script =
ExecuteScriptAndExtractBool(opener, popup_script, &did_create_popup);
// Don't check the value of |did_create_popup| since there are valid reasons
// for it to be false, e.g. |features| specifies 'noopener', or 'noreferrer'
// or others.
if (!did_execute_script ||
!(did_create_popup || !expect_return_from_window_open)) {
return nullptr; return nullptr;
}
observer.Wait(); observer.Wait();
......
...@@ -101,10 +101,19 @@ class FrameTreeVisualizer { ...@@ -101,10 +101,19 @@ class FrameTreeVisualizer {
}; };
// Uses window.open to open a popup from the frame |opener| with the specified // Uses window.open to open a popup from the frame |opener| with the specified
// |url| and |name|. Waits for the navigation to |url| to finish and then // |url|, |name| and window |features|. |expect_return_from_window_open| is used
// returns the new popup's Shell. Note that since this navigation to |url| is // to indicate if the caller expects window.open() to return a non-null value.
// renderer-initiated, it won't cause a process swap unless used in // Waits for the navigation to |url| to finish and then returns the new popup's
// --site-per-process mode. // Shell. Note that since this navigation to |url| is renderer-initiated, it
// won't cause a process swap unless used in --site-per-process mode.
Shell* OpenPopup(const ToRenderFrameHost& opener,
const GURL& url,
const std::string& name,
const std::string& features,
bool expect_return_from_window_open);
// Same as above, but with an empty |features| and
// |expect_return_from_window_open| assumed to be true..
Shell* OpenPopup(const ToRenderFrameHost& opener, Shell* OpenPopup(const ToRenderFrameHost& opener,
const GURL& url, const GURL& url,
const std::string& name); const std::string& name);
......
...@@ -13428,6 +13428,17 @@ should be kept until we remove incident reporting. --> ...@@ -13428,6 +13428,17 @@ should be kept until we remove incident reporting. -->
</summary> </summary>
</histogram> </histogram>
<histogram name="SiteIsolation.BrowsingInstance.MaxCountPerProcess"
units="units" expires_after="2021-10-15">
<owner>wjmaclean@chromium.org</owner>
<owner>creis@chromium.org</owner>
<summary>
The maximum number of BrowsingInstances seen in a RenderProcessHost over its
lifetime. Recorded once when
ChildProcessImpl::SecurityState::~SecurityState() is invoked.
</summary>
</histogram>
<histogram name="SiteIsolation.BrowsingInstanceCount" units="units" <histogram name="SiteIsolation.BrowsingInstanceCount" units="units"
expires_after="2021-09-30"> expires_after="2021-09-30">
<owner>alexmos@chromium.org</owner> <owner>alexmos@chromium.org</owner>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment