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_SANDBOX_H_ 16*ec63e07aSXin Li #define SANDBOXED_API_SANDBOX_H_ 17*ec63e07aSXin Li 18*ec63e07aSXin Li #include <ctime> 19*ec63e07aSXin Li #include <initializer_list> 20*ec63e07aSXin Li #include <memory> 21*ec63e07aSXin Li #include <string> 22*ec63e07aSXin Li #include <vector> 23*ec63e07aSXin Li 24*ec63e07aSXin Li #include "sandboxed_api/file_toc.h" 25*ec63e07aSXin Li #include "absl/base/macros.h" 26*ec63e07aSXin Li #include "absl/log/globals.h" 27*ec63e07aSXin Li #include "absl/log/log.h" 28*ec63e07aSXin Li #include "absl/status/status.h" 29*ec63e07aSXin Li #include "absl/status/statusor.h" 30*ec63e07aSXin Li #include "absl/time/time.h" 31*ec63e07aSXin Li #include "sandboxed_api/config.h" 32*ec63e07aSXin Li #include "sandboxed_api/rpcchannel.h" 33*ec63e07aSXin Li #include "sandboxed_api/sandbox2/client.h" 34*ec63e07aSXin Li #include "sandboxed_api/sandbox2/comms.h" 35*ec63e07aSXin Li #include "sandboxed_api/sandbox2/policy.h" 36*ec63e07aSXin Li #include "sandboxed_api/sandbox2/policybuilder.h" 37*ec63e07aSXin Li #include "sandboxed_api/sandbox2/sandbox2.h" 38*ec63e07aSXin Li #include "sandboxed_api/vars.h" 39*ec63e07aSXin Li 40*ec63e07aSXin Li namespace sapi { 41*ec63e07aSXin Li 42*ec63e07aSXin Li // The Sandbox class represents the sandboxed library. It provides users with 43*ec63e07aSXin Li // means to communicate with it (make function calls, transfer memory). 44*ec63e07aSXin Li class Sandbox { 45*ec63e07aSXin Li public: Sandbox(const FileToc * embed_lib_toc)46*ec63e07aSXin Li explicit Sandbox(const FileToc* embed_lib_toc) 47*ec63e07aSXin Li : embed_lib_toc_(embed_lib_toc) {} 48*ec63e07aSXin Li 49*ec63e07aSXin Li Sandbox(const Sandbox&) = delete; 50*ec63e07aSXin Li Sandbox& operator=(const Sandbox&) = delete; 51*ec63e07aSXin Li 52*ec63e07aSXin Li virtual ~Sandbox(); 53*ec63e07aSXin Li 54*ec63e07aSXin Li // Initializes a new sandboxing session. 55*ec63e07aSXin Li absl::Status Init(bool use_unotify_monitor = false); 56*ec63e07aSXin Li 57*ec63e07aSXin Li // Returns whether the current sandboxing session is active. 58*ec63e07aSXin Li bool is_active() const; 59*ec63e07aSXin Li 60*ec63e07aSXin Li // Terminates the current sandboxing session (if it exists). 61*ec63e07aSXin Li void Terminate(bool attempt_graceful_exit = true); 62*ec63e07aSXin Li 63*ec63e07aSXin Li // Restarts the sandbox. Restart(bool attempt_graceful_exit)64*ec63e07aSXin Li absl::Status Restart(bool attempt_graceful_exit) { 65*ec63e07aSXin Li Terminate(attempt_graceful_exit); 66*ec63e07aSXin Li return Init(); 67*ec63e07aSXin Li } 68*ec63e07aSXin Li comms()69*ec63e07aSXin Li sandbox2::Comms* comms() const { return comms_; } 70*ec63e07aSXin Li rpc_channel()71*ec63e07aSXin Li RPCChannel* rpc_channel() const { return rpc_channel_.get(); } 72*ec63e07aSXin Li pid()73*ec63e07aSXin Li int pid() const { return pid_; } 74*ec63e07aSXin Li 75*ec63e07aSXin Li // Synchronizes the underlying memory for the pointer before the call. 76*ec63e07aSXin Li absl::Status SynchronizePtrBefore(v::Callable* ptr); 77*ec63e07aSXin Li 78*ec63e07aSXin Li // Synchronizes the underlying memory for pointer after the call. 79*ec63e07aSXin Li absl::Status SynchronizePtrAfter(v::Callable* ptr) const; 80*ec63e07aSXin Li 81*ec63e07aSXin Li // Makes a call to the sandboxee. 82*ec63e07aSXin Li template <typename... Args> Call(const std::string & func,v::Callable * ret,Args &&...args)83*ec63e07aSXin Li absl::Status Call(const std::string& func, v::Callable* ret, Args&&... args) { 84*ec63e07aSXin Li static_assert(sizeof...(Args) <= FuncCall::kArgsMax, 85*ec63e07aSXin Li "Too many arguments to sapi::Sandbox::Call()"); 86*ec63e07aSXin Li return Call(func, ret, {std::forward<Args>(args)...}); 87*ec63e07aSXin Li } 88*ec63e07aSXin Li absl::Status Call(const std::string& func, v::Callable* ret, 89*ec63e07aSXin Li std::initializer_list<v::Callable*> args); 90*ec63e07aSXin Li 91*ec63e07aSXin Li // Allocates memory in the sandboxee, automatic_free indicates whether the 92*ec63e07aSXin Li // memory should be freed on the remote side when the 'var' goes out of scope. 93*ec63e07aSXin Li absl::Status Allocate(v::Var* var, bool automatic_free = false); 94*ec63e07aSXin Li 95*ec63e07aSXin Li // Frees memory in the sandboxee. 96*ec63e07aSXin Li absl::Status Free(v::Var* var); 97*ec63e07aSXin Li 98*ec63e07aSXin Li // Finds the address of a symbol in the sandboxee. 99*ec63e07aSXin Li absl::Status Symbol(const char* symname, void** addr); 100*ec63e07aSXin Li 101*ec63e07aSXin Li // Transfers memory (both directions). Status is returned (memory transfer 102*ec63e07aSXin Li // succeeded/failed). 103*ec63e07aSXin Li absl::Status TransferToSandboxee(v::Var* var); 104*ec63e07aSXin Li absl::Status TransferFromSandboxee(v::Var* var); 105*ec63e07aSXin Li 106*ec63e07aSXin Li absl::StatusOr<std::string> GetCString(const v::RemotePtr& str, 107*ec63e07aSXin Li size_t max_length = 10ULL 108*ec63e07aSXin Li << 20 /* 10 MiB*/ 109*ec63e07aSXin Li ); 110*ec63e07aSXin Li 111*ec63e07aSXin Li // Waits until the sandbox terminated and returns the result. 112*ec63e07aSXin Li const sandbox2::Result& AwaitResult(); result()113*ec63e07aSXin Li const sandbox2::Result& result() const { return result_; } 114*ec63e07aSXin Li 115*ec63e07aSXin Li absl::Status SetWallTimeLimit(absl::Duration limit) const; 116*ec63e07aSXin Li 117*ec63e07aSXin Li protected: 118*ec63e07aSXin Li 119*ec63e07aSXin Li // Gets extra arguments to be passed to the sandboxee. GetArgs(std::vector<std::string> * args)120*ec63e07aSXin Li virtual void GetArgs(std::vector<std::string>* args) const { 121*ec63e07aSXin Li args->push_back(absl::StrCat("--stderrthreshold=", 122*ec63e07aSXin Li static_cast<int>(absl::StderrThreshold()))); 123*ec63e07aSXin Li } 124*ec63e07aSXin Li 125*ec63e07aSXin Li private: 126*ec63e07aSXin Li // Gets the environment variables passed to the sandboxee. GetEnvs(std::vector<std::string> * envs)127*ec63e07aSXin Li virtual void GetEnvs(std::vector<std::string>* envs) const { 128*ec63e07aSXin Li // Do nothing by default. 129*ec63e07aSXin Li } 130*ec63e07aSXin Li 131*ec63e07aSXin Li // Returns the sandbox policy. Subclasses can modify the default policy 132*ec63e07aSXin Li // builder, or return a completely new policy. 133*ec63e07aSXin Li virtual std::unique_ptr<sandbox2::Policy> ModifyPolicy( 134*ec63e07aSXin Li sandbox2::PolicyBuilder* builder); 135*ec63e07aSXin Li 136*ec63e07aSXin Li // Path of the sandboxee: 137*ec63e07aSXin Li // - relative to runfiles directory: ::sapi::GetDataDependencyFilePath() 138*ec63e07aSXin Li // will be applied to it, 139*ec63e07aSXin Li // - absolute: will be used as is. GetLibPath()140*ec63e07aSXin Li virtual std::string GetLibPath() const { return ""; } 141*ec63e07aSXin Li 142*ec63e07aSXin Li // Modifies the Executor object if needed. ModifyExecutor(sandbox2::Executor * executor)143*ec63e07aSXin Li virtual void ModifyExecutor(sandbox2::Executor* executor) { 144*ec63e07aSXin Li // Do nothing by default. 145*ec63e07aSXin Li } 146*ec63e07aSXin Li 147*ec63e07aSXin Li // Provides a custom notifier for sandboxee events. May return nullptr. CreateNotifier()148*ec63e07aSXin Li virtual std::unique_ptr<sandbox2::Notify> CreateNotifier() { return nullptr; } 149*ec63e07aSXin Li 150*ec63e07aSXin Li // Exits the sandboxee. 151*ec63e07aSXin Li void Exit() const; 152*ec63e07aSXin Li 153*ec63e07aSXin Li // The client to the library forkserver. 154*ec63e07aSXin Li std::unique_ptr<sandbox2::ForkClient> fork_client_; 155*ec63e07aSXin Li std::unique_ptr<sandbox2::Executor> forkserver_executor_; 156*ec63e07aSXin Li 157*ec63e07aSXin Li // The main sandbox2::Sandbox2 object. 158*ec63e07aSXin Li std::unique_ptr<sandbox2::Sandbox2> s2_; 159*ec63e07aSXin Li // Marks whether Sandbox2 result was already fetched. 160*ec63e07aSXin Li // We cannot just delete s2_ as Terminate might be called from another thread 161*ec63e07aSXin Li // and comms object can be still in use then. 162*ec63e07aSXin Li bool s2_awaited_ = false; 163*ec63e07aSXin Li 164*ec63e07aSXin Li // Result of the most recent sandbox execution 165*ec63e07aSXin Li sandbox2::Result result_; 166*ec63e07aSXin Li 167*ec63e07aSXin Li // Comms with the sandboxee. 168*ec63e07aSXin Li sandbox2::Comms* comms_ = nullptr; 169*ec63e07aSXin Li // RPCChannel object. 170*ec63e07aSXin Li std::unique_ptr<RPCChannel> rpc_channel_; 171*ec63e07aSXin Li // The main pid of the sandboxee. 172*ec63e07aSXin Li pid_t pid_ = 0; 173*ec63e07aSXin Li 174*ec63e07aSXin Li // FileTOC with the embedded library, takes precedence over GetLibPath if 175*ec63e07aSXin Li // present (not nullptr). 176*ec63e07aSXin Li const FileToc* embed_lib_toc_; 177*ec63e07aSXin Li }; 178*ec63e07aSXin Li 179*ec63e07aSXin Li } // namespace sapi 180*ec63e07aSXin Li 181*ec63e07aSXin Li #endif // SANDBOXED_API_SANDBOX_H_ 182