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 |