• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 #ifndef SANDBOX_LINUX_SYSCALL_BROKER_BROKER_FILE_PERMISSION_H_
6 #define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_FILE_PERMISSION_H_
7 
8 #include <string>
9 
10 #include "base/macros.h"
11 #include "sandbox/sandbox_export.h"
12 
13 namespace sandbox {
14 
15 namespace syscall_broker {
16 
17 // BrokerFilePermission defines a path for whitelisting.
18 // Pick the correct static factory method to create a permission.
19 // CheckOpen and CheckAccess are async signal safe.
20 // Constuction and Destruction are not async signal safe.
21 // |path| is the path to be whitelisted.
22 class SANDBOX_EXPORT BrokerFilePermission {
23  public:
~BrokerFilePermission()24   ~BrokerFilePermission() {}
25   BrokerFilePermission(const BrokerFilePermission&) = default;
26   BrokerFilePermission& operator=(const BrokerFilePermission&) = default;
27 
ReadOnly(const std::string & path)28   static BrokerFilePermission ReadOnly(const std::string& path) {
29     return BrokerFilePermission(path, false, false, true, false, false);
30   }
31 
ReadOnlyRecursive(const std::string & path)32   static BrokerFilePermission ReadOnlyRecursive(const std::string& path) {
33     return BrokerFilePermission(path, true, false, true, false, false);
34   }
35 
WriteOnly(const std::string & path)36   static BrokerFilePermission WriteOnly(const std::string& path) {
37     return BrokerFilePermission(path, false, false, false, true, false);
38   }
39 
ReadWrite(const std::string & path)40   static BrokerFilePermission ReadWrite(const std::string& path) {
41     return BrokerFilePermission(path, false, false, true, true, false);
42   }
43 
ReadWriteCreate(const std::string & path)44   static BrokerFilePermission ReadWriteCreate(const std::string& path) {
45     return BrokerFilePermission(path, false, false, true, true, true);
46   }
47 
ReadWriteCreateUnlink(const std::string & path)48   static BrokerFilePermission ReadWriteCreateUnlink(const std::string& path) {
49     return BrokerFilePermission(path, false, true, true, true, true);
50   }
51 
ReadWriteCreateUnlinkRecursive(const std::string & path)52   static BrokerFilePermission ReadWriteCreateUnlinkRecursive(
53       const std::string& path) {
54     return BrokerFilePermission(path, true, true, true, true, true);
55   }
56 
57   // Returns true if |requested_filename| is allowed to be opened
58   // by this permission.
59   // If |file_to_open| is not NULL it is set to point to either
60   // the |requested_filename| in the case of a recursive match,
61   // or a pointer the matched path in the whitelist if an absolute
62   // match.
63   // If not NULL |unlink_after_open| is set to point to true if the
64   // caller should unlink the path after openning.
65   // Async signal safe if |file_to_open| is NULL.
66   bool CheckOpen(const char* requested_filename,
67                  int flags,
68                  const char** file_to_open,
69                  bool* unlink_after_open) const;
70   // Returns true if |requested_filename| is allowed to be accessed
71   // by this permission as per access(2).
72   // If |file_to_open| is not NULL it is set to point to either
73   // the |requested_filename| in the case of a recursive match,
74   // or a pointer to the matched path in the whitelist if an absolute
75   // match.
76   // |mode| is per mode argument of access(2).
77   // Async signal safe if |file_to_access| is NULL
78   bool CheckAccess(const char* requested_filename,
79                    int mode,
80                    const char** file_to_access) const;
81 
82  private:
83   friend class BrokerFilePermissionTester;
84   BrokerFilePermission(const std::string& path,
85                        bool recursive,
86                        bool unlink,
87                        bool allow_read,
88                        bool allow_write,
89                        bool allow_create);
90 
91   // ValidatePath checks |path| and returns true if these conditions are met
92   // * Greater than 0 length
93   // * Is an absolute path
94   // * No trailing slash
95   // * No /../ path traversal
96   static bool ValidatePath(const char* path);
97 
98   // MatchPath returns true if |requested_filename| is covered by this instance
99   bool MatchPath(const char* requested_filename) const;
100 
101   // Used in by BrokerFilePermissionTester for tests.
102   static const char* GetErrorMessageForTests();
103 
104   // These are not const as std::vector requires copy-assignment and this class
105   // is stored in vectors. All methods are marked const so
106   // the compiler will still enforce no changes outside of the constructor.
107   std::string path_;
108   bool recursive_;  // Allow everything under this path. |path| must be a dir.
109   bool unlink_;     // unlink after opening.
110   bool allow_read_;
111   bool allow_write_;
112   bool allow_create_;
113 };
114 
115 }  // namespace syscall_broker
116 
117 }  // namespace sandbox
118 
119 #endif  //  SANDBOX_LINUX_SYSCALL_BROKER_BROKER_FILE_PERMISSION_H_