1*ec63e07aSXin Li // Copyright 2019 Google LLC 2*ec63e07aSXin Li // 3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License"); 4*ec63e07aSXin Li // you may not use this file except in compliance with the License. 5*ec63e07aSXin Li // You may obtain a copy of the License at 6*ec63e07aSXin Li // 7*ec63e07aSXin Li // https://www.apache.org/licenses/LICENSE-2.0 8*ec63e07aSXin Li // 9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software 10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS, 11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*ec63e07aSXin Li // See the License for the specific language governing permissions and 13*ec63e07aSXin Li // limitations under the License. 14*ec63e07aSXin Li 15*ec63e07aSXin Li #ifndef SANDBOXED_API_SANDBOX2_EXECUTOR_H_ 16*ec63e07aSXin Li #define SANDBOXED_API_SANDBOX2_EXECUTOR_H_ 17*ec63e07aSXin Li 18*ec63e07aSXin Li #include <unistd.h> 19*ec63e07aSXin Li 20*ec63e07aSXin Li #include <memory> 21*ec63e07aSXin Li #include <string> 22*ec63e07aSXin Li #include <utility> 23*ec63e07aSXin Li #include <vector> 24*ec63e07aSXin Li 25*ec63e07aSXin Li #include "absl/base/macros.h" 26*ec63e07aSXin Li #include "absl/log/check.h" 27*ec63e07aSXin Li #include "absl/log/log.h" 28*ec63e07aSXin Li #include "absl/status/statusor.h" 29*ec63e07aSXin Li #include "absl/strings/string_view.h" 30*ec63e07aSXin Li #include "absl/types/span.h" 31*ec63e07aSXin Li #include "sandboxed_api/sandbox2/fork_client.h" 32*ec63e07aSXin Li #include "sandboxed_api/sandbox2/forkserver.pb.h" 33*ec63e07aSXin Li #include "sandboxed_api/sandbox2/ipc.h" 34*ec63e07aSXin Li #include "sandboxed_api/sandbox2/limits.h" 35*ec63e07aSXin Li #include "sandboxed_api/sandbox2/namespace.h" 36*ec63e07aSXin Li #include "sandboxed_api/util/fileops.h" 37*ec63e07aSXin Li 38*ec63e07aSXin Li namespace sandbox2 { 39*ec63e07aSXin Li 40*ec63e07aSXin Li // The sandbox2::Executor class is responsible for both creating and executing 41*ec63e07aSXin Li // new processes which will be sandboxed. 42*ec63e07aSXin Li class Executor final { 43*ec63e07aSXin Li public: 44*ec63e07aSXin Li Executor(const Executor&) = delete; 45*ec63e07aSXin Li Executor& operator=(const Executor&) = delete; 46*ec63e07aSXin Li 47*ec63e07aSXin Li // Initialized with a path to the process that the Executor class will 48*ec63e07aSXin Li // execute 49*ec63e07aSXin Li Executor( 50*ec63e07aSXin Li absl::string_view path, absl::Span<const std::string> argv, 51*ec63e07aSXin Li absl::Span<const std::string> envp = absl::MakeConstSpan(CopyEnviron())) path_(std::string (path))52*ec63e07aSXin Li : path_(std::string(path)), 53*ec63e07aSXin Li argv_(argv.begin(), argv.end()), 54*ec63e07aSXin Li envp_(envp.begin(), envp.end()) { 55*ec63e07aSXin Li CHECK(!path_.empty()); 56*ec63e07aSXin Li SetUpServerSideCommsFd(); 57*ec63e07aSXin Li } 58*ec63e07aSXin Li 59*ec63e07aSXin Li // Executor will own this file-descriptor, so if intend to use it, pass here 60*ec63e07aSXin Li // dup(fd) instead 61*ec63e07aSXin Li Executor( 62*ec63e07aSXin Li int exec_fd, absl::Span<const std::string> argv, 63*ec63e07aSXin Li absl::Span<const std::string> envp = absl::MakeConstSpan(CopyEnviron())) exec_fd_(exec_fd)64*ec63e07aSXin Li : exec_fd_(exec_fd), 65*ec63e07aSXin Li argv_(argv.begin(), argv.end()), 66*ec63e07aSXin Li envp_(envp.begin(), envp.end()) { 67*ec63e07aSXin Li CHECK_GE(exec_fd, 0); 68*ec63e07aSXin Li SetUpServerSideCommsFd(); 69*ec63e07aSXin Li } 70*ec63e07aSXin Li 71*ec63e07aSXin Li // Uses a custom ForkServer (which the supplied ForkClient can communicate 72*ec63e07aSXin Li // with), which knows how to fork (or even execute) new sandboxed processes 73*ec63e07aSXin Li // (hence, no need to supply path/argv/envp here) Executor(ForkClient * fork_client)74*ec63e07aSXin Li explicit Executor(ForkClient* fork_client) 75*ec63e07aSXin Li : enable_sandboxing_pre_execve_(false), fork_client_(fork_client) { 76*ec63e07aSXin Li CHECK(fork_client != nullptr); 77*ec63e07aSXin Li SetUpServerSideCommsFd(); 78*ec63e07aSXin Li } 79*ec63e07aSXin Li 80*ec63e07aSXin Li // Creates a new process which will act as a custom ForkServer. Should be used 81*ec63e07aSXin Li // with custom fork servers only. 82*ec63e07aSXin Li // This function returns immediately and returns a nullptr on failure. 83*ec63e07aSXin Li std::unique_ptr<ForkClient> StartForkServer(); 84*ec63e07aSXin Li 85*ec63e07aSXin Li // Accessors ipc()86*ec63e07aSXin Li IPC* ipc() { return &ipc_; } 87*ec63e07aSXin Li limits()88*ec63e07aSXin Li Limits* limits() { return &limits_; } 89*ec63e07aSXin Li set_enable_sandbox_before_exec(bool value)90*ec63e07aSXin Li Executor& set_enable_sandbox_before_exec(bool value) { 91*ec63e07aSXin Li enable_sandboxing_pre_execve_ = value; 92*ec63e07aSXin Li return *this; 93*ec63e07aSXin Li } 94*ec63e07aSXin Li set_cwd(std::string value)95*ec63e07aSXin Li Executor& set_cwd(std::string value) { 96*ec63e07aSXin Li cwd_ = std::move(value); 97*ec63e07aSXin Li return *this; 98*ec63e07aSXin Li } 99*ec63e07aSXin Li libunwind_recursion_depth()100*ec63e07aSXin Li int libunwind_recursion_depth() { return libunwind_recursion_depth_; } 101*ec63e07aSXin Li 102*ec63e07aSXin Li private: 103*ec63e07aSXin Li friend class MonitorBase; 104*ec63e07aSXin Li friend class PtraceMonitor; 105*ec63e07aSXin Li friend class StackTracePeer; 106*ec63e07aSXin Li 107*ec63e07aSXin Li // Internal constructor for executing libunwind on the given pid 108*ec63e07aSXin Li // enable_sandboxing_pre_execve=false as we are not going to execve. Executor(pid_t libunwind_sbox_for_pid,int libunwind_recursion_depth)109*ec63e07aSXin Li explicit Executor(pid_t libunwind_sbox_for_pid, int libunwind_recursion_depth) 110*ec63e07aSXin Li : libunwind_sbox_for_pid_(libunwind_sbox_for_pid), 111*ec63e07aSXin Li libunwind_recursion_depth_(libunwind_recursion_depth), 112*ec63e07aSXin Li enable_sandboxing_pre_execve_(false) { 113*ec63e07aSXin Li CHECK_GE(libunwind_sbox_for_pid_, 0); 114*ec63e07aSXin Li SetUpServerSideCommsFd(); 115*ec63e07aSXin Li } 116*ec63e07aSXin Li 117*ec63e07aSXin Li // Creates a copy of the environment 118*ec63e07aSXin Li static std::vector<std::string> CopyEnviron(); 119*ec63e07aSXin Li 120*ec63e07aSXin Li // Creates a server-side Comms end-point using a pre-connected file 121*ec63e07aSXin Li // descriptor. 122*ec63e07aSXin Li void SetUpServerSideCommsFd(); 123*ec63e07aSXin Li 124*ec63e07aSXin Li // Starts a new process which is connected with this Executor instance via a 125*ec63e07aSXin Li // Comms channel. 126*ec63e07aSXin Li // For clone_flags refer to Linux' 'man 2 clone'. 127*ec63e07aSXin Li absl::StatusOr<SandboxeeProcess> StartSubProcess( 128*ec63e07aSXin Li int clone_flags, const Namespace* ns = nullptr, 129*ec63e07aSXin Li MonitorType type = FORKSERVER_MONITOR_PTRACE); 130*ec63e07aSXin Li 131*ec63e07aSXin Li // Whether the Executor has been started yet 132*ec63e07aSXin Li bool started_ = false; 133*ec63e07aSXin Li 134*ec63e07aSXin Li // If this executor is running the libunwind sandbox for a process, 135*ec63e07aSXin Li // this variable will hold the PID of the process. Otherwise it is zero. 136*ec63e07aSXin Li pid_t libunwind_sbox_for_pid_ = 0; 137*ec63e07aSXin Li int libunwind_recursion_depth_ = 0; 138*ec63e07aSXin Li 139*ec63e07aSXin Li // Should the sandboxing be enabled before execve() occurs, or the binary will 140*ec63e07aSXin Li // do it by itself, using the Client object's methods 141*ec63e07aSXin Li bool enable_sandboxing_pre_execve_ = true; 142*ec63e07aSXin Li 143*ec63e07aSXin Li // Alternate (path/fd)/argv/envp to be used the in the __NR_execve call. 144*ec63e07aSXin Li sapi::file_util::fileops::FDCloser exec_fd_; 145*ec63e07aSXin Li std::string path_; 146*ec63e07aSXin Li std::vector<std::string> argv_; 147*ec63e07aSXin Li std::vector<std::string> envp_; 148*ec63e07aSXin Li 149*ec63e07aSXin Li // chdir to cwd_, if set. Defaults to current working directory. 150*ec63e07aSXin Li std::string cwd_ = []() { 151*ec63e07aSXin Li std::string cwd = sapi::file_util::fileops::GetCWD(); 152*ec63e07aSXin Li if (cwd.empty()) { 153*ec63e07aSXin Li PLOG(WARNING) << "Getting current working directory"; 154*ec63e07aSXin Li } 155*ec63e07aSXin Li return cwd; 156*ec63e07aSXin Li }(); 157*ec63e07aSXin Li 158*ec63e07aSXin Li // Client (sandboxee) end-point of a socket-pair used to create Comms channel 159*ec63e07aSXin Li sapi::file_util::fileops::FDCloser client_comms_fd_; 160*ec63e07aSXin Li 161*ec63e07aSXin Li // ForkClient connecting to the ForkServer - not owned by the object 162*ec63e07aSXin Li ForkClient* fork_client_ = nullptr; 163*ec63e07aSXin Li 164*ec63e07aSXin Li IPC ipc_; // Used for communication with the sandboxee 165*ec63e07aSXin Li Limits limits_; // Defines server- and client-side limits 166*ec63e07aSXin Li }; 167*ec63e07aSXin Li 168*ec63e07aSXin Li } // namespace sandbox2 169*ec63e07aSXin Li 170*ec63e07aSXin Li #endif // SANDBOXED_API_SANDBOX2_EXECUTOR_H_ 171