[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / content / browser / child_process_security_policy_impl.cc
blob21ccb5f2c6a90ef14ab5b9d18e6748bf15a16983
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"
25 namespace content {
27 namespace {
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;
46 } // namespace
48 // The SecurityState class is used to maintain per-child process security state
49 // information.
50 class ChildProcessSecurityPolicyImpl::SecurityState {
51 public:
52 SecurityState()
53 : enabled_bindings_(0),
54 can_read_raw_cookies_(false) { }
56 ~SecurityState() {
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();
62 ++iter) {
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,
101 int permissions) {
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,
109 int permissions) {
110 if (filesystem_permissions_.find(filesystem_id) ==
111 filesystem_permissions_.end())
112 return false;
113 return (filesystem_permissions_[filesystem_id] & permissions) ==
114 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)) {
139 FilePath path;
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();
150 FilePath last_path;
151 int skip = 0;
152 while (current_path != last_path) {
153 FilePath base_name = current_path.BaseName();
154 if (base_name.value() == FilePath::kParentDirectory) {
155 ++skip;
156 } else if (skip > 0) {
157 if (base_name.value() != FilePath::kCurrentDirectory)
158 --skip;
159 } else {
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();
167 return false;
170 bool CanLoadPage(const GURL& gurl) {
171 if (origin_lock_.is_empty())
172 return true;
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())
183 return true;
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))
199 return true;
201 if (origin_lock_.is_empty())
202 return true;
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) {
211 origin_lock_ = 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_;
222 private:
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
234 // or revoked.
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_;
247 GURL origin_lock_;
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();
279 // static
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_);
290 AddChild(child_id);
293 void ChildProcessSecurityPolicyImpl::AddWorker(int child_id,
294 int main_render_process_id) {
295 base::AutoLock lock(lock_);
296 AddChild(child_id);
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) {
358 if (!url.is_valid())
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())
382 return;
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(
391 int child_id,
392 const GURL& url) {
393 if (!url.SchemeIs(chrome::kFileScheme))
394 return;
397 base::AutoLock lock(lock_);
398 SecurityStateMap::iterator state = security_state_.find(child_id);
399 if (state == security_state_.end())
400 return;
402 // When the child process has been commanded to request a file:// URL,
403 // then we grant it the capability for that URL only.
404 FilePath path;
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())
426 return;
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())
437 return;
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())
460 return;
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())
470 return;
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())
486 return;
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())
496 return;
498 state->second->RevokeReadRawCookies();
501 bool ChildProcessSecurityPolicyImpl::CanLoadPage(
502 int child_id,
503 const GURL& url,
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())
516 return false;
517 return state->second->CanLoadPage(url);
519 return true;
522 bool ChildProcessSecurityPolicyImpl::CanRequestURL(
523 int child_id, const GURL& url) {
524 if (!url.is_valid())
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))
542 return false;
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.
553 return false;
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())
566 return false;
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,
582 directory,
583 kEnumerateDirectoryPermissions);
586 bool ChildProcessSecurityPolicyImpl::CanReadFileSystem(
587 int child_id, const std::string& filesystem_id) {
588 return HasPermissionsForFileSystem(child_id,
589 filesystem_id,
590 kReadFilePermissions);
593 bool ChildProcessSecurityPolicyImpl::CanReadWriteFileSystem(
594 int child_id, const std::string& filesystem_id) {
595 return HasPermissionsForFileSystem(child_id,
596 filesystem_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);
605 if (!result) {
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,
611 file,
612 permissions);
615 return result;
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())
623 return false;
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())
633 return false;
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.";
641 return;
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())
651 return false;
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())
660 return false;
661 return state->second->CanAccessCookiesForOrigin(gurl);
664 bool ChildProcessSecurityPolicyImpl::CanSendCookiesForOrigin(int child_id,
665 const GURL& gurl) {
666 base::AutoLock lock(lock_);
667 SecurityStateMap::iterator state = security_state_.find(child_id);
668 if (state == security_state_.end())
669 return false;
670 return state->second->CanSendCookiesForOrigin(gurl);
673 void ChildProcessSecurityPolicyImpl::LockToOrigin(int child_id,
674 const GURL& gurl) {
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(
684 int child_id,
685 const std::string& filesystem_id,
686 int permission) {
687 base::AutoLock lock(lock_);
689 SecurityStateMap::iterator state = security_state_.find(child_id);
690 if (state == security_state_.end())
691 return;
692 state->second->GrantPermissionsForFileSystem(filesystem_id, permission);
695 bool ChildProcessSecurityPolicyImpl::HasPermissionsForFileSystem(
696 int child_id,
697 const std::string& filesystem_id,
698 int permission) {
699 base::AutoLock lock(lock_);
701 SecurityStateMap::iterator state = security_state_.find(child_id);
702 if (state == security_state_.end())
703 return false;
704 return state->second->HasPermissionsForFileSystem(filesystem_id, permission);
707 } // namespace content