1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/child_process_security_policy_impl.h"
7 #include "base/command_line.h"
8 #include "base/file_path.h"
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/platform_file.h"
12 #include "base/stl_util.h"
13 #include "base/string_util.h"
14 #include "content/browser/site_instance_impl.h"
15 #include "content/public/browser/content_browser_client.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/common/bindings_policy.h"
18 #include "content/public/common/content_switches.h"
19 #include "content/public/common/url_constants.h"
20 #include "googleurl/src/gurl.h"
21 #include "net/base/net_util.h"
22 #include "net/url_request/url_request.h"
23 #include "webkit/fileapi/isolated_context.h"
29 const int kReadFilePermissions
=
30 base::PLATFORM_FILE_OPEN
|
31 base::PLATFORM_FILE_READ
|
32 base::PLATFORM_FILE_EXCLUSIVE_READ
|
33 base::PLATFORM_FILE_ASYNC
;
35 const int kWriteFilePermissions
=
36 base::PLATFORM_FILE_OPEN
|
37 base::PLATFORM_FILE_WRITE
|
38 base::PLATFORM_FILE_EXCLUSIVE_WRITE
|
39 base::PLATFORM_FILE_ASYNC
|
40 base::PLATFORM_FILE_WRITE_ATTRIBUTES
;
42 const int kEnumerateDirectoryPermissions
=
43 kReadFilePermissions
|
44 base::PLATFORM_FILE_ENUMERATE
;
48 // The SecurityState class is used to maintain per-child process security state
50 class ChildProcessSecurityPolicyImpl::SecurityState
{
53 : enabled_bindings_(0),
54 can_read_raw_cookies_(false) { }
57 scheme_policy_
.clear();
58 fileapi::IsolatedContext
* isolated_context
=
59 fileapi::IsolatedContext::GetInstance();
60 for (FileSystemMap::iterator iter
= filesystem_permissions_
.begin();
61 iter
!= filesystem_permissions_
.end();
63 isolated_context
->RemoveReference(iter
->first
);
65 UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.PerChildFilePermissions",
66 file_permissions_
.size());
69 // Grant permission to request URLs with the specified scheme.
70 void GrantScheme(const std::string
& scheme
) {
71 scheme_policy_
[scheme
] = true;
74 // Revoke permission to request URLs with the specified scheme.
75 void RevokeScheme(const std::string
& scheme
) {
76 scheme_policy_
[scheme
] = false;
79 // Grant certain permissions to a file.
80 void GrantPermissionsForFile(const FilePath
& file
, int permissions
) {
81 FilePath stripped
= file
.StripTrailingSeparators();
82 file_permissions_
[stripped
] |= permissions
;
83 UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.FilePermissionPathLength",
84 stripped
.value().size());
87 // Grant navigation to a file but not the file:// scheme in general.
88 void GrantRequestOfSpecificFile(const FilePath
&file
) {
89 request_file_set_
.insert(file
.StripTrailingSeparators());
92 // Revokes all permissions granted to a file.
93 void RevokeAllPermissionsForFile(const FilePath
& file
) {
94 FilePath stripped
= file
.StripTrailingSeparators();
95 file_permissions_
.erase(stripped
);
96 request_file_set_
.erase(stripped
);
99 // Grant certain permissions to a file.
100 void GrantPermissionsForFileSystem(const std::string
& filesystem_id
,
102 if (filesystem_permissions_
.find(filesystem_id
) ==
103 filesystem_permissions_
.end())
104 fileapi::IsolatedContext::GetInstance()->AddReference(filesystem_id
);
105 filesystem_permissions_
[filesystem_id
] = permissions
;
108 bool HasPermissionsForFileSystem(const std::string
& filesystem_id
,
110 if (filesystem_permissions_
.find(filesystem_id
) ==
111 filesystem_permissions_
.end())
113 return (filesystem_permissions_
[filesystem_id
] & permissions
) ==
117 void GrantBindings(int bindings
) {
118 enabled_bindings_
|= bindings
;
121 void GrantReadRawCookies() {
122 can_read_raw_cookies_
= true;
125 void RevokeReadRawCookies() {
126 can_read_raw_cookies_
= false;
129 // Determine whether permission has been granted to request |url|.
130 bool CanRequestURL(const GURL
& url
) {
131 // Having permission to a scheme implies permssion to all of its URLs.
132 SchemeMap::const_iterator
judgment(scheme_policy_
.find(url
.scheme()));
133 if (judgment
!= scheme_policy_
.end())
134 return judgment
->second
;
136 // file:// URLs are more granular. The child may have been given
137 // permission to a specific file but not the file:// scheme in general.
138 if (url
.SchemeIs(chrome::kFileScheme
)) {
140 if (net::FileURLToFilePath(url
, &path
))
141 return request_file_set_
.find(path
) != request_file_set_
.end();
144 return false; // Unmentioned schemes are disallowed.
147 // Determine if the certain permissions have been granted to a file.
148 bool HasPermissionsForFile(const FilePath
& file
, int permissions
) {
149 FilePath current_path
= file
.StripTrailingSeparators();
152 while (current_path
!= last_path
) {
153 FilePath base_name
= current_path
.BaseName();
154 if (base_name
.value() == FilePath::kParentDirectory
) {
156 } else if (skip
> 0) {
157 if (base_name
.value() != FilePath::kCurrentDirectory
)
160 if (file_permissions_
.find(current_path
) != file_permissions_
.end())
161 return (file_permissions_
[current_path
] & permissions
) == permissions
;
163 last_path
= current_path
;
164 current_path
= current_path
.DirName();
170 bool CanLoadPage(const GURL
& gurl
) {
171 if (origin_lock_
.is_empty())
174 // TODO(creis): We must pass the valid browser_context to convert hosted
175 // apps URLs. Currently, hosted apps cannot be loaded in this mode.
176 // See http://crbug.com/160576.
177 GURL site_gurl
= SiteInstanceImpl::GetSiteForURL(NULL
, gurl
);
178 return origin_lock_
== site_gurl
;
181 bool CanAccessCookiesForOrigin(const GURL
& gurl
) {
182 if (origin_lock_
.is_empty())
184 // TODO(creis): We must pass the valid browser_context to convert hosted
185 // apps URLs. Currently, hosted apps cannot set cookies in this mode.
186 // See http://crbug.com/160576.
187 GURL site_gurl
= SiteInstanceImpl::GetSiteForURL(NULL
, gurl
);
188 return origin_lock_
== site_gurl
;
191 bool CanSendCookiesForOrigin(const GURL
& gurl
) {
192 // We only block cross-site cookies on network requests if the
193 // --enable-strict-site-isolation flag is passed. This is expected to break
194 // compatibility with many sites. The similar --site-per-process flag only
195 // blocks JavaScript access to cross-site cookies (in
196 // CanAccessCookiesForOrigin).
197 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
198 if (!command_line
.HasSwitch(switches::kEnableStrictSiteIsolation
))
201 if (origin_lock_
.is_empty())
203 // TODO(creis): We must pass the valid browser_context to convert hosted
204 // apps URLs. Currently, hosted apps cannot set cookies in this mode.
205 // See http://crbug.com/160576.
206 GURL site_gurl
= SiteInstanceImpl::GetSiteForURL(NULL
, gurl
);
207 return origin_lock_
== site_gurl
;
210 void LockToOrigin(const GURL
& gurl
) {
214 bool has_web_ui_bindings() const {
215 return enabled_bindings_
& BINDINGS_POLICY_WEB_UI
;
218 bool can_read_raw_cookies() const {
219 return can_read_raw_cookies_
;
223 typedef std::map
<std::string
, bool> SchemeMap
;
225 typedef int FilePermissionFlags
; // bit-set of PlatformFileFlags
226 typedef std::map
<FilePath
, FilePermissionFlags
> FileMap
;
227 typedef std::map
<std::string
, FilePermissionFlags
> FileSystemMap
;
228 typedef std::set
<FilePath
> FileSet
;
230 // Maps URL schemes to whether permission has been granted or revoked:
231 // |true| means the scheme has been granted.
232 // |false| means the scheme has been revoked.
233 // If a scheme is not present in the map, then it has never been granted
235 SchemeMap scheme_policy_
;
237 // The set of files the child process is permited to upload to the web.
238 FileMap file_permissions_
;
240 // The set of files the child process is permitted to load.
241 FileSet request_file_set_
;
243 int enabled_bindings_
;
245 bool can_read_raw_cookies_
;
249 // The set of isolated filesystems the child process is permitted to access.
250 FileSystemMap filesystem_permissions_
;
252 DISALLOW_COPY_AND_ASSIGN(SecurityState
);
255 ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() {
256 // We know about these schemes and believe them to be safe.
257 RegisterWebSafeScheme(chrome::kHttpScheme
);
258 RegisterWebSafeScheme(chrome::kHttpsScheme
);
259 RegisterWebSafeScheme(chrome::kFtpScheme
);
260 RegisterWebSafeScheme(chrome::kDataScheme
);
261 RegisterWebSafeScheme("feed");
262 RegisterWebSafeScheme(chrome::kBlobScheme
);
263 RegisterWebSafeScheme(chrome::kFileSystemScheme
);
265 // We know about the following pseudo schemes and treat them specially.
266 RegisterPseudoScheme(chrome::kAboutScheme
);
267 RegisterPseudoScheme(chrome::kJavaScriptScheme
);
268 RegisterPseudoScheme(chrome::kViewSourceScheme
);
271 ChildProcessSecurityPolicyImpl::~ChildProcessSecurityPolicyImpl() {
272 web_safe_schemes_
.clear();
273 pseudo_schemes_
.clear();
274 STLDeleteContainerPairSecondPointers(security_state_
.begin(),
275 security_state_
.end());
276 security_state_
.clear();
280 ChildProcessSecurityPolicy
* ChildProcessSecurityPolicy::GetInstance() {
281 return ChildProcessSecurityPolicyImpl::GetInstance();
284 ChildProcessSecurityPolicyImpl
* ChildProcessSecurityPolicyImpl::GetInstance() {
285 return Singleton
<ChildProcessSecurityPolicyImpl
>::get();
288 void ChildProcessSecurityPolicyImpl::Add(int child_id
) {
289 base::AutoLock
lock(lock_
);
293 void ChildProcessSecurityPolicyImpl::AddWorker(int child_id
,
294 int main_render_process_id
) {
295 base::AutoLock
lock(lock_
);
297 worker_map_
[child_id
] = main_render_process_id
;
300 void ChildProcessSecurityPolicyImpl::Remove(int child_id
) {
301 base::AutoLock
lock(lock_
);
302 if (!security_state_
.count(child_id
))
303 return; // May be called multiple times.
305 delete security_state_
[child_id
];
306 security_state_
.erase(child_id
);
307 worker_map_
.erase(child_id
);
310 void ChildProcessSecurityPolicyImpl::RegisterWebSafeScheme(
311 const std::string
& scheme
) {
312 base::AutoLock
lock(lock_
);
313 DCHECK(web_safe_schemes_
.count(scheme
) == 0) << "Add schemes at most once.";
314 DCHECK(pseudo_schemes_
.count(scheme
) == 0) << "Web-safe implies not pseudo.";
316 web_safe_schemes_
.insert(scheme
);
319 bool ChildProcessSecurityPolicyImpl::IsWebSafeScheme(
320 const std::string
& scheme
) {
321 base::AutoLock
lock(lock_
);
323 return (web_safe_schemes_
.find(scheme
) != web_safe_schemes_
.end());
326 void ChildProcessSecurityPolicyImpl::RegisterPseudoScheme(
327 const std::string
& scheme
) {
328 base::AutoLock
lock(lock_
);
329 DCHECK(pseudo_schemes_
.count(scheme
) == 0) << "Add schemes at most once.";
330 DCHECK(web_safe_schemes_
.count(scheme
) == 0) <<
331 "Pseudo implies not web-safe.";
333 pseudo_schemes_
.insert(scheme
);
336 bool ChildProcessSecurityPolicyImpl::IsPseudoScheme(
337 const std::string
& scheme
) {
338 base::AutoLock
lock(lock_
);
340 return (pseudo_schemes_
.find(scheme
) != pseudo_schemes_
.end());
343 void ChildProcessSecurityPolicyImpl::RegisterDisabledSchemes(
344 const std::set
<std::string
>& schemes
) {
345 base::AutoLock
lock(lock_
);
346 disabled_schemes_
= schemes
;
349 bool ChildProcessSecurityPolicyImpl::IsDisabledScheme(
350 const std::string
& scheme
) {
351 base::AutoLock
lock(lock_
);
352 return disabled_schemes_
.find(scheme
) != disabled_schemes_
.end();
355 void ChildProcessSecurityPolicyImpl::GrantRequestURL(
356 int child_id
, const GURL
& url
) {
359 return; // Can't grant the capability to request invalid URLs.
361 if (IsWebSafeScheme(url
.scheme()))
362 return; // The scheme has already been whitelisted for every child process.
364 if (IsPseudoScheme(url
.scheme())) {
365 // The view-source scheme is a special case of a pseudo-URL that eventually
366 // results in requesting its embedded URL.
367 if (url
.SchemeIs(chrome::kViewSourceScheme
)) {
368 // URLs with the view-source scheme typically look like:
369 // view-source:http://www.google.com/a
370 // In order to request these URLs, the child_id needs to be able to
371 // request the embedded URL.
372 GrantRequestURL(child_id
, GURL(url
.path()));
375 return; // Can't grant the capability to request pseudo schemes.
379 base::AutoLock
lock(lock_
);
380 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
381 if (state
== security_state_
.end())
384 // When the child process has been commanded to request this scheme,
385 // we grant it the capability to request all URLs of that scheme.
386 state
->second
->GrantScheme(url
.scheme());
390 void ChildProcessSecurityPolicyImpl::GrantRequestSpecificFileURL(
393 if (!url
.SchemeIs(chrome::kFileScheme
))
397 base::AutoLock
lock(lock_
);
398 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
399 if (state
== security_state_
.end())
402 // When the child process has been commanded to request a file:// URL,
403 // then we grant it the capability for that URL only.
405 if (net::FileURLToFilePath(url
, &path
))
406 state
->second
->GrantRequestOfSpecificFile(path
);
410 void ChildProcessSecurityPolicyImpl::GrantReadFile(int child_id
,
411 const FilePath
& file
) {
412 GrantPermissionsForFile(child_id
, file
, kReadFilePermissions
);
415 void ChildProcessSecurityPolicyImpl::GrantReadDirectory(
416 int child_id
, const FilePath
& directory
) {
417 GrantPermissionsForFile(child_id
, directory
, kEnumerateDirectoryPermissions
);
420 void ChildProcessSecurityPolicyImpl::GrantPermissionsForFile(
421 int child_id
, const FilePath
& file
, int permissions
) {
422 base::AutoLock
lock(lock_
);
424 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
425 if (state
== security_state_
.end())
428 state
->second
->GrantPermissionsForFile(file
, permissions
);
431 void ChildProcessSecurityPolicyImpl::RevokeAllPermissionsForFile(
432 int child_id
, const FilePath
& file
) {
433 base::AutoLock
lock(lock_
);
435 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
436 if (state
== security_state_
.end())
439 state
->second
->RevokeAllPermissionsForFile(file
);
442 void ChildProcessSecurityPolicyImpl::GrantReadFileSystem(
443 int child_id
, const std::string
& filesystem_id
) {
444 GrantPermissionsForFileSystem(child_id
, filesystem_id
, kReadFilePermissions
);
447 void ChildProcessSecurityPolicyImpl::GrantReadWriteFileSystem(
448 int child_id
, const std::string
& filesystem_id
) {
449 GrantPermissionsForFileSystem(child_id
, filesystem_id
,
450 kReadFilePermissions
|
451 kWriteFilePermissions
);
454 void ChildProcessSecurityPolicyImpl::GrantScheme(int child_id
,
455 const std::string
& scheme
) {
456 base::AutoLock
lock(lock_
);
458 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
459 if (state
== security_state_
.end())
462 state
->second
->GrantScheme(scheme
);
465 void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id
) {
466 base::AutoLock
lock(lock_
);
468 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
469 if (state
== security_state_
.end())
472 state
->second
->GrantBindings(BINDINGS_POLICY_WEB_UI
);
474 // Web UI bindings need the ability to request chrome: URLs.
475 state
->second
->GrantScheme(chrome::kChromeUIScheme
);
477 // Web UI pages can contain links to file:// URLs.
478 state
->second
->GrantScheme(chrome::kFileScheme
);
481 void ChildProcessSecurityPolicyImpl::GrantReadRawCookies(int child_id
) {
482 base::AutoLock
lock(lock_
);
484 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
485 if (state
== security_state_
.end())
488 state
->second
->GrantReadRawCookies();
491 void ChildProcessSecurityPolicyImpl::RevokeReadRawCookies(int child_id
) {
492 base::AutoLock
lock(lock_
);
494 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
495 if (state
== security_state_
.end())
498 state
->second
->RevokeReadRawCookies();
501 bool ChildProcessSecurityPolicyImpl::CanLoadPage(
504 ResourceType::Type resource_type
) {
505 // If --site-per-process flag is passed, we should enforce
506 // stronger security restrictions on page navigation.
507 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess
) &&
508 ResourceType::IsFrame(resource_type
)) {
509 // TODO(irobert): This currently breaks some WebUI page such as
510 // "chrome://extensions/" (belongs to site chrome://chrome/) which
511 // will load an iframe for the page "chrome://uber-frame/"
512 // (belongs to site chrome://uber-frame/).
513 base::AutoLock
lock(lock_
);
514 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
515 if (state
== security_state_
.end())
517 return state
->second
->CanLoadPage(url
);
522 bool ChildProcessSecurityPolicyImpl::CanRequestURL(
523 int child_id
, const GURL
& url
) {
525 return false; // Can't request invalid URLs.
527 if (IsDisabledScheme(url
.scheme()))
528 return false; // The scheme is disabled by policy.
530 if (IsWebSafeScheme(url
.scheme()))
531 return true; // The scheme has been white-listed for every child process.
533 if (IsPseudoScheme(url
.scheme())) {
534 // There are a number of special cases for pseudo schemes.
536 if (url
.SchemeIs(chrome::kViewSourceScheme
)) {
537 // A view-source URL is allowed if the child process is permitted to
538 // request the embedded URL. Careful to avoid pointless recursion.
539 GURL
child_url(url
.path());
540 if (child_url
.SchemeIs(chrome::kViewSourceScheme
) &&
541 url
.SchemeIs(chrome::kViewSourceScheme
))
544 return CanRequestURL(child_id
, child_url
);
547 if (LowerCaseEqualsASCII(url
.spec(), chrome::kAboutBlankURL
))
548 return true; // Every child process can request <about:blank>.
550 // URLs like <about:memory> and <about:crash> shouldn't be requestable by
551 // any child process. Also, this case covers <javascript:...>, which should
552 // be handled internally by the process and not kicked up to the browser.
556 if (!GetContentClient()->browser()->IsHandledURL(url
) &&
557 !net::URLRequest::IsHandledURL(url
)) {
558 return true; // This URL request is destined for ShellExecute.
562 base::AutoLock
lock(lock_
);
564 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
565 if (state
== security_state_
.end())
568 // Otherwise, we consult the child process's security state to see if it is
569 // allowed to request the URL.
570 return state
->second
->CanRequestURL(url
);
574 bool ChildProcessSecurityPolicyImpl::CanReadFile(int child_id
,
575 const FilePath
& file
) {
576 return HasPermissionsForFile(child_id
, file
, kReadFilePermissions
);
579 bool ChildProcessSecurityPolicyImpl::CanReadDirectory(
580 int child_id
, const FilePath
& directory
) {
581 return HasPermissionsForFile(child_id
,
583 kEnumerateDirectoryPermissions
);
586 bool ChildProcessSecurityPolicyImpl::CanReadFileSystem(
587 int child_id
, const std::string
& filesystem_id
) {
588 return HasPermissionsForFileSystem(child_id
,
590 kReadFilePermissions
);
593 bool ChildProcessSecurityPolicyImpl::CanReadWriteFileSystem(
594 int child_id
, const std::string
& filesystem_id
) {
595 return HasPermissionsForFileSystem(child_id
,
597 kReadFilePermissions
|
598 kWriteFilePermissions
);
601 bool ChildProcessSecurityPolicyImpl::HasPermissionsForFile(
602 int child_id
, const FilePath
& file
, int permissions
) {
603 base::AutoLock
lock(lock_
);
604 bool result
= ChildProcessHasPermissionsForFile(child_id
, file
, permissions
);
606 // If this is a worker thread that has no access to a given file,
607 // let's check that its renderer process has access to that file instead.
608 WorkerToMainProcessMap::iterator iter
= worker_map_
.find(child_id
);
609 if (iter
!= worker_map_
.end() && iter
->second
!= 0) {
610 result
= ChildProcessHasPermissionsForFile(iter
->second
,
618 bool ChildProcessSecurityPolicyImpl::HasWebUIBindings(int child_id
) {
619 base::AutoLock
lock(lock_
);
621 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
622 if (state
== security_state_
.end())
625 return state
->second
->has_web_ui_bindings();
628 bool ChildProcessSecurityPolicyImpl::CanReadRawCookies(int child_id
) {
629 base::AutoLock
lock(lock_
);
631 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
632 if (state
== security_state_
.end())
635 return state
->second
->can_read_raw_cookies();
638 void ChildProcessSecurityPolicyImpl::AddChild(int child_id
) {
639 if (security_state_
.count(child_id
) != 0) {
640 NOTREACHED() << "Add child process at most once.";
644 security_state_
[child_id
] = new SecurityState();
647 bool ChildProcessSecurityPolicyImpl::ChildProcessHasPermissionsForFile(
648 int child_id
, const FilePath
& file
, int permissions
) {
649 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
650 if (state
== security_state_
.end())
652 return state
->second
->HasPermissionsForFile(file
, permissions
);
655 bool ChildProcessSecurityPolicyImpl::CanAccessCookiesForOrigin(
656 int child_id
, const GURL
& gurl
) {
657 base::AutoLock
lock(lock_
);
658 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
659 if (state
== security_state_
.end())
661 return state
->second
->CanAccessCookiesForOrigin(gurl
);
664 bool ChildProcessSecurityPolicyImpl::CanSendCookiesForOrigin(int child_id
,
666 base::AutoLock
lock(lock_
);
667 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
668 if (state
== security_state_
.end())
670 return state
->second
->CanSendCookiesForOrigin(gurl
);
673 void ChildProcessSecurityPolicyImpl::LockToOrigin(int child_id
,
675 // "gurl" can be currently empty in some cases, such as file://blah.
676 DCHECK(SiteInstanceImpl::GetSiteForURL(NULL
, gurl
) == gurl
);
677 base::AutoLock
lock(lock_
);
678 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
679 DCHECK(state
!= security_state_
.end());
680 state
->second
->LockToOrigin(gurl
);
683 void ChildProcessSecurityPolicyImpl::GrantPermissionsForFileSystem(
685 const std::string
& filesystem_id
,
687 base::AutoLock
lock(lock_
);
689 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
690 if (state
== security_state_
.end())
692 state
->second
->GrantPermissionsForFileSystem(filesystem_id
, permission
);
695 bool ChildProcessSecurityPolicyImpl::HasPermissionsForFileSystem(
697 const std::string
& filesystem_id
,
699 base::AutoLock
lock(lock_
);
701 SecurityStateMap::iterator state
= security_state_
.find(child_id
);
702 if (state
== security_state_
.end())
704 return state
->second
->HasPermissionsForFileSystem(filesystem_id
, permission
);
707 } // namespace content