1// Copyright 2013 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/renderer_host/pepper/pepper_security_helper.h"
6
7#include "base/logging.h"
8#include "content/browser/child_process_security_policy_impl.h"
9#include "ppapi/c/ppb_file_io.h"
10
11namespace content {
12
13namespace {
14
15template <typename CanRead,
16          typename CanWrite,
17          typename CanCreate,
18          typename CanCreateReadWrite,
19          typename FileID>
20bool CanOpenFileWithPepperFlags(CanRead can_read,
21                                CanWrite can_write,
22                                CanCreate can_create,
23                                CanCreateReadWrite can_create_read_write,
24                                int pp_open_flags,
25                                int child_id,
26                                const FileID& file) {
27  ChildProcessSecurityPolicyImpl* policy =
28      ChildProcessSecurityPolicyImpl::GetInstance();
29
30  bool pp_read = !!(pp_open_flags & PP_FILEOPENFLAG_READ);
31  bool pp_write = !!(pp_open_flags & PP_FILEOPENFLAG_WRITE);
32  bool pp_create = !!(pp_open_flags & PP_FILEOPENFLAG_CREATE);
33  bool pp_truncate = !!(pp_open_flags & PP_FILEOPENFLAG_TRUNCATE);
34  bool pp_exclusive = !!(pp_open_flags & PP_FILEOPENFLAG_EXCLUSIVE);
35  bool pp_append = !!(pp_open_flags & PP_FILEOPENFLAG_APPEND);
36
37  if (pp_read && !(policy->*can_read)(child_id, file))
38    return false;
39
40  if (pp_write && !(policy->*can_write)(child_id, file))
41    return false;
42
43  // TODO(tommycli): Maybe tighten up required permission. crbug.com/284792
44  if (pp_append && !(policy->*can_create_read_write)(child_id, file))
45    return false;
46
47  if (pp_truncate && !pp_write)
48    return false;
49
50  if (pp_create) {
51    if (pp_exclusive) {
52      return (policy->*can_create)(child_id, file);
53    } else {
54      // Asks for too much, but this is the only grant that allows overwrite.
55      return (policy->*can_create_read_write)(child_id, file);
56    }
57  } else if (pp_truncate) {
58    return (policy->*can_create_read_write)(child_id, file);
59  }
60
61  return true;
62}
63}
64
65bool CanOpenWithPepperFlags(int pp_open_flags,
66                            int child_id,
67                            const base::FilePath& file) {
68  return CanOpenFileWithPepperFlags(
69      &ChildProcessSecurityPolicyImpl::CanReadFile,
70      &ChildProcessSecurityPolicyImpl::CanCreateReadWriteFile,
71      &ChildProcessSecurityPolicyImpl::CanCreateReadWriteFile,
72      &ChildProcessSecurityPolicyImpl::CanCreateReadWriteFile,
73      pp_open_flags,
74      child_id,
75      file);
76}
77
78bool CanOpenFileSystemURLWithPepperFlags(int pp_open_flags,
79                                         int child_id,
80                                         const storage::FileSystemURL& url) {
81  return CanOpenFileWithPepperFlags(
82      &ChildProcessSecurityPolicyImpl::CanReadFileSystemFile,
83      &ChildProcessSecurityPolicyImpl::CanWriteFileSystemFile,
84      &ChildProcessSecurityPolicyImpl::CanCreateFileSystemFile,
85      &ChildProcessSecurityPolicyImpl::CanCreateReadWriteFileSystemFile,
86      pp_open_flags,
87      child_id,
88      url);
89}
90
91}  // namespace content
92