Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(779)

Unified Diff: content/browser/loader/resource_dispatcher_host_impl.cc

Issue 2182633007: Avoid using ContentBrowserClient::IsIllegalOrigin in ResourceDispatcherHost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove the IsIllegalOrigin function from ContentBrowserClient Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..7b9d1cc5e25bfc3aa4b17d0e4893540d70d36252 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,145 @@ void ResourceDispatcherHostImpl::ClearLoginDelegateForRequest(
}
}
+void ResourceDispatcherHostImpl::AddSchemeForAccessCheck(
+ const std::string& scheme) {
+ origins_for_access_check_.insert(scheme);
+}
+
+void ResourceDispatcherHostImpl::RegisterOriginForAccessChecks(
+ const ResourceContext* context,
+ const std::string& origin,
+ OriginAccessCheckMask access_check_mask) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ 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()) {
+ NOTREACHED() << "Invalid URL or unregistered scheme.";
+ return;
+ }
+
+ OriginAccessInfoMap* origin_access_info_map =
+ GetOriginAccessMapForResourceContext(context);
+ DCHECK(origin_access_info_map->find(url.host()) ==
+ origin_access_info_map->end());
+
+ OriginAccessInfo access_info;
+ access_info.access_check_mask = access_check_mask;
+
+ (*origin_access_info_map)[url.host()] = access_info;
+}
+
+void ResourceDispatcherHostImpl::UnregisterOriginForAccessChecks(
+ const ResourceContext* context,
+ const std::string& origin) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ 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()) {
+ NOTREACHED() << "Unregistered scheme for access check";
+ 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::AddProcessForOrigin(
+ const ResourceContext* context,
+ const std::string& origin,
+ int process_id,
+ bool owner_process) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ GURL url(origin);
+ // 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());
+ // No need to add access information for an unregistered host.
+ if (index == origin_access_info_map->end())
+ return;
+
+ OriginAccessInfo& access_info = index->second;
+ if (owner_process) {
+ access_info.owner_processes[process_id]++;
+ } else {
+ access_info.other_processes[process_id]++;
+ }
+}
+
+void ResourceDispatcherHostImpl::RemoveProcessForOrigin(
+ const ResourceContext* context,
+ const std::string& origin,
+ int process_id,
+ bool owner_process) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ 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());
+ // No need to add access information for an unregistered host.
+ if (index == origin_access_info_map->end())
+ return;
+
+ OriginAccessInfo& access_info = index->second;
+
+ std::map<int, int>::iterator process_index;
+ std::map<int, int>* process_map = nullptr;
+ if (owner_process) {
+ process_map = &access_info.owner_processes;
+ } else {
+ process_map = &access_info.other_processes;
+ }
+ process_index = process_map->find(process_id);
+ // The process has to be there in the list.
+ DCHECK(process_index != process_map->end());
+ process_index->second--;
+ if (process_index->second == 0)
+ process_map->erase(process_index);
+}
+
void ResourceDispatcherHostImpl::Shutdown() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(BrowserThread::IO,
@@ -1361,7 +1510,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 +2756,61 @@ 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);
+
+ // If the origin is not found then this URL cannot be committed.
+ 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 allowed access by default.
+ if (access_info.owner_processes.find(child_process_id) !=
+ access_info.owner_processes.end()) {
+ return false;
+ }
+
+ DCHECK(access_info.access_check_mask >= DENY_FOR_NON_OWNERS &&
+ access_info.access_check_mask <= ACCESS_CHECK_MASK_LAST);
+
+ if (access_info.access_check_mask == DENY_FOR_NON_OWNERS)
+ return true;
+
+ // No need to check for other processes here.
+ if (access_info.access_check_mask == ALLOW_EVERYTHING)
+ return false;
+
+ // Processes in the other_processes list are allowed.
+ if (access_info.other_processes.find(child_process_id) !=
+ access_info.other_processes.end()) {
+ return false;
+ }
+ // The origin being accessed is not allowed for the |child_process_id|.
+ return true;
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698