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 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading | 5 // See http://dev.chromium.org/developers/design-documents/multi-process-resourc e-loading |
| 6 | 6 |
| 7 #include "content/browser/loader/resource_dispatcher_host_impl.h" | 7 #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| 8 | 8 |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 | 10 |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 | 288 |
| 289 // Consults the RendererSecurity policy to determine whether the | 289 // Consults the RendererSecurity policy to determine whether the |
| 290 // ResourceDispatcherHostImpl should service this request. A request might be | 290 // ResourceDispatcherHostImpl should service this request. A request might be |
| 291 // disallowed if the renderer is not authorized to retrieve the request URL or | 291 // disallowed if the renderer is not authorized to retrieve the request URL or |
| 292 // if the renderer is attempting to upload an unauthorized file. | 292 // if the renderer is attempting to upload an unauthorized file. |
| 293 bool ShouldServiceRequest(int process_type, | 293 bool ShouldServiceRequest(int process_type, |
| 294 int child_id, | 294 int child_id, |
| 295 const ResourceRequest& request_data, | 295 const ResourceRequest& request_data, |
| 296 const net::HttpRequestHeaders& headers, | 296 const net::HttpRequestHeaders& headers, |
| 297 ResourceMessageFilter* filter, | 297 ResourceMessageFilter* filter, |
| 298 ResourceContext* resource_context) { | 298 ResourceContext* resource_context, |
| 299 ResourceDispatcherHostImpl* host) { | |
| 299 ChildProcessSecurityPolicyImpl* policy = | 300 ChildProcessSecurityPolicyImpl* policy = |
| 300 ChildProcessSecurityPolicyImpl::GetInstance(); | 301 ChildProcessSecurityPolicyImpl::GetInstance(); |
| 301 | 302 |
| 302 // Check if the renderer is permitted to request the requested URL. | 303 // Check if the renderer is permitted to request the requested URL. |
| 303 if (!policy->CanRequestURL(child_id, request_data.url)) { | 304 if (!policy->CanRequestURL(child_id, request_data.url)) { |
| 304 VLOG(1) << "Denied unauthorized request for " | 305 VLOG(1) << "Denied unauthorized request for " |
| 305 << request_data.url.possibly_invalid_spec(); | 306 << request_data.url.possibly_invalid_spec(); |
| 306 return false; | 307 return false; |
| 307 } | 308 } |
| 308 | 309 |
| 309 // Check if the renderer is using an illegal Origin header. If so, kill it. | 310 // Check if the renderer is using an illegal Origin header. If so, kill it. |
| 310 std::string origin_string; | 311 std::string origin_string; |
| 311 bool has_origin = headers.GetHeader("Origin", &origin_string) && | 312 bool has_origin = headers.GetHeader("Origin", &origin_string) && |
| 312 origin_string != "null"; | 313 origin_string != "null"; |
| 313 if (has_origin) { | 314 if (has_origin) { |
| 314 GURL origin(origin_string); | 315 GURL origin(origin_string); |
| 315 if (!policy->CanCommitURL(child_id, origin) || | 316 if (!policy->CanCommitURL(child_id, origin) || |
| 316 GetContentClient()->browser()->IsIllegalOrigin(resource_context, | 317 host->IsIllegalOrigin(resource_context, origin, child_id)) { |
| 317 child_id, origin)) { | |
| 318 VLOG(1) << "Killed renderer for illegal origin: " << origin_string; | 318 VLOG(1) << "Killed renderer for illegal origin: " << origin_string; |
| 319 bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN); | 319 bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN); |
| 320 return false; | 320 return false; |
| 321 } | 321 } |
| 322 } | 322 } |
| 323 | 323 |
| 324 // Check if the renderer is permitted to upload the requested files. | 324 // Check if the renderer is permitted to upload the requested files. |
| 325 if (request_data.request_body.get()) { | 325 if (request_data.request_body.get()) { |
| 326 const std::vector<ResourceRequestBodyImpl::Element>* uploads = | 326 const std::vector<ResourceRequestBodyImpl::Element>* uploads = |
| 327 request_data.request_body->elements(); | 327 request_data.request_body->elements(); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 if (pending_frame_host) | 486 if (pending_frame_host) |
| 487 routing_ids->insert(pending_frame_host->GetGlobalFrameRoutingId()); | 487 routing_ids->insert(pending_frame_host->GetGlobalFrameRoutingId()); |
| 488 } | 488 } |
| 489 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 489 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 490 base::Bind(&NotifyForRouteSetOnIO, frame_callback, | 490 base::Bind(&NotifyForRouteSetOnIO, frame_callback, |
| 491 base::Passed(std::move(routing_ids)))); | 491 base::Passed(std::move(routing_ids)))); |
| 492 } | 492 } |
| 493 | 493 |
| 494 } // namespace | 494 } // namespace |
| 495 | 495 |
| 496 ResourceDispatcherHostImpl::OriginAccessInfo::OriginAccessInfo() { | |
| 497 } | |
| 498 | |
| 499 ResourceDispatcherHostImpl::OriginAccessInfo::~OriginAccessInfo() { | |
| 500 } | |
| 501 | |
| 502 ResourceDispatcherHostImpl::OriginAccessInfo::OriginAccessInfo( | |
| 503 const OriginAccessInfo& other) { | |
| 504 } | |
| 505 | |
| 496 // static | 506 // static |
| 497 ResourceDispatcherHost* ResourceDispatcherHost::Get() { | 507 ResourceDispatcherHost* ResourceDispatcherHost::Get() { |
| 498 return g_resource_dispatcher_host; | 508 return g_resource_dispatcher_host; |
| 499 } | 509 } |
| 500 | 510 |
| 501 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() | 511 ResourceDispatcherHostImpl::ResourceDispatcherHostImpl() |
| 502 : save_file_manager_(new SaveFileManager()), | 512 : save_file_manager_(new SaveFileManager()), |
| 503 request_id_(-1), | 513 request_id_(-1), |
| 504 is_shutdown_(false), | 514 is_shutdown_(false), |
| 505 num_in_flight_requests_(0), | 515 num_in_flight_requests_(0), |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 744 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( | 754 void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( |
| 745 net::URLRequest* request) { | 755 net::URLRequest* request) { |
| 746 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); | 756 ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request); |
| 747 if (info) { | 757 if (info) { |
| 748 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID()); | 758 ResourceLoader* loader = GetLoader(info->GetGlobalRequestID()); |
| 749 if (loader) | 759 if (loader) |
| 750 loader->ClearLoginDelegate(); | 760 loader->ClearLoginDelegate(); |
| 751 } | 761 } |
| 752 } | 762 } |
| 753 | 763 |
| 764 void ResourceDispatcherHostImpl::AddSchemeForAccessCheck( | |
| 765 const std::string& scheme) { | |
| 766 origins_for_access_check_.insert(scheme); | |
| 767 } | |
| 768 | |
| 769 void ResourceDispatcherHostImpl::AddProcessForOrigin( | |
| 770 const ResourceContext* context, | |
| 771 const std::string& origin, | |
| 772 int process_id) { | |
| 773 GURL url(origin); | |
|
jam
2016/08/02 17:01:46
nit: in these three new methods, add a DCHECK_CURR
ananta
2016/08/02 22:28:28
Added the DCHECK for the following methods:
1. Reg
| |
| 774 // The following conditions need to apply before we can add the process to | |
| 775 // the list of allowed processes for an origin. | |
| 776 // 1. The URL has to be valid. | |
| 777 // 2. It has to have a valid host. | |
| 778 // 3. The scheme has to be registered in the list of schemes being access | |
| 779 // checked. | |
| 780 if (!url.is_valid() || !url.has_host() || | |
| 781 origins_for_access_check_.find(url.scheme()) == | |
| 782 origins_for_access_check_.end()) { | |
| 783 NOTREACHED() << "Invalid URL or unregistered scheme."; | |
| 784 return; | |
| 785 } | |
| 786 | |
| 787 OriginAccessInfoMap* origin_access_info_map = | |
| 788 GetOriginAccessMapForResourceContext(context); | |
| 789 DCHECK(origin_access_info_map); | |
| 790 | |
| 791 OriginAccessInfoMap::iterator index = origin_access_info_map->find( | |
| 792 url.host()); | |
| 793 // If the host is not found in the map, then don't add the owner. | |
| 794 if (index == origin_access_info_map->end()) | |
| 795 return; | |
| 796 | |
| 797 OriginAccessInfo& access_info = index->second; | |
| 798 // The process should not be there in the list. | |
| 799 DCHECK(access_info.allowed_processes.find(process_id) == | |
| 800 access_info.allowed_processes.end()); | |
| 801 access_info.allowed_processes.insert(process_id); | |
| 802 } | |
| 803 | |
| 804 void ResourceDispatcherHostImpl::RemoveProcessForOrigin( | |
| 805 const ResourceContext* context, | |
| 806 const std::string& origin, | |
| 807 int process_id) { | |
| 808 GURL url(origin); | |
| 809 // The scheme has to be registered in the list of schemes being access | |
| 810 // checked. | |
| 811 if (origins_for_access_check_.find(url.scheme()) == | |
| 812 origins_for_access_check_.end()) { | |
| 813 DCHECK(false); | |
| 814 return; | |
| 815 } | |
| 816 | |
| 817 OriginAccessInfoMap* origin_access_info_map = | |
| 818 GetOriginAccessMapForResourceContext(context); | |
| 819 DCHECK(origin_access_info_map); | |
| 820 | |
| 821 OriginAccessInfoMap::iterator index = origin_access_info_map->find( | |
| 822 url.host()); | |
| 823 // If the host is not found in the map, then don't remove the owner. | |
| 824 if (index == origin_access_info_map->end()) | |
| 825 return; | |
| 826 | |
| 827 OriginAccessInfo& access_info = index->second; | |
| 828 | |
| 829 std::set<int>::iterator process_index = | |
| 830 access_info.allowed_processes.find(process_id); | |
| 831 // The process has to be there in the list. | |
| 832 DCHECK(process_index != access_info.allowed_processes.end()); | |
| 833 access_info.allowed_processes.erase(process_index); | |
| 834 if (access_info.allowed_processes.empty()) | |
| 835 origin_access_info_map->erase(index); | |
| 836 } | |
| 837 | |
| 754 void ResourceDispatcherHostImpl::Shutdown() { | 838 void ResourceDispatcherHostImpl::Shutdown() { |
| 755 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 839 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 756 BrowserThread::PostTask(BrowserThread::IO, | 840 BrowserThread::PostTask(BrowserThread::IO, |
| 757 FROM_HERE, | 841 FROM_HERE, |
| 758 base::Bind(&ResourceDispatcherHostImpl::OnShutdown, | 842 base::Bind(&ResourceDispatcherHostImpl::OnShutdown, |
| 759 base::Unretained(this))); | 843 base::Unretained(this))); |
| 760 } | 844 } |
| 761 | 845 |
| 762 std::unique_ptr<ResourceHandler> | 846 std::unique_ptr<ResourceHandler> |
| 763 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload( | 847 ResourceDispatcherHostImpl::CreateResourceHandlerForDownload( |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1354 filter_->GetContexts(request_data.resource_type, &resource_context, | 1438 filter_->GetContexts(request_data.resource_type, &resource_context, |
| 1355 &request_context); | 1439 &request_context); |
| 1356 | 1440 |
| 1357 // Parse the headers before calling ShouldServiceRequest, so that they are | 1441 // Parse the headers before calling ShouldServiceRequest, so that they are |
| 1358 // available to be validated. | 1442 // available to be validated. |
| 1359 net::HttpRequestHeaders headers; | 1443 net::HttpRequestHeaders headers; |
| 1360 headers.AddHeadersFromString(request_data.headers); | 1444 headers.AddHeadersFromString(request_data.headers); |
| 1361 | 1445 |
| 1362 if (is_shutdown_ || | 1446 if (is_shutdown_ || |
| 1363 !ShouldServiceRequest(process_type, child_id, request_data, headers, | 1447 !ShouldServiceRequest(process_type, child_id, request_data, headers, |
| 1364 filter_, resource_context)) { | 1448 filter_, resource_context, this)) { |
| 1365 AbortRequestBeforeItStarts(filter_, sync_result, request_id); | 1449 AbortRequestBeforeItStarts(filter_, sync_result, request_id); |
| 1366 return; | 1450 return; |
| 1367 } | 1451 } |
| 1368 | 1452 |
| 1369 // Allow the observer to block/handle the request. | 1453 // Allow the observer to block/handle the request. |
| 1370 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method, | 1454 if (delegate_ && !delegate_->ShouldBeginRequest(request_data.method, |
| 1371 request_data.url, | 1455 request_data.url, |
| 1372 request_data.resource_type, | 1456 request_data.resource_type, |
| 1373 resource_context)) { | 1457 resource_context)) { |
| 1374 AbortRequestBeforeItStarts(filter_, sync_result, request_id); | 1458 AbortRequestBeforeItStarts(filter_, sync_result, request_id); |
| (...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2600 DCHECK(deserialized); | 2684 DCHECK(deserialized); |
| 2601 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id); | 2685 ssl.cert_id = GetCertStore()->StoreCert(ssl_info.cert.get(), child_id); |
| 2602 response->head.security_info = SerializeSecurityInfo(ssl); | 2686 response->head.security_info = SerializeSecurityInfo(ssl); |
| 2603 } | 2687 } |
| 2604 | 2688 |
| 2605 CertStore* ResourceDispatcherHostImpl::GetCertStore() { | 2689 CertStore* ResourceDispatcherHostImpl::GetCertStore() { |
| 2606 return cert_store_for_testing_ ? cert_store_for_testing_ | 2690 return cert_store_for_testing_ ? cert_store_for_testing_ |
| 2607 : CertStore::GetInstance(); | 2691 : CertStore::GetInstance(); |
| 2608 } | 2692 } |
| 2609 | 2693 |
| 2694 ResourceDispatcherHostImpl::OriginAccessInfoMap* | |
| 2695 ResourceDispatcherHostImpl::GetOriginAccessMapForResourceContext( | |
| 2696 const ResourceContext* context) { | |
| 2697 ResourceContextOriginMap::iterator context_index = | |
| 2698 context_origin_access_info_map_.find(context); | |
| 2699 if (context_index != context_origin_access_info_map_.end()) | |
| 2700 return context_index->second.get(); | |
| 2701 | |
| 2702 context_origin_access_info_map_[context].reset(new OriginAccessInfoMap); | |
| 2703 return context_origin_access_info_map_[context].get(); | |
| 2704 } | |
| 2705 | |
| 2706 bool ResourceDispatcherHostImpl::IsIllegalOrigin(ResourceContext* context, | |
| 2707 const GURL& origin, | |
| 2708 int child_process_id) { | |
| 2709 if (origins_for_access_check_.find(origin.scheme()) == | |
| 2710 origins_for_access_check_.end()) { | |
| 2711 return false; | |
| 2712 } | |
| 2713 | |
| 2714 OriginAccessInfoMap* origin_access_info_map = | |
| 2715 GetOriginAccessMapForResourceContext( | |
| 2716 const_cast<const ResourceContext*>(context)); | |
| 2717 DCHECK(origin_access_info_map); | |
| 2718 | |
| 2719 OriginAccessInfoMap::iterator index = | |
| 2720 origin_access_info_map->find(origin.host()); | |
| 2721 if (index == origin_access_info_map->end()) | |
| 2722 return false; | |
| 2723 | |
| 2724 OriginAccessInfo& access_info = index->second; | |
| 2725 // Processes in the list for this origin are allowed. | |
| 2726 if (access_info.allowed_processes.find(child_process_id) != | |
| 2727 access_info.allowed_processes.end()) { | |
| 2728 return false; | |
| 2729 } | |
| 2730 // The origin being accessed is not allowed for the |child_process_id|. | |
| 2731 return true; | |
| 2732 } | |
| 2733 | |
| 2610 } // namespace content | 2734 } // namespace content |
| OLD | NEW |