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 fb12a9b95407a2d9276c7bbe9279646f22f837d8..2bc6480fa18656dd0807bca82366c581bf343932 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; |
| @@ -506,6 +506,19 @@ void LoaderIOThreadNotifier::RenderFrameDeleted( |
| base::Bind(&ResourceDispatcherHostImpl::OnRenderFrameDeleted)); |
| } |
| +// The ctors for the OriginAccessInfo structure have been defined here to fix |
| +// compile errors with clang. Reason being presence of members with complex |
| +// ctors like STL set. |
|
jam
2016/08/01 20:06:01
nit: no need for this comment (i.e. we don't do it
ananta
2016/08/02 00:40:49
Done.
|
| +ResourceDispatcherHostImpl::OriginAccessInfo::OriginAccessInfo() { |
| +} |
| + |
| +ResourceDispatcherHostImpl::OriginAccessInfo::~OriginAccessInfo() { |
| +} |
| + |
| +ResourceDispatcherHostImpl::OriginAccessInfo::OriginAccessInfo( |
| + const OriginAccessInfo& other) { |
| +} |
| + |
| // static |
| ResourceDispatcherHost* ResourceDispatcherHost::Get() { |
| return g_resource_dispatcher_host; |
| @@ -559,6 +572,10 @@ ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { |
| DCHECK(outstanding_requests_stats_map_.empty()); |
| DCHECK(g_resource_dispatcher_host); |
| g_resource_dispatcher_host = NULL; |
| + |
| + // Delete the origin access info maps. |
|
jam
2016/08/01 20:06:01
(wouldn't be needed if unique_ptr was used)
ananta
2016/08/02 00:40:49
Done.
|
| + for (auto index : context_origin_access_info_map_) |
| + delete index.second; |
| } |
| // static |
| @@ -764,6 +781,178 @@ void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest( |
| } |
| } |
| +void ResourceDispatcherHostImpl::AddSchemeForAccessCheck( |
| + const std::string& scheme) { |
| + origins_for_access_check_.insert(scheme); |
| +} |
| + |
| +void ResourceDispatcherHostImpl::AddOriginAccessInformation( |
| + const ResourceContext* context, |
| + const std::string& origin) { |
| + GURL url(origin); |
| + // The following conditions need to apply before we can add access |
| + // information 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()) { |
| + DCHECK(false); |
|
jam
2016/08/01 20:06:01
nit: NOTREACHED() is preferred to DCHECK(false)
ananta
2016/08/02 00:40:49
Done.
|
| + return; |
| + } |
| + |
| + OriginAccessInfoMap* origin_access_info_map = |
| + GetOriginAccessMapForResourceContext(context); |
| + |
| + OriginAccessInfo access_info; |
| + (*origin_access_info_map)[url.host()] = access_info; |
| +} |
| + |
| +void ResourceDispatcherHostImpl::RemoveOriginAccessInformation( |
| + const ResourceContext* context, |
| + const std::string& origin) { |
| + 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); |
| + |
| + OriginAccessInfoMap::iterator index = origin_access_info_map->find( |
| + url.host()); |
| + if (index != origin_access_info_map->end()) |
| + origin_access_info_map->erase(index); |
| +} |
| + |
| +void ResourceDispatcherHostImpl::AddOwnerForOrigin( |
| + const ResourceContext* context, |
| + const std::string& origin, |
| + int owner_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); |
| + |
| + 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 owner should not be there in the list. |
| + DCHECK(access_info.origin_owner_processes.find(owner_process_id) == |
| + access_info.origin_owner_processes.end()); |
| + access_info.origin_owner_processes.insert(owner_process_id); |
| +} |
| + |
| +void ResourceDispatcherHostImpl::RemoveOwnerForOrigin( |
| + const ResourceContext* context, |
| + const std::string& origin, |
| + int owner_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); |
| + |
| + 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.origin_owner_processes.find(owner_process_id); |
| + // The owner has to be there in the list. |
| + DCHECK(access_info.origin_owner_processes.find(owner_process_id) != |
| + access_info.origin_owner_processes.end()); |
| + access_info.origin_owner_processes.erase(process_index); |
| +} |
| + |
| +void ResourceDispatcherHostImpl::AddGuestForOrigin( |
| + const ResourceContext* context, |
| + const std::string& origin, |
| + int guest_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); |
| + |
| + OriginAccessInfoMap::iterator index = origin_access_info_map->find( |
| + url.host()); |
| + // If the host is not found in the map, then don't add the guest. |
| + if (index == origin_access_info_map->end()) |
| + return; |
| + |
| + OriginAccessInfo& access_info = index->second; |
| + // The guest should not be there in the list. |
| + DCHECK(access_info.origin_guest_processes.find(guest_process_id) == |
| + access_info.origin_guest_processes.end()); |
| + access_info.origin_guest_processes.insert(guest_process_id); |
| +} |
| + |
| +void ResourceDispatcherHostImpl::RemoveGuestForOrigin( |
| + const ResourceContext* context, |
| + const std::string& origin, |
| + int guest_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); |
| + |
| + OriginAccessInfoMap::iterator index = origin_access_info_map->find( |
| + url.host()); |
| + // If the host is not found in the map, then don't remove the guest. |
| + if (index == origin_access_info_map->end()) |
| + return; |
| + |
| + OriginAccessInfo& access_info = index->second; |
| + |
| + std::set<int>::iterator process_index = |
| + access_info.origin_guest_processes.find(guest_process_id); |
| + // The guest has to be there in the list. |
| + DCHECK(access_info.origin_guest_processes.find(guest_process_id) != |
| + access_info.origin_guest_processes.end()); |
| + access_info.origin_guest_processes.erase(process_index); |
| +} |
| + |
| void ResourceDispatcherHostImpl::Shutdown() { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| BrowserThread::PostTask(BrowserThread::IO, |
| @@ -1374,7 +1563,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; |
| } |
| @@ -2602,4 +2791,48 @@ CertStore* ResourceDispatcherHostImpl::GetCertStore() { |
| : CertStore::GetInstance(); |
| } |
| +ResourceDispatcherHostImpl::OriginAccessInfoMap* |
| +ResourceDispatcherHostImpl::GetOriginAccessMapForResourceContext( |
| + const ResourceContext* context) { |
| + OriginAccessInfoMap* origin_access_map = |
| + context_origin_access_info_map_[context]; |
| + if (!origin_access_map) { |
| + origin_access_map = new OriginAccessInfoMap; |
| + context_origin_access_info_map_[context] = origin_access_map; |
| + } |
| + return origin_access_map; |
| +} |
| + |
| +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; |
| + // Owner processes are granted access by default. |
| + if (access_info.origin_owner_processes.find(child_process_id) != |
| + access_info.origin_owner_processes.end()) { |
| + return false; |
| + } |
| + // Guest processes are allowed access. |
| + if (access_info.origin_guest_processes.find(child_process_id) != |
| + access_info.origin_guest_processes.end()) { |
| + return false; |
| + } |
| + // The origin being accessed is not allowed for the |child_process_id|. |
| + return true; |
| +} |
| + |
| } // namespace content |