Chromium Code Reviews| Index: content/browser/loader/resource_dispatcher_host_impl.cc |
| diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc |
| index 981c71ba454f337c573f6c9b64805d7934a13ce5..6c8c6849610f18c93e2b62c622ca5362f545e467 100644 |
| --- a/content/browser/loader/resource_dispatcher_host_impl.cc |
| +++ b/content/browser/loader/resource_dispatcher_host_impl.cc |
| @@ -295,7 +295,8 @@ bool ShouldServiceRequest(int process_type, |
| const ResourceRequest& request_data, |
| const net::HttpRequestHeaders& headers, |
| ResourceMessageFilter* filter, |
| - ResourceContext* resource_context) { |
| + ResourceContext* resource_context, |
| + ResourceDispatcherHostImpl* host) { |
| ChildProcessSecurityPolicyImpl* policy = |
| ChildProcessSecurityPolicyImpl::GetInstance(); |
| @@ -313,8 +314,7 @@ bool ShouldServiceRequest(int process_type, |
| if (has_origin) { |
| GURL origin(origin_string); |
| if (!policy->CanCommitURL(child_id, origin) || |
| - GetContentClient()->browser()->IsIllegalOrigin(resource_context, |
| - child_id, origin)) { |
| + host->IsIllegalOrigin(resource_context, origin, child_id)) { |
| VLOG(1) << "Killed renderer for illegal origin: " << origin_string; |
| bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN); |
| return false; |
| @@ -493,6 +493,16 @@ void NotifyForEachFrameFromUI( |
| } // namespace |
| +ResourceDispatcherHostImpl::OriginAccessInfo::OriginAccessInfo() { |
| +} |
| + |
| +ResourceDispatcherHostImpl::OriginAccessInfo::~OriginAccessInfo() { |
| +} |
| + |
| +ResourceDispatcherHostImpl::OriginAccessInfo::OriginAccessInfo( |
| + const OriginAccessInfo& other) { |
| +} |
| + |
| // static |
| ResourceDispatcherHost* ResourceDispatcherHost::Get() { |
| return g_resource_dispatcher_host; |
| @@ -751,6 +761,80 @@ void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( |
| } |
| } |
| +void ResourceDispatcherHostImpl::AddSchemeForAccessCheck( |
| + const std::string& scheme) { |
| + origins_for_access_check_.insert(scheme); |
| +} |
| + |
| +void ResourceDispatcherHostImpl::AddProcessForOrigin( |
| + const ResourceContext* context, |
| + const std::string& origin, |
| + int process_id) { |
| + 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
|
| + // The following conditions need to apply before we can add the process to |
| + // the list of allowed processes for an origin. |
| + // 1. The URL has to be valid. |
| + // 2. It has to have a valid host. |
| + // 3. The scheme has to be registered in the list of schemes being access |
| + // checked. |
| + if (!url.is_valid() || !url.has_host() || |
| + origins_for_access_check_.find(url.scheme()) == |
| + origins_for_access_check_.end()) { |
| + NOTREACHED() << "Invalid URL or unregistered scheme."; |
| + return; |
| + } |
| + |
| + OriginAccessInfoMap* origin_access_info_map = |
| + GetOriginAccessMapForResourceContext(context); |
| + DCHECK(origin_access_info_map); |
| + |
| + OriginAccessInfoMap::iterator index = origin_access_info_map->find( |
| + url.host()); |
| + // If the host is not found in the map, then don't add the owner. |
| + if (index == origin_access_info_map->end()) |
| + return; |
| + |
| + OriginAccessInfo& access_info = index->second; |
| + // The process should not be there in the list. |
| + DCHECK(access_info.allowed_processes.find(process_id) == |
| + access_info.allowed_processes.end()); |
| + access_info.allowed_processes.insert(process_id); |
| +} |
| + |
| +void ResourceDispatcherHostImpl::RemoveProcessForOrigin( |
| + const ResourceContext* context, |
| + const std::string& origin, |
| + int process_id) { |
| + GURL url(origin); |
| + // The scheme has to be registered in the list of schemes being access |
| + // checked. |
| + if (origins_for_access_check_.find(url.scheme()) == |
| + origins_for_access_check_.end()) { |
| + DCHECK(false); |
| + return; |
| + } |
| + |
| + OriginAccessInfoMap* origin_access_info_map = |
| + GetOriginAccessMapForResourceContext(context); |
| + DCHECK(origin_access_info_map); |
| + |
| + OriginAccessInfoMap::iterator index = origin_access_info_map->find( |
| + url.host()); |
| + // If the host is not found in the map, then don't remove the owner. |
| + if (index == origin_access_info_map->end()) |
| + return; |
| + |
| + OriginAccessInfo& access_info = index->second; |
| + |
| + std::set<int>::iterator process_index = |
| + access_info.allowed_processes.find(process_id); |
| + // The process has to be there in the list. |
| + DCHECK(process_index != access_info.allowed_processes.end()); |
| + access_info.allowed_processes.erase(process_index); |
| + if (access_info.allowed_processes.empty()) |
| + origin_access_info_map->erase(index); |
| +} |
| + |
| void ResourceDispatcherHostImpl::Shutdown() { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| BrowserThread::PostTask(BrowserThread::IO, |
| @@ -1361,7 +1445,7 @@ void ResourceDispatcherHostImpl::BeginRequest( |
| if (is_shutdown_ || |
| !ShouldServiceRequest(process_type, child_id, request_data, headers, |
| - filter_, resource_context)) { |
| + filter_, resource_context, this)) { |
| AbortRequestBeforeItStarts(filter_, sync_result, request_id); |
| return; |
| } |
| @@ -2607,4 +2691,44 @@ CertStore* ResourceDispatcherHostImpl::GetCertStore() { |
| : CertStore::GetInstance(); |
| } |
| +ResourceDispatcherHostImpl::OriginAccessInfoMap* |
| +ResourceDispatcherHostImpl::GetOriginAccessMapForResourceContext( |
| + const ResourceContext* context) { |
| + ResourceContextOriginMap::iterator context_index = |
| + context_origin_access_info_map_.find(context); |
| + if (context_index != context_origin_access_info_map_.end()) |
| + return context_index->second.get(); |
| + |
| + context_origin_access_info_map_[context].reset(new OriginAccessInfoMap); |
| + return context_origin_access_info_map_[context].get(); |
| +} |
| + |
| +bool ResourceDispatcherHostImpl::IsIllegalOrigin(ResourceContext* context, |
| + const GURL& origin, |
| + int child_process_id) { |
| + if (origins_for_access_check_.find(origin.scheme()) == |
| + origins_for_access_check_.end()) { |
| + return false; |
| + } |
| + |
| + OriginAccessInfoMap* origin_access_info_map = |
| + GetOriginAccessMapForResourceContext( |
| + const_cast<const ResourceContext*>(context)); |
| + DCHECK(origin_access_info_map); |
| + |
| + OriginAccessInfoMap::iterator index = |
| + origin_access_info_map->find(origin.host()); |
| + if (index == origin_access_info_map->end()) |
| + return false; |
| + |
| + OriginAccessInfo& access_info = index->second; |
| + // Processes in the list for this origin are allowed. |
| + if (access_info.allowed_processes.find(child_process_id) != |
| + access_info.allowed_processes.end()) { |
| + return false; |
| + } |
| + // The origin being accessed is not allowed for the |child_process_id|. |
| + return true; |
| +} |
| + |
| } // namespace content |