summaryrefslogtreecommitdiff
path: root/chromium/content/browser/site_instance_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/site_instance_impl.cc')
-rw-r--r--chromium/content/browser/site_instance_impl.cc123
1 files changed, 91 insertions, 32 deletions
diff --git a/chromium/content/browser/site_instance_impl.cc b/chromium/content/browser/site_instance_impl.cc
index 91ae83aaf6a..618f09320ff 100644
--- a/chromium/content/browser/site_instance_impl.cc
+++ b/chromium/content/browser/site_instance_impl.cc
@@ -54,6 +54,29 @@ const GURL& SiteInstanceImpl::GetDefaultSiteURL() {
return default_site_url.Get().url;
}
+// static
+SiteInfo SiteInfo::CreateForErrorPage() {
+ return SiteInfo(GURL(content::kUnreachableWebDataURL));
+}
+
+SiteInfo::SiteInfo(const GURL& site_url) : site_url_(site_url) {}
+
+bool SiteInfo::operator==(const SiteInfo& other) const {
+ return site_url_ == other.site_url_;
+}
+
+bool SiteInfo::operator!=(const SiteInfo& other) const {
+ return site_url_ != other.site_url_;
+}
+
+std::string SiteInfo::GetDebugString() const {
+ return site_url_.possibly_invalid_spec();
+}
+
+std::ostream& operator<<(std::ostream& out, const SiteInfo& site_info) {
+ return out << site_info.GetDebugString();
+}
+
SiteInstanceImpl::SiteInstanceImpl(BrowsingInstance* browsing_instance)
: id_(next_site_instance_id_++),
active_frame_count_(0),
@@ -262,7 +285,7 @@ bool SiteInstanceImpl::HasProcess() {
// existing process that we would use if GetProcess() were called.
BrowserContext* browser_context = browsing_instance_->GetBrowserContext();
if (has_site_ &&
- RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_) &&
+ RenderProcessHostImpl::ShouldUseProcessPerSite(browser_context, site_) &&
RenderProcessHostImpl::GetSoleProcessHostForSite(
GetIsolationContext(), site_, lock_url_, IsGuest())) {
return true;
@@ -286,7 +309,7 @@ RenderProcessHost* SiteInstanceImpl::GetProcess() {
// Check if the ProcessReusePolicy should be updated.
bool should_use_process_per_site =
has_site_ &&
- RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_);
+ RenderProcessHostImpl::ShouldUseProcessPerSite(browser_context, site_);
if (should_use_process_per_site) {
process_reuse_policy_ = ProcessReusePolicy::PROCESS_PER_SITE;
} else if (process_reuse_policy_ == ProcessReusePolicy::PROCESS_PER_SITE) {
@@ -303,22 +326,30 @@ RenderProcessHost* SiteInstanceImpl::GetProcess() {
void SiteInstanceImpl::ReuseCurrentProcessIfPossible(
RenderProcessHost* current_process) {
- if (IsGuest() || HasProcess() || RequiresDedicatedProcess())
+ DCHECK(!IsGuest());
+ if (HasProcess())
return;
+
// We should not reuse the current process if the destination uses
// process-per-site. Note that this includes the case where the process for
// the site is not there yet (so we're going to create a new process).
// Note also that this does not apply for the reverse case: if the current
// process is used for a process-per-site site, it is ok to reuse this for the
// new page (regardless of the site).
- if (HasSite() && RenderProcessHost::ShouldUseProcessPerSite(
- browsing_instance_->GetBrowserContext(), GetSiteURL()))
+ if (HasSite() && RenderProcessHostImpl::ShouldUseProcessPerSite(
+ browsing_instance_->GetBrowserContext(), site_)) {
return;
+ }
+
+ // Do not reuse the process if it's not suitable for this SiteInstance. For
+ // example, this won't allow reusing a process if it's locked to a site that's
+ // different from this SiteInstance's site.
if (!current_process->MayReuseHost() ||
!RenderProcessHostImpl::IsSuitableHost(
- current_process, GetIsolationContext(), GetSiteURL(), lock_url(),
- IsGuest()))
+ current_process, GetIsolationContext(), site_.site_url(), lock_url(),
+ IsGuest())) {
return;
+ }
SetProcessInternal(current_process);
}
@@ -391,7 +422,7 @@ void SiteInstanceImpl::SetSiteAndLockInternal(const GURL& site_url,
// Remember that this SiteInstance has been used to load a URL, even if the
// URL is invalid.
has_site_ = true;
- site_ = site_url;
+ site_ = SiteInfo(site_url);
lock_url_ = lock_url;
// Check if |site_url| corresponds to an opt-in isolated origin, and if so,
@@ -419,7 +450,7 @@ void SiteInstanceImpl::SetSiteAndLockInternal(const GURL& site_url,
// Update the process reuse policy based on the site.
BrowserContext* browser_context = browsing_instance_->GetBrowserContext();
bool should_use_process_per_site =
- RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_);
+ RenderProcessHostImpl::ShouldUseProcessPerSite(browser_context, site_);
if (should_use_process_per_site) {
process_reuse_policy_ = ProcessReusePolicy::PROCESS_PER_SITE;
}
@@ -445,6 +476,10 @@ void SiteInstanceImpl::ConvertToDefaultOrSetSite(const GURL& url) {
}
const GURL& SiteInstanceImpl::GetSiteURL() {
+ return site_.site_url();
+}
+
+const SiteInfo& SiteInstanceImpl::GetSiteInfo() {
return site_;
}
@@ -486,7 +521,7 @@ bool SiteInstanceImpl::IsSuitableForURL(const GURL& url) {
// Renderer-initiated navigations will handle about:blank navigations
// elsewhere and leave them in the source SiteInstance, along with
// about:srcdoc and data:.
- if (url.IsAboutBlank() && site_ != GURL(kUnreachableWebDataURL))
+ if (url.IsAboutBlank() && site_ != SiteInfo::CreateForErrorPage())
return true;
// If the site URL is an extension (e.g., for hosted apps or WebUI) but the
@@ -499,6 +534,7 @@ bool SiteInstanceImpl::IsSuitableForURL(const GURL& url) {
// GetRelatedSiteInstance(url).
browsing_instance_->GetSiteAndLockForURL(
url, /* allow_default_instance */ true, &site_url, &origin_lock);
+ SiteInfo site_info(site_url);
// If this is a default SiteInstance and the BrowsingInstance gives us a
// non-default site URL even when we explicitly allow the default SiteInstance
@@ -511,7 +547,7 @@ bool SiteInstanceImpl::IsSuitableForURL(const GURL& url) {
// frame is a site that should be in the default SiteInstance and the
// SiteInstance associated with that frame is initially a SiteInstance with
// no site URL set.
- if (IsDefaultSiteInstance() && site_url != GetSiteURL())
+ if (IsDefaultSiteInstance() && site_info != site_)
return false;
// Note that HasProcess() may return true if process_ is null, in
@@ -527,7 +563,7 @@ bool SiteInstanceImpl::IsSuitableForURL(const GURL& url) {
// If there is no process but there is a site, then the process must have
// been discarded after we navigated away. If the site URLs match, then it
// is safe to use this SiteInstance.
- if (GetSiteURL() == site_url)
+ if (site_ == site_info)
return true;
// If the site URLs do not match, but neither this SiteInstance nor the
@@ -553,7 +589,8 @@ bool SiteInstanceImpl::RequiresDedicatedProcess() {
if (!has_site_)
return false;
- return DoesSiteURLRequireDedicatedProcess(GetIsolationContext(), site_);
+ return DoesSiteURLRequireDedicatedProcess(GetIsolationContext(),
+ site_.site_url());
}
void SiteInstanceImpl::IncrementActiveFrameCount() {
@@ -628,14 +665,16 @@ bool SiteInstanceImpl::IsSameSiteWithURL(const GURL& url) {
// TODO(acolwell): Remove HasSiteInstance() call once we have a way to
// prevent SiteInstances with no site URL from being used for URLs
// that should be routed to the default SiteInstance.
- DCHECK_EQ(site_, GetDefaultSiteURL());
- return site_ == GetSiteForURLInternal(GetIsolationContext(), url,
- true /* should_use_effective_urls */,
- true /* allow_default_site_url */) &&
+ DCHECK_EQ(site_.site_url(), GetDefaultSiteURL());
+ return site_.site_url() ==
+ GetSiteForURLInternal(GetIsolationContext(), url,
+ true /* should_use_effective_urls */,
+ true /* allow_default_site_url */) &&
!browsing_instance_->HasSiteInstance(url);
}
- return SiteInstanceImpl::IsSameSite(GetIsolationContext(), site_, url,
+ return SiteInstanceImpl::IsSameSite(GetIsolationContext(), site_.site_url(),
+ url,
true /* should_compare_effective_urls */);
}
@@ -741,9 +780,10 @@ bool SiteInstanceImpl::IsSameSite(const IsolationContext& isolation_context,
bool SiteInstanceImpl::DoesSiteForURLMatch(const GURL& url) {
// Note: The |allow_default_site_url| value used here MUST match the value
// used in CreateForURL().
- return site_ == GetSiteForURLInternal(GetIsolationContext(), url,
- true /* should_use_effective_urls */,
- true /* allow_default_site_url */);
+ return site_.site_url() ==
+ GetSiteForURLInternal(GetIsolationContext(), url,
+ true /* should_use_effective_urls */,
+ true /* allow_default_site_url */);
}
void SiteInstanceImpl::PreventOptInOriginIsolation(
@@ -769,8 +809,17 @@ GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
// where needed. Eventually, GetSiteForURL should always require an
// IsolationContext to be passed in, and this implementation should just
// become SiteInstanceImpl::GetSiteForURL.
- return SiteInstanceImpl::GetSiteForURL(IsolationContext(browser_context),
- url);
+ return SiteInstanceImpl::ComputeSiteInfo(IsolationContext(browser_context),
+ url)
+ .site_url();
+}
+
+SiteInfo SiteInstanceImpl::ComputeSiteInfo(
+ const IsolationContext& isolation_context,
+ const GURL& url) {
+ // This function will expand as more information, such as site-/origin-keying,
+ // are included in SiteInfo.
+ return SiteInfo(GetSiteForURL(isolation_context, url));
}
// static
@@ -916,7 +965,7 @@ GURL SiteInstanceImpl::GetSiteForURLInternal(
}
if (allow_default_site_url &&
- CanBePlacedInDefaultSiteInstance(isolation_context, url, site_url)) {
+ CanBePlacedInDefaultSiteInstance(isolation_context, real_url, site_url)) {
return GetDefaultSiteURL();
}
return site_url;
@@ -992,7 +1041,8 @@ bool SiteInstanceImpl::DoesSiteRequireDedicatedProcess(
return SiteIsolationPolicy::UseDedicatedProcessesForAllSites() ||
DoesSiteURLRequireDedicatedProcess(
isolation_context,
- SiteInstanceImpl::GetSiteForURL(isolation_context, url));
+ SiteInstanceImpl::ComputeSiteInfo(isolation_context, url)
+ .site_url());
}
// static
@@ -1047,7 +1097,8 @@ bool SiteInstanceImpl::ShouldLockToOrigin(
DCHECK(browser_context);
// Don't lock to origin in --single-process mode, since this mode puts
- // cross-site pages into the same process.
+ // cross-site pages into the same process. Note that this also covers the
+ // single-process mode in Android Webview.
if (RenderProcessHost::run_renderer_in_process())
return false;
@@ -1062,6 +1113,14 @@ bool SiteInstanceImpl::ShouldLockToOrigin(
if (is_guest)
return false;
+ // Most WebUI processes should be locked on all platforms. The only exception
+ // is NTP, handled via the separate callout to the embedder.
+ const auto& webui_schemes = URLDataManagerBackend::GetWebUISchemes();
+ if (base::Contains(webui_schemes, site_url.scheme())) {
+ return GetContentClient()->browser()->DoesWebUISchemeRequireProcessLock(
+ site_url.scheme());
+ }
+
// TODO(creis, nick): Until we can handle sites with effective URLs at the
// call sites of ChildProcessSecurityPolicy::CanAccessDataForOrigin, we
// must give the embedder a chance to exempt some sites to avoid process
@@ -1076,13 +1135,13 @@ bool SiteInstanceImpl::ShouldLockToOrigin(
// static
base::Optional<url::Origin> SiteInstanceImpl::GetRequestInitiatorSiteLock(
- GURL site_url) {
+ GURL lock_url) {
// The following schemes are safe for sites that require a process lock:
// - data: - locking |request_initiator| to an opaque origin
// - http/https - requiring |request_initiator| to match |site_url| with
// DomainIs (i.e. suffix-based) comparison.
- if (site_url.SchemeIsHTTPOrHTTPS() || site_url.SchemeIs(url::kDataScheme))
- return url::Origin::Create(site_url);
+ if (lock_url.SchemeIsHTTPOrHTTPS() || lock_url.SchemeIs(url::kDataScheme))
+ return url::Origin::Create(lock_url);
// Other schemes might not be safe to use as |request_initiator_site_lock|.
// One example is chrome-guest://...
@@ -1120,7 +1179,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() {
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
GURL process_lock = policy->GetOriginLock(process_->GetID());
- if (ShouldLockToOrigin(GetIsolationContext(), site_, IsGuest())) {
+ if (ShouldLockToOrigin(GetIsolationContext(), site_.site_url(), IsGuest())) {
// Sanity check that this won't try to assign an origin lock to a <webview>
// process, which can't be locked.
CHECK(!process_->IsForGuestsOnly());
@@ -1137,7 +1196,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() {
// We should never attempt to reassign a different origin lock to a
// process.
base::debug::SetCrashKeyString(bad_message::GetRequestedSiteURLKey(),
- site_.possibly_invalid_spec());
+ site_.GetDebugString());
policy->LogKilledProcessOriginLock(process_->GetID());
CHECK(false) << "Trying to lock a process to " << lock_url()
<< " but the process is already locked to " << process_lock;
@@ -1151,7 +1210,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() {
// does.
if (!process_lock.is_empty()) {
base::debug::SetCrashKeyString(bad_message::GetRequestedSiteURLKey(),
- site_.possibly_invalid_spec());
+ site_.GetDebugString());
policy->LogKilledProcessOriginLock(process_->GetID());
CHECK(false) << "Trying to commit non-isolated site " << site_
<< " in process locked to " << process_lock;