Commit 71426a90 authored by Alex Moshchuk's avatar Alex Moshchuk

Lock hosted apps to their underlying web origin.

Previously, hosted apps were exempt from LockToOrigin() even in
--site-per-process mode.  That meant that hosted apps were not subject
to enforcements such as not allowing access to cookies, passwords, or
local storage of other sites.  Worse, it meant that hosted apps could
arbitrarily share a process (e.g., when over process limit), even if
they covered different web sites with --site-per-process.

This CL starts locking hosted apps to their underlying web origin.  If
a frame commits a navigation to URL http://foo.com, which is part of a
hosted app X's web extent, the process for that frame will be locked
to http://foo.com.  Note that the SiteInstance for this frame will
still use a site URL based on the effective URL (i.e.,
chrome-extension://<ext_id_for_X>/), but the origin lock will not be
based on effective URLs.  This requires plumbing to compute the origin
lock as a site URL that does not use an effective URL, and to plumb it
into various places that make process model decisions, such as
RPHI::IsSuitableHost().

Bug: 811939, 794315, 791796
Change-Id: Icc9b3c0a04253e581ea35953f3c566308305db59
Reviewed-on: https://chromium-review.googlesource.com/959346
Commit-Queue: Alex Moshchuk <alexmos@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarCharlie Reis <creis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#583895}
parent 71120bdb
...@@ -428,28 +428,29 @@ bool ChromeContentBrowserClientExtensionsPart::DoesSiteRequireDedicatedProcess( ...@@ -428,28 +428,29 @@ bool ChromeContentBrowserClientExtensionsPart::DoesSiteRequireDedicatedProcess(
bool ChromeContentBrowserClientExtensionsPart::ShouldLockToOrigin( bool ChromeContentBrowserClientExtensionsPart::ShouldLockToOrigin(
content::BrowserContext* browser_context, content::BrowserContext* browser_context,
const GURL& effective_site_url) { const GURL& effective_site_url) {
// https://crbug.com/160576 workaround: Origin lock to the chrome-extension:// if (!effective_site_url.SchemeIs(kExtensionScheme))
// scheme for a hosted app would kill processes on legitimate requests for the return true;
// app's cookies.
if (effective_site_url.SchemeIs(extensions::kExtensionScheme)) { const Extension* extension = ExtensionRegistry::Get(browser_context)
const Extension* extension =
ExtensionRegistry::Get(browser_context)
->enabled_extensions() ->enabled_extensions()
.GetExtensionOrAppByURL(effective_site_url); .GetExtensionOrAppByURL(effective_site_url);
if (extension && extension->is_hosted_app()) if (!extension)
return false; return true;
// Hosted apps should be locked to their web origin. See
// https://crbug.com/794315.
if (extension->is_hosted_app())
return true;
// Extensions are allowed to share processes, even in --site-per-process // Other extensions are allowed to share processes, even in
// currently. See https://crbug.com/600441#c1 for some background on the // --site-per-process currently. See https://crbug.com/600441#c1 for some
// intersection of extension process reuse and site isolation. // background on the intersection of extension process reuse and site
// isolation.
// //
// TODO(nick): Fix this, possibly by revamping the extensions process model // TODO(nick): Fix this, possibly by revamping the extensions process model
// so that sharing is determined by privilege level, as described in // so that sharing is determined by privilege level, as described in
// https://crbug.com/766267 // https://crbug.com/766267.
if (extension)
return false; return false;
}
return true;
} }
// static // static
......
...@@ -21,8 +21,7 @@ BrowsingInstance::BrowsingInstance(BrowserContext* browser_context) ...@@ -21,8 +21,7 @@ BrowsingInstance::BrowsingInstance(BrowserContext* browser_context)
} }
bool BrowsingInstance::HasSiteInstance(const GURL& url) { bool BrowsingInstance::HasSiteInstance(const GURL& url) {
std::string site = std::string site = SiteInstance::GetSiteForURL(browser_context_, url)
SiteInstanceImpl::GetSiteForURL(browser_context_, url)
.possibly_invalid_spec(); .possibly_invalid_spec();
return site_instance_map_.find(site) != site_instance_map_.end(); return site_instance_map_.find(site) != site_instance_map_.end();
...@@ -30,7 +29,7 @@ bool BrowsingInstance::HasSiteInstance(const GURL& url) { ...@@ -30,7 +29,7 @@ bool BrowsingInstance::HasSiteInstance(const GURL& url) {
scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURL( scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURL(
const GURL& url) { const GURL& url) {
std::string site = SiteInstanceImpl::GetSiteForURL(browser_context_, url) std::string site = SiteInstance::GetSiteForURL(browser_context_, url)
.possibly_invalid_spec(); .possibly_invalid_spec();
SiteInstanceMap::iterator i = site_instance_map_.find(site); SiteInstanceMap::iterator i = site_instance_map_.find(site);
......
...@@ -1120,7 +1120,7 @@ bool ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin(int child_id, ...@@ -1120,7 +1120,7 @@ bool ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin(int child_id,
// TODO(creis): We must pass the valid browser_context to convert hosted apps // TODO(creis): We must pass the valid browser_context to convert hosted apps
// URLs. Currently, hosted apps cannot set cookies in this mode. See // URLs. Currently, hosted apps cannot set cookies in this mode. See
// http://crbug.com/160576. // http://crbug.com/160576.
GURL site_url = SiteInstanceImpl::GetSiteForURL(nullptr, url); GURL site_url = SiteInstance::GetSiteForURL(nullptr, url);
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
SecurityStateMap::iterator state = security_state_.find(child_id); SecurityStateMap::iterator state = security_state_.find(child_id);
...@@ -1153,7 +1153,7 @@ void ChildProcessSecurityPolicyImpl::LockToOrigin(int child_id, ...@@ -1153,7 +1153,7 @@ void ChildProcessSecurityPolicyImpl::LockToOrigin(int child_id,
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
// "gurl" can be currently empty in some cases, such as file://blah. // "gurl" can be currently empty in some cases, such as file://blah.
DCHECK(SiteInstanceImpl::GetSiteForURL(nullptr, gurl) == gurl); DCHECK_EQ(SiteInstanceImpl::DetermineProcessLockURL(nullptr, gurl), gurl);
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
SecurityStateMap::iterator state = security_state_.find(child_id); SecurityStateMap::iterator state = security_state_.find(child_id);
DCHECK(state != security_state_.end()); DCHECK(state != security_state_.end());
......
...@@ -133,7 +133,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, ...@@ -133,7 +133,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_TRUE(main_test_rfh()->navigation_request()); EXPECT_TRUE(main_test_rfh()->navigation_request());
main_test_rfh()->SendNavigate(entry_id, true, kUrl); main_test_rfh()->SendNavigate(entry_id, true, kUrl);
EXPECT_TRUE(main_test_rfh()->is_active()); EXPECT_TRUE(main_test_rfh()->is_active());
EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrl), EXPECT_EQ(SiteInstance::GetSiteForURL(browser_context(), kUrl),
main_test_rfh()->GetSiteInstance()->GetSiteURL()); main_test_rfh()->GetSiteInstance()->GetSiteURL());
EXPECT_EQ(kUrl, contents()->GetLastCommittedURL()); EXPECT_EQ(kUrl, contents()->GetLastCommittedURL());
...@@ -187,7 +187,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, ...@@ -187,7 +187,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Commit the navigation. // Commit the navigation.
navigation->Commit(); navigation->Commit();
EXPECT_TRUE(main_test_rfh()->is_active()); EXPECT_TRUE(main_test_rfh()->is_active());
EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrl2), EXPECT_EQ(SiteInstance::GetSiteForURL(browser_context(), kUrl2),
main_test_rfh()->GetSiteInstance()->GetSiteURL()); main_test_rfh()->GetSiteInstance()->GetSiteURL());
EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL()); EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node)); EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
...@@ -878,7 +878,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, ...@@ -878,7 +878,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Receive the beforeUnload ACK. // Receive the beforeUnload ACK.
main_test_rfh()->SendBeforeUnloadACK(true); main_test_rfh()->SendBeforeUnloadACK(true);
EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node)); EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrl), EXPECT_EQ(SiteInstance::GetSiteForURL(browser_context(), kUrl),
speculative_rfh->GetSiteInstance()->GetSiteURL()); speculative_rfh->GetSiteInstance()->GetSiteURL());
int32_t site_instance_id = speculative_rfh->GetSiteInstance()->GetId(); int32_t site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
int64_t navigation_id = int64_t navigation_id =
...@@ -923,7 +923,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, ...@@ -923,7 +923,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_NE(init_site_instance_id, site_instance_id); EXPECT_NE(init_site_instance_id, site_instance_id);
EXPECT_EQ(init_site_instance_id, main_test_rfh()->GetSiteInstance()->GetId()); EXPECT_EQ(init_site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
EXPECT_NE(speculative_rfh, main_test_rfh()); EXPECT_NE(speculative_rfh, main_test_rfh());
EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrl), EXPECT_EQ(SiteInstance::GetSiteForURL(browser_context(), kUrl),
speculative_rfh->GetSiteInstance()->GetSiteURL()); speculative_rfh->GetSiteInstance()->GetSiteURL());
// Receive the beforeUnload ACK. // Receive the beforeUnload ACK.
...@@ -960,7 +960,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, ...@@ -960,7 +960,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Once commit happens the speculative RenderFrameHost is updated to match the // Once commit happens the speculative RenderFrameHost is updated to match the
// known final SiteInstance. // known final SiteInstance.
EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrlRedirect), EXPECT_EQ(SiteInstance::GetSiteForURL(browser_context(), kUrlRedirect),
speculative_rfh->GetSiteInstance()->GetSiteURL()); speculative_rfh->GetSiteInstance()->GetSiteURL());
int32_t redirect_site_instance_id = int32_t redirect_site_instance_id =
speculative_rfh->GetSiteInstance()->GetId(); speculative_rfh->GetSiteInstance()->GetId();
......
...@@ -1218,7 +1218,8 @@ RenderFrameHostManager::DetermineSiteInstanceForURL( ...@@ -1218,7 +1218,8 @@ RenderFrameHostManager::DetermineSiteInstanceForURL(
// thus use the correct process. // thus use the correct process.
bool use_process_per_site = bool use_process_per_site =
RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) && RenderProcessHost::ShouldUseProcessPerSite(browser_context, dest_url) &&
RenderProcessHostImpl::GetProcessHostForSite(browser_context, dest_url); RenderProcessHostImpl::GetSoleProcessHostForURL(browser_context,
dest_url);
if (current_instance_impl->HasRelatedSiteInstance(dest_url) || if (current_instance_impl->HasRelatedSiteInstance(dest_url) ||
use_process_per_site) { use_process_per_site) {
return SiteInstanceDescriptor(browser_context, dest_url, return SiteInstanceDescriptor(browser_context, dest_url,
......
...@@ -568,10 +568,12 @@ IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, ProcessLimit) { ...@@ -568,10 +568,12 @@ IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, ProcessLimit) {
// Sanity-check IsSuitableHost values for the current processes. // Sanity-check IsSuitableHost values for the current processes.
BrowserContext* browser_context = web_contents()->GetBrowserContext(); BrowserContext* browser_context = web_contents()->GetBrowserContext();
auto is_suitable_host = [browser_context](RenderProcessHost* process, auto is_suitable_host = [browser_context](RenderProcessHost* process,
GURL url) { const GURL& url) {
return RenderProcessHostImpl::IsSuitableHost( GURL site_url(SiteInstance::GetSiteForURL(browser_context, url));
process, browser_context, GURL lock_url(
SiteInstance::GetSiteForURL(browser_context, url)); SiteInstanceImpl::DetermineProcessLockURL(browser_context, url));
return RenderProcessHostImpl::IsSuitableHost(process, browser_context,
site_url, lock_url);
}; };
EXPECT_TRUE(is_suitable_host(foo_process, foo_url)); EXPECT_TRUE(is_suitable_host(foo_process, foo_url));
EXPECT_FALSE(is_suitable_host(foo_process, isolated_foo_url)); EXPECT_FALSE(is_suitable_host(foo_process, isolated_foo_url));
......
...@@ -266,11 +266,16 @@ class CONTENT_EXPORT RenderProcessHostImpl ...@@ -266,11 +266,16 @@ class CONTENT_EXPORT RenderProcessHostImpl
// Implementation of FilterURL below that can be shared with the mock class. // Implementation of FilterURL below that can be shared with the mock class.
static void FilterURL(RenderProcessHost* rph, bool empty_allowed, GURL* url); static void FilterURL(RenderProcessHost* rph, bool empty_allowed, GURL* url);
// Returns true if |host| is suitable for launching a new view with |site_url| // Returns true if |host| is suitable for rendering a page in the given
// in the given |browser_context|. // |browser_context|, where the page would utilize |site_url| as its
// SiteInstance site URL, and its process would be locked to |lock_url|.
// |site_url| and |lock_url| may differ in cases where an effective URL is
// not the actual site that the process is locked to, which happens for
// hosted apps.
static bool IsSuitableHost(RenderProcessHost* host, static bool IsSuitableHost(RenderProcessHost* host,
BrowserContext* browser_context, BrowserContext* browser_context,
const GURL& site_url); const GURL& site_url,
const GURL& lock_url);
// Returns an existing RenderProcessHost for |url| in |browser_context|, // Returns an existing RenderProcessHost for |url| in |browser_context|,
// if one exists. Otherwise a new RenderProcessHost should be created and // if one exists. Otherwise a new RenderProcessHost should be created and
...@@ -278,25 +283,45 @@ class CONTENT_EXPORT RenderProcessHostImpl ...@@ -278,25 +283,45 @@ class CONTENT_EXPORT RenderProcessHostImpl
// This should only be used for process-per-site mode, which can be enabled // This should only be used for process-per-site mode, which can be enabled
// globally with a command line flag or per-site, as determined by // globally with a command line flag or per-site, as determined by
// SiteInstanceImpl::ShouldUseProcessPerSite. // SiteInstanceImpl::ShouldUseProcessPerSite.
static RenderProcessHost* GetProcessHostForSite( // Important: |url| should be a full URL and *not* a site URL.
static RenderProcessHost* GetSoleProcessHostForURL(
BrowserContext* browser_context, BrowserContext* browser_context,
const GURL& url); const GURL& url);
// Registers the given |process| to be used for any instance of |url| // Variant of the above that takes in a SiteInstance site URL and the
// within |browser_context|. // process's origin lock URL, when they are known.
static RenderProcessHost* GetSoleProcessHostForSite(
BrowserContext* browser_context,
const GURL& site_url,
const GURL& lock_url);
// Registers the given |process| to be used for all sites identified by
// |site_instance| within |browser_context|.
// This should only be used for process-per-site mode, which can be enabled // This should only be used for process-per-site mode, which can be enabled
// globally with a command line flag or per-site, as determined by // globally with a command line flag or per-site, as determined by
// SiteInstanceImpl::ShouldUseProcessPerSite. // SiteInstanceImpl::ShouldUseProcessPerSite.
static void RegisterProcessHostForSite( static void RegisterSoleProcessHostForSite(BrowserContext* browser_context,
BrowserContext* browser_context,
RenderProcessHost* process, RenderProcessHost* process,
const GURL& url); SiteInstanceImpl* site_instance);
// Returns a suitable RenderProcessHost to use for |site_instance|. Depending // Returns a suitable RenderProcessHost to use for |site_instance|. Depending
// on the SiteInstance's ProcessReusePolicy and its url, this may be an // on the SiteInstance's ProcessReusePolicy and its url, this may be an
// existing RenderProcessHost or a new one. // existing RenderProcessHost or a new one.
//
// This is the main entrypoint into the process assignment logic, which
// handles all cases. These cases include:
// - process-per-site: see
// RegisterSoleProcessHostForSite/GetSoleProcessHostForSite.
// - TDI: see GetDefaultSubframeProcessHost.
// - REUSE_PENDING_OR_COMMITTED reuse policy (for ServiceWorkers and OOPIFs):
// see FindReusableProcessHostForSiteInstance.
// - normal process reuse when over process limit: see
// GetExistingProcessHost.
// - using the spare RenderProcessHost when possible: see
// MaybeTakeSpareRenderProcessHost.
// - process creation when an existing process couldn't be found: see
// CreateRenderProcessHost.
static RenderProcessHost* GetProcessHostForSiteInstance( static RenderProcessHost* GetProcessHostForSiteInstance(
BrowserContext* browser_context,
SiteInstanceImpl* site_instance); SiteInstanceImpl* site_instance);
// Should be called when |browser_context| is used in a navigation. // Should be called when |browser_context| is used in a navigation.
...@@ -552,20 +577,19 @@ class CONTENT_EXPORT RenderProcessHostImpl ...@@ -552,20 +577,19 @@ class CONTENT_EXPORT RenderProcessHostImpl
// Get an existing RenderProcessHost associated with the given browser // Get an existing RenderProcessHost associated with the given browser
// context, if possible. The renderer process is chosen randomly from // context, if possible. The renderer process is chosen randomly from
// suitable renderers that share the same context and type (determined by the // suitable renderers that share the same context and type (determined by the
// site url). // site url of |site_instance|).
// Returns nullptr if no suitable renderer process is available, in which case // Returns nullptr if no suitable renderer process is available, in which case
// the caller is free to create a new renderer. // the caller is free to create a new renderer.
static RenderProcessHost* GetExistingProcessHost( static RenderProcessHost* GetExistingProcessHost(
content::BrowserContext* browser_context, SiteInstanceImpl* site_instance);
const GURL& site_url);
FRIEND_TEST_ALL_PREFIXES(RenderProcessHostUnitTest, FRIEND_TEST_ALL_PREFIXES(RenderProcessHostUnitTest,
GuestsAreNotSuitableHosts); GuestsAreNotSuitableHosts);
// Returns a RenderProcessHost that is rendering |site_url| in one of its // Returns a RenderProcessHost that is rendering a URL corresponding to
// frames, or that is expecting a navigation to |site_url|. // |site_instance| in one of its frames, or that is expecting a navigation to
static RenderProcessHost* FindReusableProcessHostForSite( // that SiteInstance.
BrowserContext* browser_context, static RenderProcessHost* FindReusableProcessHostForSiteInstance(
const GURL& site_url); SiteInstanceImpl* site_instance);
void CreateMediaStreamDispatcherHost( void CreateMediaStreamDispatcherHost(
MediaStreamManager* media_stream_manager, MediaStreamManager* media_stream_manager,
......
...@@ -42,12 +42,16 @@ TEST_F(RenderProcessHostUnitTest, GuestsAreNotSuitableHosts) { ...@@ -42,12 +42,16 @@ TEST_F(RenderProcessHostUnitTest, GuestsAreNotSuitableHosts) {
MockRenderProcessHost guest_host(browser_context()); MockRenderProcessHost guest_host(browser_context());
guest_host.set_is_for_guests_only(true); guest_host.set_is_for_guests_only(true);
scoped_refptr<SiteInstanceImpl> site_instance =
SiteInstanceImpl::CreateForURL(browser_context(), test_url);
EXPECT_FALSE(RenderProcessHostImpl::IsSuitableHost( EXPECT_FALSE(RenderProcessHostImpl::IsSuitableHost(
&guest_host, browser_context(), test_url)); &guest_host, browser_context(), site_instance->GetSiteURL(),
site_instance->lock_url()));
EXPECT_TRUE(RenderProcessHostImpl::IsSuitableHost( EXPECT_TRUE(RenderProcessHostImpl::IsSuitableHost(
process(), browser_context(), test_url)); process(), browser_context(), site_instance->GetSiteURL(),
EXPECT_EQ(process(), RenderProcessHostImpl::GetExistingProcessHost( site_instance->lock_url()));
browser_context(), test_url)); EXPECT_EQ(process(),
RenderProcessHostImpl::GetExistingProcessHost(site_instance.get()));
} }
#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
......
...@@ -104,7 +104,8 @@ bool SiteInstanceImpl::HasProcess() const { ...@@ -104,7 +104,8 @@ bool SiteInstanceImpl::HasProcess() const {
browsing_instance_->browser_context(); browsing_instance_->browser_context();
if (has_site_ && if (has_site_ &&
RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) && RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) &&
RenderProcessHostImpl::GetProcessHostForSite(browser_context, site_)) { RenderProcessHostImpl::GetSoleProcessHostForSite(browser_context, site_,
lock_url_)) {
return true; return true;
} }
...@@ -133,8 +134,7 @@ RenderProcessHost* SiteInstanceImpl::GetProcess() { ...@@ -133,8 +134,7 @@ RenderProcessHost* SiteInstanceImpl::GetProcess() {
process_reuse_policy_ = ProcessReusePolicy::DEFAULT; process_reuse_policy_ = ProcessReusePolicy::DEFAULT;
} }
process_ = RenderProcessHostImpl::GetProcessHostForSiteInstance( process_ = RenderProcessHostImpl::GetProcessHostForSiteInstance(this);
browser_context, this);
CHECK(process_); CHECK(process_);
process_->AddObserver(this); process_->AddObserver(this);
...@@ -144,8 +144,8 @@ RenderProcessHost* SiteInstanceImpl::GetProcess() { ...@@ -144,8 +144,8 @@ RenderProcessHost* SiteInstanceImpl::GetProcess() {
// at this time, we will register it in SetSite().) // at this time, we will register it in SetSite().)
if (process_reuse_policy_ == ProcessReusePolicy::PROCESS_PER_SITE && if (process_reuse_policy_ == ProcessReusePolicy::PROCESS_PER_SITE &&
has_site_) { has_site_) {
RenderProcessHostImpl::RegisterProcessHostForSite(browser_context, RenderProcessHostImpl::RegisterSoleProcessHostForSite(browser_context,
process_, site_); process_, this);
} }
TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess", TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess",
...@@ -182,8 +182,10 @@ void SiteInstanceImpl::SetSite(const GURL& url) { ...@@ -182,8 +182,10 @@ void SiteInstanceImpl::SetSite(const GURL& url) {
// URL is invalid. // URL is invalid.
has_site_ = true; has_site_ = true;
BrowserContext* browser_context = browsing_instance_->browser_context(); BrowserContext* browser_context = browsing_instance_->browser_context();
site_ = GetSiteForURL(browser_context, url); site_ =
GetSiteForURL(browser_context, url, true /* should_use_effective_urls */);
original_url_ = url; original_url_ = url;
lock_url_ = DetermineProcessLockURL(browser_context, url);
// Now that we have a site, register it with the BrowsingInstance. This // Now that we have a site, register it with the BrowsingInstance. This
// ensures that we won't create another SiteInstance for this site within // ensures that we won't create another SiteInstance for this site within
...@@ -203,8 +205,8 @@ void SiteInstanceImpl::SetSite(const GURL& url) { ...@@ -203,8 +205,8 @@ void SiteInstanceImpl::SetSite(const GURL& url) {
// Ensure the process is registered for this site if necessary. // Ensure the process is registered for this site if necessary.
if (should_use_process_per_site) { if (should_use_process_per_site) {
RenderProcessHostImpl::RegisterProcessHostForSite( RenderProcessHostImpl::RegisterSoleProcessHostForSite(browser_context,
browser_context, process_, site_); process_, this);
} }
} }
} }
...@@ -262,9 +264,13 @@ bool SiteInstanceImpl::HasWrongProcessForURL(const GURL& url) { ...@@ -262,9 +264,13 @@ bool SiteInstanceImpl::HasWrongProcessForURL(const GURL& url) {
// If the site URL is an extension (e.g., for hosted apps or WebUI) but the // If the site URL is an extension (e.g., for hosted apps or WebUI) but the
// process is not (or vice versa), make sure we notice and fix it. // process is not (or vice versa), make sure we notice and fix it.
GURL site_url = GetSiteForURL(browsing_instance_->browser_context(), url); GURL site_url =
SiteInstance::GetSiteForURL(browsing_instance_->browser_context(), url);
GURL origin_lock =
DetermineProcessLockURL(browsing_instance_->browser_context(), url);
return !RenderProcessHostImpl::IsSuitableHost( return !RenderProcessHostImpl::IsSuitableHost(
GetProcess(), browsing_instance_->browser_context(), site_url); GetProcess(), browsing_instance_->browser_context(), site_url,
origin_lock);
} }
scoped_refptr<SiteInstanceImpl> scoped_refptr<SiteInstanceImpl>
...@@ -415,12 +421,32 @@ bool SiteInstanceImpl::IsSameWebSite(BrowserContext* browser_context, ...@@ -415,12 +421,32 @@ bool SiteInstanceImpl::IsSameWebSite(BrowserContext* browser_context,
// static // static
GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context, GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
const GURL& real_url) { const GURL& url) {
// By default, GetSiteForURL will resolve |real_url| to an effective URL
// before computing its site.
return SiteInstanceImpl::GetSiteForURL(browser_context, url,
true /* should_use_effective_urls */);
}
// static
GURL SiteInstanceImpl::DetermineProcessLockURL(BrowserContext* browser_context,
const GURL& url) {
// For the process lock URL, convert |url| to a site without resolving |url|
// to an effective URL.
return SiteInstanceImpl::GetSiteForURL(browser_context, url,
false /* should_use_effective_urls */);
}
GURL SiteInstanceImpl::GetSiteForURL(BrowserContext* browser_context,
const GURL& real_url,
bool should_use_effective_urls) {
// TODO(fsamuel, creis): For some reason appID is not recognized as a host. // TODO(fsamuel, creis): For some reason appID is not recognized as a host.
if (real_url.SchemeIs(kGuestScheme)) if (real_url.SchemeIs(kGuestScheme))
return real_url; return real_url;
GURL url = SiteInstanceImpl::GetEffectiveURL(browser_context, real_url); GURL url = should_use_effective_urls
? SiteInstanceImpl::GetEffectiveURL(browser_context, real_url)
: real_url;
url::Origin origin = url::Origin::Create(url); url::Origin origin = url::Origin::Create(url);
// Isolated origins should use the full origin as their site URL. A subdomain // Isolated origins should use the full origin as their site URL. A subdomain
...@@ -522,7 +548,7 @@ bool SiteInstanceImpl::DoesSiteRequireDedicatedProcess( ...@@ -522,7 +548,7 @@ bool SiteInstanceImpl::DoesSiteRequireDedicatedProcess(
return true; return true;
// Always require a dedicated process for isolated origins. // Always require a dedicated process for isolated origins.
GURL site_url = GetSiteForURL(browser_context, url); GURL site_url = SiteInstance::GetSiteForURL(browser_context, url);
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
if (policy->IsIsolatedOrigin(url::Origin::Create(site_url))) if (policy->IsIsolatedOrigin(url::Origin::Create(site_url)))
return true; return true;
...@@ -605,7 +631,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() { ...@@ -605,7 +631,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() {
ChildProcessSecurityPolicyImpl* policy = ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance(); ChildProcessSecurityPolicyImpl::GetInstance();
auto lock_state = policy->CheckOriginLock(process_->GetID(), site_); auto lock_state = policy->CheckOriginLock(process_->GetID(), lock_url());
if (ShouldLockToOrigin(GetBrowserContext(), site_)) { if (ShouldLockToOrigin(GetBrowserContext(), site_)) {
// Sanity check that this won't try to assign an origin lock to a <webview> // Sanity check that this won't try to assign an origin lock to a <webview>
// process, which can't be locked. // process, which can't be locked.
...@@ -617,7 +643,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() { ...@@ -617,7 +643,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() {
// strong protection. If only some sites are isolated, we need // strong protection. If only some sites are isolated, we need
// additional logic to prevent the non-isolated sites from requesting // additional logic to prevent the non-isolated sites from requesting
// resources for isolated sites. https://crbug.com/509125 // resources for isolated sites. https://crbug.com/509125
process_->LockToOrigin(site_); process_->LockToOrigin(lock_url());
break; break;
} }
case CheckOriginLockResult::HAS_WRONG_LOCK: case CheckOriginLockResult::HAS_WRONG_LOCK:
...@@ -628,7 +654,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() { ...@@ -628,7 +654,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() {
base::debug::SetCrashKeyString( base::debug::SetCrashKeyString(
bad_message::GetKilledProcessOriginLockKey(), bad_message::GetKilledProcessOriginLockKey(),
policy->GetOriginLock(process_->GetID()).spec()); policy->GetOriginLock(process_->GetID()).spec());
CHECK(false) << "Trying to lock a process to " << site_ CHECK(false) << "Trying to lock a process to " << lock_url()
<< " but the process is already locked to " << " but the process is already locked to "
<< policy->GetOriginLock(process_->GetID()); << policy->GetOriginLock(process_->GetID());
break; break;
......
...@@ -116,11 +116,29 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance, ...@@ -116,11 +116,29 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
// May be empty if this SiteInstance does not have a |site_|. // May be empty if this SiteInstance does not have a |site_|.
const GURL& original_url() { return original_url_; } const GURL& original_url() { return original_url_; }
// Returns the URL which should be used in a LockToOrigin call for this
// SiteInstance's process.
const GURL& lock_url() { return lock_url_; }
// True if |url| resolves to an effective URL that is different from |url|. // True if |url| resolves to an effective URL that is different from |url|.
// See GetEffectiveURL(). This will be true for hosted apps as well as NTP // See GetEffectiveURL(). This will be true for hosted apps as well as NTP
// URLs. // URLs.
static bool HasEffectiveURL(BrowserContext* browser_context, const GURL& url); static bool HasEffectiveURL(BrowserContext* browser_context, const GURL& url);
// Returns the site for the given URL, which includes only the scheme and
// registered domain. Returns an empty GURL if the URL has no host.
// |use_effective_urls| specifies whether to resolve |url| to an effective
// URL (via ContentBrowserClient::GetEffectiveURL()) before determining the
// site.
static GURL GetSiteForURL(BrowserContext* context,
const GURL& url,
bool use_effective_urls);
// Returns the URL to which a process should be locked for the given URL.
// This is computed similarly to the site URL (see GetSiteForURL), but
// without resolving effective URLs.
static GURL DetermineProcessLockURL(BrowserContext* context, const GURL& url);
// Returns the SiteInstance, related to this one, that should be used // Returns the SiteInstance, related to this one, that should be used
// for subframes when an oopif is required, but a dedicated process is not. // for subframes when an oopif is required, but a dedicated process is not.
// This SiteInstance will be created if it doesn't already exist. There is // This SiteInstance will be created if it doesn't already exist. There is
...@@ -275,6 +293,12 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance, ...@@ -275,6 +293,12 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
// The URL which was used to set the |site_| for this SiteInstance. // The URL which was used to set the |site_| for this SiteInstance.
GURL original_url_; GURL original_url_;
// The URL to use when locking a process to this SiteInstance's site via
// LockToOrigin(). This is the same as |site_| except for cases involving
// effective URLs, such as hosted apps. In those cases, this URL is a site
// URL that is computed without the use of effective URLs.
GURL lock_url_;
// The ProcessReusePolicy to use when creating a RenderProcessHost for this // The ProcessReusePolicy to use when creating a RenderProcessHost for this
// SiteInstance. // SiteInstance.
ProcessReusePolicy process_reuse_policy_; ProcessReusePolicy process_reuse_policy_;
......
...@@ -170,7 +170,9 @@ class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance> { ...@@ -170,7 +170,9 @@ class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance> {
const GURL& dest_url); const GURL& dest_url);
// Returns the site for the given URL, which includes only the scheme and // Returns the site for the given URL, which includes only the scheme and
// registered domain. Returns an empty GURL if the URL has no host. // registered domain. Returns an empty GURL if the URL has no host. Prior to
// determining the site, |url| is resolved to an effective URL via
// ContentBrowserClient::GetEffectiveURL().
static GURL GetSiteForURL(BrowserContext* context, const GURL& url); static GURL GetSiteForURL(BrowserContext* context, const GURL& url);
protected: protected:
......
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