Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/site_instance_impl.h" | 5 #include "content/browser/site_instance_impl.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "content/browser/browsing_instance.h" | 9 #include "content/browser/browsing_instance.h" |
| 10 #include "content/browser/child_process_security_policy_impl.h" | 10 #include "content/browser/child_process_security_policy_impl.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 has_site_) { | 117 has_site_) { |
| 118 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context, | 118 RenderProcessHostImpl::RegisterProcessHostForSite(browser_context, |
| 119 process_, site_); | 119 process_, site_); |
| 120 } | 120 } |
| 121 | 121 |
| 122 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess", | 122 TRACE_EVENT2("navigation", "SiteInstanceImpl::GetProcess", |
| 123 "site id", id_, "process id", process_->GetID()); | 123 "site id", id_, "process id", process_->GetID()); |
| 124 GetContentClient()->browser()->SiteInstanceGotProcess(this); | 124 GetContentClient()->browser()->SiteInstanceGotProcess(this); |
| 125 | 125 |
| 126 if (has_site_) | 126 if (has_site_) |
| 127 LockToOrigin(); | 127 LockToOriginIfNeeded(); |
| 128 } | 128 } |
| 129 DCHECK(process_); | 129 DCHECK(process_); |
| 130 | 130 |
| 131 return process_; | 131 return process_; |
| 132 } | 132 } |
| 133 | 133 |
| 134 void SiteInstanceImpl::SetSite(const GURL& url) { | 134 void SiteInstanceImpl::SetSite(const GURL& url) { |
| 135 TRACE_EVENT2("navigation", "SiteInstanceImpl::SetSite", | 135 TRACE_EVENT2("navigation", "SiteInstanceImpl::SetSite", |
| 136 "site id", id_, "url", url.possibly_invalid_spec()); | 136 "site id", id_, "url", url.possibly_invalid_spec()); |
| 137 // A SiteInstance's site should not change. | 137 // A SiteInstance's site should not change. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 154 browsing_instance_->RegisterSiteInstance(this); | 154 browsing_instance_->RegisterSiteInstance(this); |
| 155 | 155 |
| 156 // Update the process reuse policy based on the site. | 156 // Update the process reuse policy based on the site. |
| 157 bool should_use_process_per_site = | 157 bool should_use_process_per_site = |
| 158 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_); | 158 RenderProcessHost::ShouldUseProcessPerSite(browser_context, site_); |
| 159 if (should_use_process_per_site) { | 159 if (should_use_process_per_site) { |
| 160 process_reuse_policy_ = ProcessReusePolicy::PROCESS_PER_SITE; | 160 process_reuse_policy_ = ProcessReusePolicy::PROCESS_PER_SITE; |
| 161 } | 161 } |
| 162 | 162 |
| 163 if (process_) { | 163 if (process_) { |
| 164 LockToOrigin(); | 164 LockToOriginIfNeeded(); |
| 165 | 165 |
| 166 // Ensure the process is registered for this site if necessary. | 166 // Ensure the process is registered for this site if necessary. |
| 167 if (should_use_process_per_site) { | 167 if (should_use_process_per_site) { |
| 168 RenderProcessHostImpl::RegisterProcessHostForSite( | 168 RenderProcessHostImpl::RegisterProcessHostForSite( |
| 169 browser_context, process_, site_); | 169 browser_context, process_, site_); |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 } | 172 } |
| 173 | 173 |
| 174 const GURL& SiteInstanceImpl::GetSiteURL() const { | 174 const GURL& SiteInstanceImpl::GetSiteURL() const { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 204 // We want to use such a process in the IsSuitableHost check, so we | 204 // We want to use such a process in the IsSuitableHost check, so we |
| 205 // may end up assigning process_ in the GetProcess() call below. | 205 // may end up assigning process_ in the GetProcess() call below. |
| 206 if (!HasProcess()) | 206 if (!HasProcess()) |
| 207 return false; | 207 return false; |
| 208 | 208 |
| 209 // If the URL to navigate to can be associated with any site instance, | 209 // If the URL to navigate to can be associated with any site instance, |
| 210 // we want to keep it in the same process. | 210 // we want to keep it in the same process. |
| 211 if (IsRendererDebugURL(url)) | 211 if (IsRendererDebugURL(url)) |
| 212 return false; | 212 return false; |
| 213 | 213 |
| 214 // Any process can host an about:blank URL. | |
| 215 if (url == url::kAboutBlankURL) | |
| 216 return false; | |
| 217 | |
| 214 // If the site URL is an extension (e.g., for hosted apps or WebUI) but the | 218 // If the site URL is an extension (e.g., for hosted apps or WebUI) but the |
| 215 // process is not (or vice versa), make sure we notice and fix it. | 219 // process is not (or vice versa), make sure we notice and fix it. |
| 216 GURL site_url = GetSiteForURL(browsing_instance_->browser_context(), url); | 220 GURL site_url = GetSiteForURL(browsing_instance_->browser_context(), url); |
| 217 return !RenderProcessHostImpl::IsSuitableHost( | 221 return !RenderProcessHostImpl::IsSuitableHost( |
| 218 GetProcess(), browsing_instance_->browser_context(), site_url); | 222 GetProcess(), browsing_instance_->browser_context(), site_url); |
| 219 } | 223 } |
| 220 | 224 |
| 221 scoped_refptr<SiteInstanceImpl> | 225 scoped_refptr<SiteInstanceImpl> |
| 222 SiteInstanceImpl::GetDefaultSubframeSiteInstance() { | 226 SiteInstanceImpl::GetDefaultSubframeSiteInstance() { |
| 223 return browsing_instance_->GetDefaultSubframeSiteInstance(); | 227 return browsing_instance_->GetDefaultSubframeSiteInstance(); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 395 // (blob and filesystem) work properly. | 399 // (blob and filesystem) work properly. |
| 396 if (GetContentClient()->IsSupplementarySiteIsolationModeEnabled() && | 400 if (GetContentClient()->IsSupplementarySiteIsolationModeEnabled() && |
| 397 GetContentClient()->browser()->DoesSiteRequireDedicatedProcess( | 401 GetContentClient()->browser()->DoesSiteRequireDedicatedProcess( |
| 398 browser_context, site_url)) { | 402 browser_context, site_url)) { |
| 399 return true; | 403 return true; |
| 400 } | 404 } |
| 401 | 405 |
| 402 return false; | 406 return false; |
| 403 } | 407 } |
| 404 | 408 |
| 409 // static | |
| 410 bool SiteInstanceImpl::ShouldLockToOrigin(BrowserContext* browser_context, | |
| 411 GURL site_url) { | |
| 412 if (!DoesSiteRequireDedicatedProcess(browser_context, site_url)) | |
| 413 return false; | |
| 414 | |
| 415 // Guest processes cannot be locked to its site because guests always have | |
|
Charlie Reis
2017/06/17 23:13:53
nit: s/its/their/
alexmos
2017/06/19 20:03:59
Done.
| |
| 416 // a fixed SiteInstance. The site of GURLs a guest loads doesn't match that | |
| 417 // SiteInstance. So we skip locking the guest process to the site. | |
| 418 // TODO(ncarter): Remove this exclusion once we can make origin lock per | |
| 419 // RenderFrame routing id. | |
| 420 if (site_url.SchemeIs(content::kGuestScheme)) | |
| 421 return false; | |
| 422 | |
| 423 // TODO(creis, nick) https://crbug.com/510588 Chrome UI pages use the same | |
|
Charlie Reis
2017/06/17 23:13:53
Oh, I see. Actually, dbeam@ was just working on a
alexmos
2017/06/19 20:03:58
Ack - thanks for the pointer!
| |
| 424 // site (chrome://chrome), so they can't be locked because the site being | |
| 425 // loaded doesn't match the SiteInstance. | |
| 426 if (site_url.SchemeIs(content::kChromeUIScheme)) | |
| 427 return false; | |
| 428 | |
| 429 // TODO(creis, nick): Until we can handle sites with effective URLs at the | |
| 430 // call sites of ChildProcessSecurityPolicy::CanAccessDataForOrigin, we | |
| 431 // must give the embedder a chance to exempt some sites to avoid process | |
| 432 // kills. | |
| 433 if (!GetContentClient()->browser()->ShouldLockToOrigin(browser_context, | |
| 434 site_url)) { | |
| 435 return false; | |
| 436 } | |
| 437 | |
| 438 return true; | |
| 439 } | |
| 440 | |
| 405 void SiteInstanceImpl::RenderProcessHostDestroyed(RenderProcessHost* host) { | 441 void SiteInstanceImpl::RenderProcessHostDestroyed(RenderProcessHost* host) { |
| 406 DCHECK_EQ(process_, host); | 442 DCHECK_EQ(process_, host); |
| 407 process_->RemoveObserver(this); | 443 process_->RemoveObserver(this); |
| 408 process_ = nullptr; | 444 process_ = nullptr; |
| 409 } | 445 } |
| 410 | 446 |
| 411 void SiteInstanceImpl::RenderProcessWillExit(RenderProcessHost* host) { | 447 void SiteInstanceImpl::RenderProcessWillExit(RenderProcessHost* host) { |
| 412 // TODO(nick): http://crbug.com/575400 - RenderProcessWillExit might not serve | 448 // TODO(nick): http://crbug.com/575400 - RenderProcessWillExit might not serve |
| 413 // any purpose here. | 449 // any purpose here. |
| 414 for (auto& observer : observers_) | 450 for (auto& observer : observers_) |
| 415 observer.RenderProcessGone(this); | 451 observer.RenderProcessGone(this); |
| 416 } | 452 } |
| 417 | 453 |
| 418 void SiteInstanceImpl::RenderProcessExited(RenderProcessHost* host, | 454 void SiteInstanceImpl::RenderProcessExited(RenderProcessHost* host, |
| 419 base::TerminationStatus status, | 455 base::TerminationStatus status, |
| 420 int exit_code) { | 456 int exit_code) { |
| 421 for (auto& observer : observers_) | 457 for (auto& observer : observers_) |
| 422 observer.RenderProcessGone(this); | 458 observer.RenderProcessGone(this); |
| 423 } | 459 } |
| 424 | 460 |
| 425 void SiteInstanceImpl::LockToOrigin() { | 461 void SiteInstanceImpl::LockToOriginIfNeeded() { |
| 462 DCHECK(HasSite()); | |
| 463 | |
| 464 // From now on, this process should be considered "tainted" for future | |
| 465 // process reuse decisions: | |
| 466 // (1) If |site_| required a dedicated process, this SiteInstance's process | |
| 467 // can only host URLs for the same site. | |
| 468 // (2) Even if |site_| does not require a dedicated process, this | |
| 469 // SiteInstance's process still cannot be reused to host other sites | |
| 470 // requiring dedicated sites in the future. | |
| 471 // We can get here either when we commit a URL into a SiteInstance that does | |
| 472 // not yet have a site, or when we create a process for a SiteInstance with a | |
| 473 // preassigned site. | |
| 474 process_->SetIsUsed(); | |
| 475 | |
| 426 // TODO(nick): When all sites are isolated, this operation provides strong | 476 // TODO(nick): When all sites are isolated, this operation provides strong |
| 427 // protection. If only some sites are isolated, we need additional logic to | 477 // protection. If only some sites are isolated, we need additional logic to |
| 428 // prevent the non-isolated sites from requesting resources for isolated | 478 // prevent the non-isolated sites from requesting resources for isolated |
| 429 // sites. https://crbug.com/509125 | 479 // sites. https://crbug.com/509125 |
| 430 if (RequiresDedicatedProcess()) { | 480 if (ShouldLockToOrigin(GetBrowserContext(), site_)) { |
| 431 // Guest processes cannot be locked to its site because guests always have | |
| 432 // a fixed SiteInstance. The site of GURLs a guest loads doesn't match that | |
| 433 // SiteInstance. So we skip locking the guest process to the site. | |
| 434 // TODO(ncarter): Remove this exclusion once we can make origin lock per | |
| 435 // RenderFrame routing id. | |
| 436 if (site_.SchemeIs(content::kGuestScheme)) | |
| 437 return; | |
| 438 | |
| 439 // TODO(creis, nick) https://crbug.com/510588 Chrome UI pages use the same | |
| 440 // site (chrome://chrome), so they can't be locked because the site being | |
| 441 // loaded doesn't match the SiteInstance. | |
| 442 if (site_.SchemeIs(content::kChromeUIScheme)) | |
| 443 return; | |
| 444 | |
| 445 // TODO(creis, nick): Until we can handle sites with effective URLs at the | |
| 446 // call sites of ChildProcessSecurityPolicy::CanAccessDataForOrigin, we | |
| 447 // must give the embedder a chance to exempt some sites to avoid process | |
| 448 // kills. | |
| 449 if (!GetContentClient()->browser()->ShouldLockToOrigin( | |
| 450 browsing_instance_->browser_context(), site_)) | |
| 451 return; | |
| 452 | |
| 453 ChildProcessSecurityPolicyImpl* policy = | 481 ChildProcessSecurityPolicyImpl* policy = |
| 454 ChildProcessSecurityPolicyImpl::GetInstance(); | 482 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 455 policy->LockToOrigin(process_->GetID(), site_); | 483 policy->LockToOrigin(process_->GetID(), site_); |
| 456 } | 484 } |
| 457 } | 485 } |
| 458 | 486 |
| 459 } // namespace content | 487 } // namespace content |
| OLD | NEW |