Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: content/browser/site_instance_impl.cc

Issue 2921063003: Fix process reuse for dedicated processes when over process limit. (Closed)
Patch Set: Fix IsSuitableHost for sites that require a dedicated process but don't set an origin lock Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698