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

Side by Side Diff: content/browser/child_process_security_policy_impl.cc

Issue 2108053005: Pull ChildProcessSecurityPolicyImpl out to shared subfolder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 5 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 unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "content/browser/child_process_security_policy_impl.h"
6
7 #include <algorithm>
8 #include <utility>
9
10 #include "base/command_line.h"
11 #include "base/files/file_path.h"
12 #include "base/logging.h"
13 #include "base/macros.h"
14 #include "base/metrics/histogram.h"
15 #include "base/stl_util.h"
16 #include "base/strings/string_util.h"
17 #include "build/build_config.h"
18 #include "content/browser/site_instance_impl.h"
19 #include "content/common/site_isolation_policy.h"
20 #include "content/public/browser/child_process_data.h"
21 #include "content/public/browser/content_browser_client.h"
22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/common/bindings_policy.h"
24 #include "content/public/common/url_constants.h"
25 #include "net/base/filename_util.h"
26 #include "net/url_request/url_request.h"
27 #include "storage/browser/fileapi/file_permission_policy.h"
28 #include "storage/browser/fileapi/file_system_url.h"
29 #include "storage/browser/fileapi/isolated_context.h"
30 #include "storage/common/fileapi/file_system_util.h"
31 #include "url/gurl.h"
32
33 namespace content {
34
35 namespace {
36
37 // Used internally only. These bit positions have no relationship to any
38 // underlying OS and can be changed to accommodate finer-grained permissions.
39 enum ChildProcessSecurityPermissions {
40 READ_FILE_PERMISSION = 1 << 0,
41 WRITE_FILE_PERMISSION = 1 << 1,
42 CREATE_NEW_FILE_PERMISSION = 1 << 2,
43 CREATE_OVERWRITE_FILE_PERMISSION = 1 << 3,
44 DELETE_FILE_PERMISSION = 1 << 4,
45
46 // Used by Media Galleries API
47 COPY_INTO_FILE_PERMISSION = 1 << 5,
48 };
49
50 // Used internally only. Bitmasks that are actually used by the Grant* and Can*
51 // methods. These contain one or more ChildProcessSecurityPermissions.
52 enum ChildProcessSecurityGrants {
53 READ_FILE_GRANT = READ_FILE_PERMISSION,
54 WRITE_FILE_GRANT = WRITE_FILE_PERMISSION,
55
56 CREATE_NEW_FILE_GRANT = CREATE_NEW_FILE_PERMISSION |
57 COPY_INTO_FILE_PERMISSION,
58
59 CREATE_READ_WRITE_FILE_GRANT = CREATE_NEW_FILE_PERMISSION |
60 CREATE_OVERWRITE_FILE_PERMISSION |
61 READ_FILE_PERMISSION |
62 WRITE_FILE_PERMISSION |
63 COPY_INTO_FILE_PERMISSION |
64 DELETE_FILE_PERMISSION,
65
66 COPY_INTO_FILE_GRANT = COPY_INTO_FILE_PERMISSION,
67 DELETE_FILE_GRANT = DELETE_FILE_PERMISSION,
68 };
69
70 } // namespace
71
72 // The SecurityState class is used to maintain per-child process security state
73 // information.
74 class ChildProcessSecurityPolicyImpl::SecurityState {
75 public:
76 SecurityState()
77 : enabled_bindings_(0),
78 can_read_raw_cookies_(false),
79 can_send_midi_sysex_(false) { }
80
81 ~SecurityState() {
82 scheme_policy_.clear();
83 storage::IsolatedContext* isolated_context =
84 storage::IsolatedContext::GetInstance();
85 for (FileSystemMap::iterator iter = filesystem_permissions_.begin();
86 iter != filesystem_permissions_.end();
87 ++iter) {
88 isolated_context->RemoveReference(iter->first);
89 }
90 UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.PerChildFilePermissions",
91 file_permissions_.size());
92 }
93
94 // Grant permission to request URLs with the specified origin.
95 void GrantOrigin(const url::Origin& origin) {
96 origin_set_.insert(origin);
97 }
98
99 // Grant permission to request URLs with the specified scheme.
100 void GrantScheme(const std::string& scheme) {
101 scheme_policy_[scheme] = true;
102 }
103
104 // Revoke permission to request URLs with the specified scheme.
105 void RevokeScheme(const std::string& scheme) {
106 scheme_policy_[scheme] = false;
107 }
108
109 // Grant certain permissions to a file.
110 void GrantPermissionsForFile(const base::FilePath& file, int permissions) {
111 base::FilePath stripped = file.StripTrailingSeparators();
112 file_permissions_[stripped] |= permissions;
113 UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.FilePermissionPathLength",
114 stripped.value().size());
115 }
116
117 // Grant navigation to a file but not the file:// scheme in general.
118 void GrantRequestOfSpecificFile(const base::FilePath &file) {
119 request_file_set_.insert(file.StripTrailingSeparators());
120 }
121
122 // Revokes all permissions granted to a file.
123 void RevokeAllPermissionsForFile(const base::FilePath& file) {
124 base::FilePath stripped = file.StripTrailingSeparators();
125 file_permissions_.erase(stripped);
126 request_file_set_.erase(stripped);
127 }
128
129 // Grant certain permissions to a file.
130 void GrantPermissionsForFileSystem(const std::string& filesystem_id,
131 int permissions) {
132 if (!ContainsKey(filesystem_permissions_, filesystem_id))
133 storage::IsolatedContext::GetInstance()->AddReference(filesystem_id);
134 filesystem_permissions_[filesystem_id] |= permissions;
135 }
136
137 bool HasPermissionsForFileSystem(const std::string& filesystem_id,
138 int permissions) {
139 FileSystemMap::const_iterator it =
140 filesystem_permissions_.find(filesystem_id);
141 if (it == filesystem_permissions_.end())
142 return false;
143 return (it->second & permissions) == permissions;
144 }
145
146 #if defined(OS_ANDROID)
147 // Determine if the certain permissions have been granted to a content URI.
148 bool HasPermissionsForContentUri(const base::FilePath& file,
149 int permissions) {
150 DCHECK(!file.empty());
151 DCHECK(file.IsContentUri());
152 if (!permissions)
153 return false;
154 base::FilePath file_path = file.StripTrailingSeparators();
155 FileMap::const_iterator it = file_permissions_.find(file_path);
156 if (it != file_permissions_.end())
157 return (it->second & permissions) == permissions;
158 return false;
159 }
160 #endif
161
162 void GrantBindings(int bindings) {
163 enabled_bindings_ |= bindings;
164 }
165
166 void GrantReadRawCookies() {
167 can_read_raw_cookies_ = true;
168 }
169
170 void RevokeReadRawCookies() {
171 can_read_raw_cookies_ = false;
172 }
173
174 void GrantPermissionForMidiSysEx() {
175 can_send_midi_sysex_ = true;
176 }
177
178 // Determine whether permission has been granted to commit |url|.
179 bool CanCommitURL(const GURL& url) {
180 // Having permission to a scheme implies permission to all of its URLs.
181 SchemeMap::const_iterator scheme_judgment(
182 scheme_policy_.find(url.scheme()));
183 if (scheme_judgment != scheme_policy_.end())
184 return scheme_judgment->second;
185
186 // Otherwise, check for permission for specific origin.
187 if (ContainsKey(origin_set_, url::Origin(url)))
188 return true;
189
190 // file:// URLs are more granular. The child may have been given
191 // permission to a specific file but not the file:// scheme in general.
192 if (url.SchemeIs(url::kFileScheme)) {
193 base::FilePath path;
194 if (net::FileURLToFilePath(url, &path))
195 return ContainsKey(request_file_set_, path);
196 }
197
198 return false; // Unmentioned schemes are disallowed.
199 }
200
201 // Determine if the certain permissions have been granted to a file.
202 bool HasPermissionsForFile(const base::FilePath& file, int permissions) {
203 #if defined(OS_ANDROID)
204 if (file.IsContentUri())
205 return HasPermissionsForContentUri(file, permissions);
206 #endif
207 if (!permissions || file.empty() || !file.IsAbsolute())
208 return false;
209 base::FilePath current_path = file.StripTrailingSeparators();
210 base::FilePath last_path;
211 int skip = 0;
212 while (current_path != last_path) {
213 base::FilePath base_name = current_path.BaseName();
214 if (base_name.value() == base::FilePath::kParentDirectory) {
215 ++skip;
216 } else if (skip > 0) {
217 if (base_name.value() != base::FilePath::kCurrentDirectory)
218 --skip;
219 } else {
220 FileMap::const_iterator it = file_permissions_.find(current_path);
221 if (it != file_permissions_.end())
222 return (it->second & permissions) == permissions;
223 }
224 last_path = current_path;
225 current_path = current_path.DirName();
226 }
227
228 return false;
229 }
230
231 bool CanAccessDataForOrigin(const GURL& gurl) {
232 if (origin_lock_.is_empty())
233 return true;
234 // TODO(creis): We must pass the valid browser_context to convert hosted
235 // apps URLs. Currently, hosted apps cannot set cookies in this mode.
236 // See http://crbug.com/160576.
237 GURL site_gurl = SiteInstanceImpl::GetSiteForURL(NULL, gurl);
238 return origin_lock_ == site_gurl;
239 }
240
241 void LockToOrigin(const GURL& gurl) {
242 origin_lock_ = gurl;
243 }
244
245 bool has_web_ui_bindings() const {
246 return enabled_bindings_ & BINDINGS_POLICY_WEB_UI;
247 }
248
249 bool can_read_raw_cookies() const {
250 return can_read_raw_cookies_;
251 }
252
253 bool can_send_midi_sysex() const {
254 return can_send_midi_sysex_;
255 }
256
257 private:
258 typedef std::map<std::string, bool> SchemeMap;
259 typedef std::set<url::Origin> OriginSet;
260
261 typedef int FilePermissionFlags; // bit-set of base::File::Flags
262 typedef std::map<base::FilePath, FilePermissionFlags> FileMap;
263 typedef std::map<std::string, FilePermissionFlags> FileSystemMap;
264 typedef std::set<base::FilePath> FileSet;
265
266 // Maps URL schemes to whether permission has been granted or revoked:
267 // |true| means the scheme has been granted.
268 // |false| means the scheme has been revoked.
269 // If a scheme is not present in the map, then it has never been granted
270 // or revoked.
271 SchemeMap scheme_policy_;
272
273 // The set of URL origins to which the child process has been granted
274 // permission.
275 OriginSet origin_set_;
276
277 // The set of files the child process is permited to upload to the web.
278 FileMap file_permissions_;
279
280 // The set of files the child process is permitted to load.
281 FileSet request_file_set_;
282
283 int enabled_bindings_;
284
285 bool can_read_raw_cookies_;
286
287 bool can_send_midi_sysex_;
288
289 GURL origin_lock_;
290
291 // The set of isolated filesystems the child process is permitted to access.
292 FileSystemMap filesystem_permissions_;
293
294 DISALLOW_COPY_AND_ASSIGN(SecurityState);
295 };
296
297 ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() {
298 // We know about these schemes and believe them to be safe.
299 RegisterWebSafeScheme(url::kHttpScheme);
300 RegisterWebSafeScheme(url::kHttpsScheme);
301 RegisterWebSafeScheme(url::kFtpScheme);
302 RegisterWebSafeScheme(url::kDataScheme);
303 RegisterWebSafeScheme("feed");
304 RegisterWebSafeScheme(url::kBlobScheme);
305 RegisterWebSafeScheme(url::kFileSystemScheme);
306
307 // We know about the following pseudo schemes and treat them specially.
308 RegisterPseudoScheme(url::kAboutScheme);
309 RegisterPseudoScheme(url::kJavaScriptScheme);
310 RegisterPseudoScheme(kViewSourceScheme);
311 }
312
313 ChildProcessSecurityPolicyImpl::~ChildProcessSecurityPolicyImpl() {
314 web_safe_schemes_.clear();
315 pseudo_schemes_.clear();
316 STLDeleteContainerPairSecondPointers(security_state_.begin(),
317 security_state_.end());
318 security_state_.clear();
319 }
320
321 // static
322 ChildProcessSecurityPolicy* ChildProcessSecurityPolicy::GetInstance() {
323 return ChildProcessSecurityPolicyImpl::GetInstance();
324 }
325
326 ChildProcessSecurityPolicyImpl* ChildProcessSecurityPolicyImpl::GetInstance() {
327 return base::Singleton<ChildProcessSecurityPolicyImpl>::get();
328 }
329
330 void ChildProcessSecurityPolicyImpl::Add(int child_id) {
331 base::AutoLock lock(lock_);
332 AddChild(child_id);
333 }
334
335 void ChildProcessSecurityPolicyImpl::AddWorker(int child_id,
336 int main_render_process_id) {
337 base::AutoLock lock(lock_);
338 AddChild(child_id);
339 worker_map_[child_id] = main_render_process_id;
340 }
341
342 void ChildProcessSecurityPolicyImpl::Remove(int child_id) {
343 base::AutoLock lock(lock_);
344 SecurityStateMap::iterator it = security_state_.find(child_id);
345 if (it == security_state_.end())
346 return; // May be called multiple times.
347
348 delete it->second;
349 security_state_.erase(it);
350 worker_map_.erase(child_id);
351 }
352
353 void ChildProcessSecurityPolicyImpl::RegisterWebSafeScheme(
354 const std::string& scheme) {
355 base::AutoLock lock(lock_);
356 DCHECK_EQ(0U, web_safe_schemes_.count(scheme)) << "Add schemes at most once.";
357 DCHECK_EQ(0U, pseudo_schemes_.count(scheme))
358 << "Web-safe implies not pseudo.";
359
360 web_safe_schemes_.insert(scheme);
361 }
362
363 bool ChildProcessSecurityPolicyImpl::IsWebSafeScheme(
364 const std::string& scheme) {
365 base::AutoLock lock(lock_);
366
367 return ContainsKey(web_safe_schemes_, scheme);
368 }
369
370 void ChildProcessSecurityPolicyImpl::RegisterPseudoScheme(
371 const std::string& scheme) {
372 base::AutoLock lock(lock_);
373 DCHECK_EQ(0U, pseudo_schemes_.count(scheme)) << "Add schemes at most once.";
374 DCHECK_EQ(0U, web_safe_schemes_.count(scheme))
375 << "Pseudo implies not web-safe.";
376
377 pseudo_schemes_.insert(scheme);
378 }
379
380 bool ChildProcessSecurityPolicyImpl::IsPseudoScheme(
381 const std::string& scheme) {
382 base::AutoLock lock(lock_);
383
384 return ContainsKey(pseudo_schemes_, scheme);
385 }
386
387 void ChildProcessSecurityPolicyImpl::GrantRequestURL(
388 int child_id, const GURL& url) {
389
390 if (!url.is_valid())
391 return; // Can't grant the capability to request invalid URLs.
392
393 if (IsWebSafeScheme(url.scheme()))
394 return; // The scheme has already been whitelisted for every child process.
395
396 if (IsPseudoScheme(url.scheme())) {
397 return; // Can't grant the capability to request pseudo schemes.
398 }
399
400 {
401 base::AutoLock lock(lock_);
402 SecurityStateMap::iterator state = security_state_.find(child_id);
403 if (state == security_state_.end())
404 return;
405
406 // When the child process has been commanded to request this scheme,
407 // we grant it the capability to request all URLs of that scheme.
408 state->second->GrantScheme(url.scheme());
409 }
410 }
411
412 void ChildProcessSecurityPolicyImpl::GrantRequestSpecificFileURL(
413 int child_id,
414 const GURL& url) {
415 if (!url.SchemeIs(url::kFileScheme))
416 return;
417
418 {
419 base::AutoLock lock(lock_);
420 SecurityStateMap::iterator state = security_state_.find(child_id);
421 if (state == security_state_.end())
422 return;
423
424 // When the child process has been commanded to request a file:// URL,
425 // then we grant it the capability for that URL only.
426 base::FilePath path;
427 if (net::FileURLToFilePath(url, &path))
428 state->second->GrantRequestOfSpecificFile(path);
429 }
430 }
431
432 void ChildProcessSecurityPolicyImpl::GrantReadFile(int child_id,
433 const base::FilePath& file) {
434 GrantPermissionsForFile(child_id, file, READ_FILE_GRANT);
435 }
436
437 void ChildProcessSecurityPolicyImpl::GrantCreateReadWriteFile(
438 int child_id, const base::FilePath& file) {
439 GrantPermissionsForFile(child_id, file, CREATE_READ_WRITE_FILE_GRANT);
440 }
441
442 void ChildProcessSecurityPolicyImpl::GrantCopyInto(int child_id,
443 const base::FilePath& dir) {
444 GrantPermissionsForFile(child_id, dir, COPY_INTO_FILE_GRANT);
445 }
446
447 void ChildProcessSecurityPolicyImpl::GrantDeleteFrom(
448 int child_id, const base::FilePath& dir) {
449 GrantPermissionsForFile(child_id, dir, DELETE_FILE_GRANT);
450 }
451
452 void ChildProcessSecurityPolicyImpl::GrantPermissionsForFile(
453 int child_id, const base::FilePath& file, int permissions) {
454 base::AutoLock lock(lock_);
455
456 SecurityStateMap::iterator state = security_state_.find(child_id);
457 if (state == security_state_.end())
458 return;
459
460 state->second->GrantPermissionsForFile(file, permissions);
461 }
462
463 void ChildProcessSecurityPolicyImpl::RevokeAllPermissionsForFile(
464 int child_id, const base::FilePath& file) {
465 base::AutoLock lock(lock_);
466
467 SecurityStateMap::iterator state = security_state_.find(child_id);
468 if (state == security_state_.end())
469 return;
470
471 state->second->RevokeAllPermissionsForFile(file);
472 }
473
474 void ChildProcessSecurityPolicyImpl::GrantReadFileSystem(
475 int child_id, const std::string& filesystem_id) {
476 GrantPermissionsForFileSystem(child_id, filesystem_id, READ_FILE_GRANT);
477 }
478
479 void ChildProcessSecurityPolicyImpl::GrantWriteFileSystem(
480 int child_id, const std::string& filesystem_id) {
481 GrantPermissionsForFileSystem(child_id, filesystem_id, WRITE_FILE_GRANT);
482 }
483
484 void ChildProcessSecurityPolicyImpl::GrantCreateFileForFileSystem(
485 int child_id, const std::string& filesystem_id) {
486 GrantPermissionsForFileSystem(child_id, filesystem_id, CREATE_NEW_FILE_GRANT);
487 }
488
489 void ChildProcessSecurityPolicyImpl::GrantCreateReadWriteFileSystem(
490 int child_id, const std::string& filesystem_id) {
491 GrantPermissionsForFileSystem(
492 child_id, filesystem_id, CREATE_READ_WRITE_FILE_GRANT);
493 }
494
495 void ChildProcessSecurityPolicyImpl::GrantCopyIntoFileSystem(
496 int child_id, const std::string& filesystem_id) {
497 GrantPermissionsForFileSystem(child_id, filesystem_id, COPY_INTO_FILE_GRANT);
498 }
499
500 void ChildProcessSecurityPolicyImpl::GrantDeleteFromFileSystem(
501 int child_id, const std::string& filesystem_id) {
502 GrantPermissionsForFileSystem(child_id, filesystem_id, DELETE_FILE_GRANT);
503 }
504
505 void ChildProcessSecurityPolicyImpl::GrantSendMidiSysExMessage(int child_id) {
506 base::AutoLock lock(lock_);
507
508 SecurityStateMap::iterator state = security_state_.find(child_id);
509 if (state == security_state_.end())
510 return;
511
512 state->second->GrantPermissionForMidiSysEx();
513 }
514
515 void ChildProcessSecurityPolicyImpl::GrantOrigin(int child_id,
516 const url::Origin& origin) {
517 base::AutoLock lock(lock_);
518
519 SecurityStateMap::iterator state = security_state_.find(child_id);
520 if (state == security_state_.end())
521 return;
522
523 state->second->GrantOrigin(origin);
524 }
525
526 void ChildProcessSecurityPolicyImpl::GrantScheme(int child_id,
527 const std::string& scheme) {
528 base::AutoLock lock(lock_);
529
530 SecurityStateMap::iterator state = security_state_.find(child_id);
531 if (state == security_state_.end())
532 return;
533
534 state->second->GrantScheme(scheme);
535 }
536
537 void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id) {
538 base::AutoLock lock(lock_);
539
540 SecurityStateMap::iterator state = security_state_.find(child_id);
541 if (state == security_state_.end())
542 return;
543
544 state->second->GrantBindings(BINDINGS_POLICY_WEB_UI);
545
546 // Web UI bindings need the ability to request chrome: URLs.
547 state->second->GrantScheme(kChromeUIScheme);
548
549 // Web UI pages can contain links to file:// URLs.
550 state->second->GrantScheme(url::kFileScheme);
551 }
552
553 void ChildProcessSecurityPolicyImpl::GrantReadRawCookies(int child_id) {
554 base::AutoLock lock(lock_);
555
556 SecurityStateMap::iterator state = security_state_.find(child_id);
557 if (state == security_state_.end())
558 return;
559
560 state->second->GrantReadRawCookies();
561 }
562
563 void ChildProcessSecurityPolicyImpl::RevokeReadRawCookies(int child_id) {
564 base::AutoLock lock(lock_);
565
566 SecurityStateMap::iterator state = security_state_.find(child_id);
567 if (state == security_state_.end())
568 return;
569
570 state->second->RevokeReadRawCookies();
571 }
572
573 bool ChildProcessSecurityPolicyImpl::CanRequestURL(
574 int child_id, const GURL& url) {
575 if (!url.is_valid())
576 return false; // Can't request invalid URLs.
577
578 if (IsPseudoScheme(url.scheme())) {
579 // Every child process can request <about:blank>.
580 if (base::LowerCaseEqualsASCII(url.spec(), url::kAboutBlankURL))
581 return true;
582 // URLs like <about:version>, <about:crash>, <view-source:...> shouldn't be
583 // requestable by any child process. Also, this case covers
584 // <javascript:...>, which should be handled internally by the process and
585 // not kicked up to the browser.
586 return false;
587 }
588
589 // If the process can commit the URL, it can request it.
590 if (CanCommitURL(child_id, url))
591 return true;
592
593 // Also allow URLs destined for ShellExecute and not the browser itself.
594 return !GetContentClient()->browser()->IsHandledURL(url) &&
595 !net::URLRequest::IsHandledURL(url);
596 }
597
598 bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id,
599 const GURL& url) {
600 if (!url.is_valid())
601 return false; // Can't commit invalid URLs.
602
603 // Of all the pseudo schemes, only about:blank is allowed to commit.
604 if (IsPseudoScheme(url.scheme()))
605 return base::LowerCaseEqualsASCII(url.spec(), url::kAboutBlankURL);
606
607 // TODO(creis): Tighten this for Site Isolation, so that a URL from a site
608 // that is isolated can only be committed in a process dedicated to that site.
609 // CanRequestURL should still allow all web-safe schemes. See
610 // https://crbug.com/515309.
611 if (IsWebSafeScheme(url.scheme()))
612 return true; // The scheme has been white-listed for every child process.
613
614 {
615 base::AutoLock lock(lock_);
616
617 SecurityStateMap::iterator state = security_state_.find(child_id);
618 if (state == security_state_.end())
619 return false;
620
621 // Otherwise, we consult the child process's security state to see if it is
622 // allowed to commit the URL.
623 return state->second->CanCommitURL(url);
624 }
625 }
626
627 bool ChildProcessSecurityPolicyImpl::CanReadFile(int child_id,
628 const base::FilePath& file) {
629 return HasPermissionsForFile(child_id, file, READ_FILE_GRANT);
630 }
631
632 bool ChildProcessSecurityPolicyImpl::CanReadAllFiles(
633 int child_id,
634 const std::vector<base::FilePath>& files) {
635 return std::all_of(files.begin(), files.end(),
636 [this, child_id](const base::FilePath& file) {
637 return CanReadFile(child_id, file);
638 });
639 }
640
641 bool ChildProcessSecurityPolicyImpl::CanCreateReadWriteFile(
642 int child_id,
643 const base::FilePath& file) {
644 return HasPermissionsForFile(child_id, file, CREATE_READ_WRITE_FILE_GRANT);
645 }
646
647 bool ChildProcessSecurityPolicyImpl::CanReadFileSystem(
648 int child_id, const std::string& filesystem_id) {
649 return HasPermissionsForFileSystem(child_id, filesystem_id, READ_FILE_GRANT);
650 }
651
652 bool ChildProcessSecurityPolicyImpl::CanReadWriteFileSystem(
653 int child_id, const std::string& filesystem_id) {
654 return HasPermissionsForFileSystem(child_id, filesystem_id,
655 READ_FILE_GRANT | WRITE_FILE_GRANT);
656 }
657
658 bool ChildProcessSecurityPolicyImpl::CanCopyIntoFileSystem(
659 int child_id, const std::string& filesystem_id) {
660 return HasPermissionsForFileSystem(child_id, filesystem_id,
661 COPY_INTO_FILE_GRANT);
662 }
663
664 bool ChildProcessSecurityPolicyImpl::CanDeleteFromFileSystem(
665 int child_id, const std::string& filesystem_id) {
666 return HasPermissionsForFileSystem(child_id, filesystem_id,
667 DELETE_FILE_GRANT);
668 }
669
670 bool ChildProcessSecurityPolicyImpl::HasPermissionsForFile(
671 int child_id, const base::FilePath& file, int permissions) {
672 base::AutoLock lock(lock_);
673 bool result = ChildProcessHasPermissionsForFile(child_id, file, permissions);
674 if (!result) {
675 // If this is a worker thread that has no access to a given file,
676 // let's check that its renderer process has access to that file instead.
677 WorkerToMainProcessMap::iterator iter = worker_map_.find(child_id);
678 if (iter != worker_map_.end() && iter->second != 0) {
679 result = ChildProcessHasPermissionsForFile(iter->second,
680 file,
681 permissions);
682 }
683 }
684 return result;
685 }
686
687 bool ChildProcessSecurityPolicyImpl::HasPermissionsForFileSystemFile(
688 int child_id,
689 const storage::FileSystemURL& url,
690 int permissions) {
691 if (!url.is_valid())
692 return false;
693
694 if (url.path().ReferencesParent())
695 return false;
696
697 // Any write access is disallowed on the root path.
698 if (storage::VirtualPath::IsRootPath(url.path()) &&
699 (permissions & ~READ_FILE_GRANT)) {
700 return false;
701 }
702
703 if (url.mount_type() == storage::kFileSystemTypeIsolated) {
704 // When Isolated filesystems is overlayed on top of another filesystem,
705 // its per-filesystem permission overrides the underlying filesystem
706 // permissions).
707 return HasPermissionsForFileSystem(
708 child_id, url.mount_filesystem_id(), permissions);
709 }
710
711 FileSystemPermissionPolicyMap::iterator found =
712 file_system_policy_map_.find(url.type());
713 if (found == file_system_policy_map_.end())
714 return false;
715
716 if ((found->second & storage::FILE_PERMISSION_READ_ONLY) &&
717 permissions & ~READ_FILE_GRANT) {
718 return false;
719 }
720
721 if (found->second & storage::FILE_PERMISSION_USE_FILE_PERMISSION)
722 return HasPermissionsForFile(child_id, url.path(), permissions);
723
724 if (found->second & storage::FILE_PERMISSION_SANDBOX)
725 return true;
726
727 return false;
728 }
729
730 bool ChildProcessSecurityPolicyImpl::CanReadFileSystemFile(
731 int child_id,
732 const storage::FileSystemURL& url) {
733 return HasPermissionsForFileSystemFile(child_id, url, READ_FILE_GRANT);
734 }
735
736 bool ChildProcessSecurityPolicyImpl::CanWriteFileSystemFile(
737 int child_id,
738 const storage::FileSystemURL& url) {
739 return HasPermissionsForFileSystemFile(child_id, url, WRITE_FILE_GRANT);
740 }
741
742 bool ChildProcessSecurityPolicyImpl::CanCreateFileSystemFile(
743 int child_id,
744 const storage::FileSystemURL& url) {
745 return HasPermissionsForFileSystemFile(child_id, url, CREATE_NEW_FILE_GRANT);
746 }
747
748 bool ChildProcessSecurityPolicyImpl::CanCreateReadWriteFileSystemFile(
749 int child_id,
750 const storage::FileSystemURL& url) {
751 return HasPermissionsForFileSystemFile(child_id, url,
752 CREATE_READ_WRITE_FILE_GRANT);
753 }
754
755 bool ChildProcessSecurityPolicyImpl::CanCopyIntoFileSystemFile(
756 int child_id,
757 const storage::FileSystemURL& url) {
758 return HasPermissionsForFileSystemFile(child_id, url, COPY_INTO_FILE_GRANT);
759 }
760
761 bool ChildProcessSecurityPolicyImpl::CanDeleteFileSystemFile(
762 int child_id,
763 const storage::FileSystemURL& url) {
764 return HasPermissionsForFileSystemFile(child_id, url, DELETE_FILE_GRANT);
765 }
766
767 bool ChildProcessSecurityPolicyImpl::HasWebUIBindings(int child_id) {
768 base::AutoLock lock(lock_);
769
770 SecurityStateMap::iterator state = security_state_.find(child_id);
771 if (state == security_state_.end())
772 return false;
773
774 return state->second->has_web_ui_bindings();
775 }
776
777 bool ChildProcessSecurityPolicyImpl::CanReadRawCookies(int child_id) {
778 base::AutoLock lock(lock_);
779
780 SecurityStateMap::iterator state = security_state_.find(child_id);
781 if (state == security_state_.end())
782 return false;
783
784 return state->second->can_read_raw_cookies();
785 }
786
787 void ChildProcessSecurityPolicyImpl::AddChild(int child_id) {
788 if (security_state_.count(child_id) != 0) {
789 NOTREACHED() << "Add child process at most once.";
790 return;
791 }
792
793 security_state_[child_id] = new SecurityState();
794 }
795
796 bool ChildProcessSecurityPolicyImpl::ChildProcessHasPermissionsForFile(
797 int child_id, const base::FilePath& file, int permissions) {
798 SecurityStateMap::iterator state = security_state_.find(child_id);
799 if (state == security_state_.end())
800 return false;
801 return state->second->HasPermissionsForFile(file, permissions);
802 }
803
804 bool ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin(int child_id,
805 const GURL& gurl) {
806 base::AutoLock lock(lock_);
807 SecurityStateMap::iterator state = security_state_.find(child_id);
808 if (state == security_state_.end()) {
809 // TODO(nick): Returning true instead of false here is a temporary
810 // workaround for https://crbug.com/600441
811 return true;
812 }
813 return state->second->CanAccessDataForOrigin(gurl);
814 }
815
816 void ChildProcessSecurityPolicyImpl::LockToOrigin(int child_id,
817 const GURL& gurl) {
818 // "gurl" can be currently empty in some cases, such as file://blah.
819 DCHECK(SiteInstanceImpl::GetSiteForURL(NULL, gurl) == gurl);
820 base::AutoLock lock(lock_);
821 SecurityStateMap::iterator state = security_state_.find(child_id);
822 DCHECK(state != security_state_.end());
823 state->second->LockToOrigin(gurl);
824 }
825
826 void ChildProcessSecurityPolicyImpl::GrantPermissionsForFileSystem(
827 int child_id,
828 const std::string& filesystem_id,
829 int permission) {
830 base::AutoLock lock(lock_);
831
832 SecurityStateMap::iterator state = security_state_.find(child_id);
833 if (state == security_state_.end())
834 return;
835 state->second->GrantPermissionsForFileSystem(filesystem_id, permission);
836 }
837
838 bool ChildProcessSecurityPolicyImpl::HasPermissionsForFileSystem(
839 int child_id,
840 const std::string& filesystem_id,
841 int permission) {
842 base::AutoLock lock(lock_);
843
844 SecurityStateMap::iterator state = security_state_.find(child_id);
845 if (state == security_state_.end())
846 return false;
847 return state->second->HasPermissionsForFileSystem(filesystem_id, permission);
848 }
849
850 void ChildProcessSecurityPolicyImpl::RegisterFileSystemPermissionPolicy(
851 storage::FileSystemType type,
852 int policy) {
853 base::AutoLock lock(lock_);
854 file_system_policy_map_[type] = policy;
855 }
856
857 bool ChildProcessSecurityPolicyImpl::CanSendMidiSysExMessage(int child_id) {
858 base::AutoLock lock(lock_);
859
860 SecurityStateMap::iterator state = security_state_.find(child_id);
861 if (state == security_state_.end())
862 return false;
863
864 return state->second->can_send_midi_sysex();
865 }
866
867 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/child_process_security_policy_impl.h ('k') | content/browser/child_process_security_policy_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698