broker_process.h revision a3f7b4e666c476898878fa745f637129375cd889
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/pickle.h" 13a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sandbox { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Create a new "broker" process to which we can send requests via an IPC 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// channel. 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is a low level IPC mechanism that is suitable to be called from a 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// signal handler. 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A process would typically create a broker process before entering 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// sandboxing. 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. BrokerProcess open_broker(read_whitelist, write_whitelist); 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. CHECK(open_broker.Init(NULL)); 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 3. Enable sandbox. 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 4. Use open_broker.Open() to open files. 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BrokerProcess { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |allowed_file_names| is a white list of files that can be opened later via 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the Open() API. 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |fast_check_in_client| and |quiet_failures_for_tests| are reserved for 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // unit tests, don't use it. 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit BrokerProcess(const std::vector<std::string>& allowed_r_files_, 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<std::string>& allowed_w_files_, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fast_check_in_client = true, 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool quiet_failures_for_tests = false); 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~BrokerProcess(); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Will initialize the broker process. There should be no threads at this 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // point, since we need to fork(). 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // sandbox_callback is a function that should be called to enable the 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // sandbox in the broker. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool Init(bool (*sandbox_callback)(void)); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Can be used in place of access(). Will be async signal safe. 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // X_OK will always EPERM in practice since the broker process doesn't support 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // execute permissions. 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // It's similar to the access() system call and will return -errno on errors. 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int Access(const char* pathname, int mode) const; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Can be used in place of open(). Will be async signal safe. 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The implementation only supports certain white listed flags and will 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // return -EPERM on other flags. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It's similar to the open() system call and will return -errno on errors. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int Open(const char* pathname, int flags) const; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int broker_pid() const { return broker_pid_; } 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enum IPCCommands { 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kCommandInvalid = 0, 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kCommandOpen, 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kCommandAccess, 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int PathAndFlagsSyscall(enum IPCCommands command_type, 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* pathname, int flags) const; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool HandleRequest() const; 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool HandleRemoteCommand(IPCCommands command_type, int reply_ipc, 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Pickle& read_pickle, PickleIterator iter) const; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void AccessFileForIPC(const std::string& requested_filename, 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int mode, Pickle* write_pickle) const; 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OpenFileForIPC(const std::string& requested_filename, 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int flags, Pickle* write_pickle, 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<int>* opened_files) const; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool GetFileNameIfAllowedToAccess(const char*, int, const char**) const; 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool GetFileNameIfAllowedToOpen(const char*, int, const char**) const; 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool initialized_; // Whether we've been through Init() yet. 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_child_; // Whether we're the child (broker process). 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fast_check_in_client_; // Whether to forward a request that we know 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will be denied to the broker. 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool quiet_failures_for_tests_; // Disable certain error message when 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // testing for failures. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pid_t broker_pid_; // The PID of the broker (child). 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<std::string> allowed_r_files_; // Files allowed for read. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<std::string> allowed_w_files_; // Files allowed for write. 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int ipc_socketpair_; // Our communication channel to parent or child. 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_IMPLICIT_CONSTRUCTORS(BrokerProcess); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace sandbox 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_ 92