|  | // Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef SANDBOX_LINUX_SYSCALL_BROKER_BROKER_FILE_PERMISSION_H_ | 
|  | #define SANDBOX_LINUX_SYSCALL_BROKER_BROKER_FILE_PERMISSION_H_ | 
|  |  | 
|  | #include <string> | 
|  |  | 
|  | #include "base/macros.h" | 
|  | #include "sandbox/sandbox_export.h" | 
|  |  | 
|  | namespace sandbox { | 
|  |  | 
|  | namespace syscall_broker { | 
|  |  | 
|  | // BrokerFilePermission defines a path for whitelisting. | 
|  | // Pick the correct static factory method to create a permission. | 
|  | // CheckOpen and CheckAccess are async signal safe. | 
|  | // Constuction and Destruction are not async signal safe. | 
|  | // |path| is the path to be whitelisted. | 
|  | class SANDBOX_EXPORT BrokerFilePermission { | 
|  | public: | 
|  | ~BrokerFilePermission() {} | 
|  | BrokerFilePermission(const BrokerFilePermission&) = default; | 
|  | BrokerFilePermission& operator=(const BrokerFilePermission&) = default; | 
|  |  | 
|  | static BrokerFilePermission ReadOnly(const std::string& path) { | 
|  | return BrokerFilePermission(path, false, false, true, false, false); | 
|  | } | 
|  |  | 
|  | static BrokerFilePermission ReadOnlyRecursive(const std::string& path) { | 
|  | return BrokerFilePermission(path, true, false, true, false, false); | 
|  | } | 
|  |  | 
|  | static BrokerFilePermission WriteOnly(const std::string& path) { | 
|  | return BrokerFilePermission(path, false, false, false, true, false); | 
|  | } | 
|  |  | 
|  | static BrokerFilePermission ReadWrite(const std::string& path) { | 
|  | return BrokerFilePermission(path, false, false, true, true, false); | 
|  | } | 
|  |  | 
|  | static BrokerFilePermission ReadWriteCreate(const std::string& path) { | 
|  | return BrokerFilePermission(path, false, false, true, true, true); | 
|  | } | 
|  |  | 
|  | static BrokerFilePermission ReadWriteCreateUnlink(const std::string& path) { | 
|  | return BrokerFilePermission(path, false, true, true, true, true); | 
|  | } | 
|  |  | 
|  | static BrokerFilePermission ReadWriteCreateUnlinkRecursive( | 
|  | const std::string& path) { | 
|  | return BrokerFilePermission(path, true, true, true, true, true); | 
|  | } | 
|  |  | 
|  | // Returns true if |requested_filename| is allowed to be opened | 
|  | // by this permission. | 
|  | // If |file_to_open| is not NULL it is set to point to either | 
|  | // the |requested_filename| in the case of a recursive match, | 
|  | // or a pointer the matched path in the whitelist if an absolute | 
|  | // match. | 
|  | // If not NULL |unlink_after_open| is set to point to true if the | 
|  | // caller should unlink the path after openning. | 
|  | // Async signal safe if |file_to_open| is NULL. | 
|  | bool CheckOpen(const char* requested_filename, | 
|  | int flags, | 
|  | const char** file_to_open, | 
|  | bool* unlink_after_open) const; | 
|  | // Returns true if |requested_filename| is allowed to be accessed | 
|  | // by this permission as per access(2). | 
|  | // If |file_to_open| is not NULL it is set to point to either | 
|  | // the |requested_filename| in the case of a recursive match, | 
|  | // or a pointer to the matched path in the whitelist if an absolute | 
|  | // match. | 
|  | // |mode| is per mode argument of access(2). | 
|  | // Async signal safe if |file_to_access| is NULL | 
|  | bool CheckAccess(const char* requested_filename, | 
|  | int mode, | 
|  | const char** file_to_access) const; | 
|  |  | 
|  | private: | 
|  | friend class BrokerFilePermissionTester; | 
|  | BrokerFilePermission(const std::string& path, | 
|  | bool recursive, | 
|  | bool unlink, | 
|  | bool allow_read, | 
|  | bool allow_write, | 
|  | bool allow_create); | 
|  |  | 
|  | // ValidatePath checks |path| and returns true if these conditions are met | 
|  | // * Greater than 0 length | 
|  | // * Is an absolute path | 
|  | // * No trailing slash | 
|  | // * No /../ path traversal | 
|  | static bool ValidatePath(const char* path); | 
|  |  | 
|  | // MatchPath returns true if |requested_filename| is covered by this instance | 
|  | bool MatchPath(const char* requested_filename) const; | 
|  |  | 
|  | // Used in by BrokerFilePermissionTester for tests. | 
|  | static const char* GetErrorMessageForTests(); | 
|  |  | 
|  | // These are not const as std::vector requires copy-assignment and this class | 
|  | // is stored in vectors. All methods are marked const so | 
|  | // the compiler will still enforce no changes outside of the constructor. | 
|  | std::string path_; | 
|  | bool recursive_;  // Allow everything under this path. |path| must be a dir. | 
|  | bool unlink_;     // unlink after opening. | 
|  | bool allow_read_; | 
|  | bool allow_write_; | 
|  | bool allow_create_; | 
|  | }; | 
|  |  | 
|  | }  // namespace syscall_broker | 
|  |  | 
|  | }  // namespace sandbox | 
|  |  | 
|  | #endif  //  SANDBOX_LINUX_SYSCALL_BROKER_BROKER_FILE_PERMISSION_H_ |