Home | History | Annotate | Download | only in syscall_broker
      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:
     24   ~BrokerFilePermission() {}
     25   BrokerFilePermission(const BrokerFilePermission&) = default;
     26   BrokerFilePermission& operator=(const BrokerFilePermission&) = default;
     27 
     28   static BrokerFilePermission ReadOnly(const std::string& path) {
     29     return BrokerFilePermission(path, false, false, true, false, false);
     30   }
     31 
     32   static BrokerFilePermission ReadOnlyRecursive(const std::string& path) {
     33     return BrokerFilePermission(path, true, false, true, false, false);
     34   }
     35 
     36   static BrokerFilePermission WriteOnly(const std::string& path) {
     37     return BrokerFilePermission(path, false, false, false, true, false);
     38   }
     39 
     40   static BrokerFilePermission ReadWrite(const std::string& path) {
     41     return BrokerFilePermission(path, false, false, true, true, false);
     42   }
     43 
     44   static BrokerFilePermission ReadWriteCreate(const std::string& path) {
     45     return BrokerFilePermission(path, false, false, true, true, true);
     46   }
     47 
     48   static BrokerFilePermission ReadWriteCreateUnlink(const std::string& path) {
     49     return BrokerFilePermission(path, false, true, true, true, true);
     50   }
     51 
     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_