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 |