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"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/callback_forward.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/pickle.h"
14a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "sandbox/sandbox_export.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace sandbox {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Create a new "broker" process to which we can send requests via an IPC
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// channel.
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is a low level IPC mechanism that is suitable to be called from a
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// signal handler.
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A process would typically create a broker process before entering
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// sandboxing.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. BrokerProcess open_broker(read_whitelist, write_whitelist);
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. CHECK(open_broker.Init(NULL));
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 3. Enable sandbox.
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 4. Use open_broker.Open() to open files.
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass SANDBOX_EXPORT BrokerProcess {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |denied_errno| is the error code returned when methods such as Open()
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // or Access() are invoked on a file which is not in the whitelist. EACCESS
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // would be a typical value.
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |allowed_r_files| and |allowed_w_files| are white lists of files that can
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // be opened later via the Open() API, respectively for reading and writing.
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // A file available read-write should be listed in both.
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |fast_check_in_client| and |quiet_failures_for_tests| are reserved for
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // unit tests, don't use it.
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  explicit BrokerProcess(int denied_errno,
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                         const std::vector<std::string>& allowed_r_files,
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                         const std::vector<std::string>& allowed_w_files,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool fast_check_in_client = true,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         bool quiet_failures_for_tests = false);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~BrokerProcess();
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Will initialize the broker process. There should be no threads at this
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // point, since we need to fork().
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // broker_process_init_callback will be called in the new broker process,
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // after fork() returns.
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool Init(const base::Callback<bool(void)>& broker_process_init_callback);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Can be used in place of access(). Will be async signal safe.
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // X_OK will always return an error in practice since the broker process
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // doesn't support execute permissions.
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // It's similar to the access() system call and will return -errno on errors.
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int Access(const char* pathname, int mode) const;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Can be used in place of open(). Will be async signal safe.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The implementation only supports certain white listed flags and will
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // return -EPERM on other flags.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It's similar to the open() system call and will return -errno on errors.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int Open(const char* pathname, int flags) const;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int broker_pid() const { return broker_pid_; }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enum IPCCommands {
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kCommandInvalid = 0,
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kCommandOpen,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    kCommandAccess,
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int PathAndFlagsSyscall(enum IPCCommands command_type,
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          const char* pathname,
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                          int flags) const;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool HandleRequest() const;
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool HandleRemoteCommand(IPCCommands command_type,
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           int reply_ipc,
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           const Pickle& read_pickle,
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           PickleIterator iter) const;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void AccessFileForIPC(const std::string& requested_filename,
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        int mode,
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        Pickle* write_pickle) const;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OpenFileForIPC(const std::string& requested_filename,
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      int flags,
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      Pickle* write_pickle,
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      std::vector<int>* opened_files) const;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool GetFileNameIfAllowedToAccess(const char*, int, const char**) const;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool GetFileNameIfAllowedToOpen(const char*, int, const char**) const;
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const int denied_errno_;
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool initialized_;               // Whether we've been through Init() yet.
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool is_child_;                  // Whether we're the child (broker process).
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool fast_check_in_client_;      // Whether to forward a request that we know
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   // will be denied to the broker.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool quiet_failures_for_tests_;  // Disable certain error message when
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   // testing for failures.
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  pid_t broker_pid_;               // The PID of the broker (child).
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::vector<std::string> allowed_r_files_;  // Files allowed for read.
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::vector<std::string> allowed_w_files_;  // Files allowed for write.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int ipc_socketpair_;  // Our communication channel to parent or child.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(BrokerProcess);
100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  friend class BrokerProcessTestHelper;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace sandbox
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_
107