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