// 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_