2020-01-17 21:05:03 +08:00
|
|
|
// Copyright 2019 Google LLC
|
2019-03-19 00:21:48 +08:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#ifndef SANDBOXED_API_SANDBOX_H_
|
|
|
|
#define SANDBOXED_API_SANDBOX_H_
|
|
|
|
|
|
|
|
#include <memory>
|
2019-03-26 22:54:02 +08:00
|
|
|
#include <string>
|
2019-03-19 00:21:48 +08:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "sandboxed_api/file_toc.h"
|
|
|
|
#include "absl/base/macros.h"
|
2020-10-27 00:08:06 +08:00
|
|
|
#include "absl/status/statusor.h"
|
2019-03-19 00:21:48 +08:00
|
|
|
#include "sandboxed_api/rpcchannel.h"
|
|
|
|
#include "sandboxed_api/sandbox2/client.h"
|
|
|
|
#include "sandboxed_api/sandbox2/comms.h"
|
|
|
|
#include "sandboxed_api/sandbox2/policy.h"
|
|
|
|
#include "sandboxed_api/sandbox2/policybuilder.h"
|
|
|
|
#include "sandboxed_api/sandbox2/sandbox2.h"
|
|
|
|
#include "sandboxed_api/vars.h"
|
|
|
|
|
|
|
|
namespace sapi {
|
|
|
|
|
|
|
|
// The Sandbox class represents the sandboxed library. It provides users with
|
|
|
|
// means to communicate with it (make function calls, transfer memory).
|
|
|
|
class Sandbox {
|
|
|
|
public:
|
2020-08-07 15:30:04 +08:00
|
|
|
explicit Sandbox(const FileToc* embed_lib_toc)
|
|
|
|
: embed_lib_toc_(embed_lib_toc) {}
|
|
|
|
|
2019-03-19 00:21:48 +08:00
|
|
|
Sandbox(const Sandbox&) = delete;
|
|
|
|
Sandbox& operator=(const Sandbox&) = delete;
|
|
|
|
|
|
|
|
virtual ~Sandbox();
|
|
|
|
|
|
|
|
// Initializes a new sandboxing session.
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status Init();
|
2019-03-19 00:21:48 +08:00
|
|
|
|
2020-08-07 15:30:04 +08:00
|
|
|
ABSL_DEPRECATED("Use sapi::Sandbox::is_active() instead")
|
|
|
|
bool IsActive() const { return is_active(); }
|
|
|
|
// Returns whether the current sandboxing session is active.
|
|
|
|
bool is_active() const;
|
2019-03-19 00:21:48 +08:00
|
|
|
|
|
|
|
// Terminates the current sandboxing session (if it exists).
|
|
|
|
void Terminate(bool attempt_graceful_exit = true);
|
|
|
|
|
|
|
|
// Restarts the sandbox.
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status Restart(bool attempt_graceful_exit) {
|
2019-03-19 00:21:48 +08:00
|
|
|
Terminate(attempt_graceful_exit);
|
|
|
|
return Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Getters for common fields.
|
|
|
|
sandbox2::Comms* comms() const { return comms_; }
|
|
|
|
|
2020-08-07 15:30:04 +08:00
|
|
|
ABSL_DEPRECATED("Use sapi::Sandbox::rpc_channel() instead")
|
2019-03-19 00:21:48 +08:00
|
|
|
RPCChannel* GetRpcChannel() const { return rpc_channel_.get(); }
|
2020-08-07 15:30:04 +08:00
|
|
|
RPCChannel* rpc_channel() const { return rpc_channel_.get(); }
|
2019-03-19 00:21:48 +08:00
|
|
|
|
2020-08-07 15:30:04 +08:00
|
|
|
ABSL_DEPRECATED("Use sapi::Sandbox::pid() instead")
|
2019-03-19 00:21:48 +08:00
|
|
|
int GetPid() const { return pid_; }
|
2020-08-07 15:30:04 +08:00
|
|
|
int pid() const { return pid_; }
|
2019-03-19 00:21:48 +08:00
|
|
|
|
|
|
|
// Synchronizes the underlying memory for the pointer before the call.
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status SynchronizePtrBefore(v::Callable* ptr);
|
2019-03-19 00:21:48 +08:00
|
|
|
|
|
|
|
// Synchronizes the underlying memory for pointer after the call.
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status SynchronizePtrAfter(v::Callable* ptr) const;
|
2019-03-19 00:21:48 +08:00
|
|
|
|
|
|
|
// Makes a call to the sandboxee.
|
|
|
|
template <typename... Args>
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status Call(const std::string& func, v::Callable* ret, Args&&... args) {
|
2019-03-19 00:21:48 +08:00
|
|
|
static_assert(sizeof...(Args) <= FuncCall::kArgsMax,
|
|
|
|
"Too many arguments to sapi::Sandbox::Call()");
|
|
|
|
return Call(func, ret, {std::forward<Args>(args)...});
|
|
|
|
}
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status Call(const std::string& func, v::Callable* ret,
|
2019-08-23 23:08:23 +08:00
|
|
|
std::initializer_list<v::Callable*> args);
|
2019-03-19 00:21:48 +08:00
|
|
|
|
|
|
|
// Allocates memory in the sandboxee, automatic_free indicates whether the
|
|
|
|
// memory should be freed on the remote side when the 'var' goes out of scope.
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status Allocate(v::Var* var, bool automatic_free = false);
|
2019-03-19 00:21:48 +08:00
|
|
|
|
|
|
|
// Frees memory in the sandboxee.
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status Free(v::Var* var);
|
2019-03-19 00:21:48 +08:00
|
|
|
|
2020-08-07 15:30:04 +08:00
|
|
|
// Finds the address of a symbol in the sandboxee.
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status Symbol(const char* symname, void** addr);
|
2019-03-19 00:21:48 +08:00
|
|
|
|
|
|
|
// Transfers memory (both directions). Status is returned (memory transfer
|
|
|
|
// succeeded/failed).
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status TransferToSandboxee(v::Var* var);
|
|
|
|
absl::Status TransferFromSandboxee(v::Var* var);
|
2019-03-19 00:21:48 +08:00
|
|
|
|
2020-09-02 23:46:48 +08:00
|
|
|
absl::StatusOr<std::string> GetCString(const v::RemotePtr& str,
|
2020-09-18 22:44:34 +08:00
|
|
|
size_t max_length = 10ULL
|
|
|
|
<< 20 /* 10 MiB*/
|
2020-08-07 15:30:04 +08:00
|
|
|
);
|
2019-11-22 22:59:37 +08:00
|
|
|
|
2019-03-19 00:21:48 +08:00
|
|
|
// Waits until the sandbox terminated and returns the result.
|
|
|
|
const sandbox2::Result& AwaitResult();
|
|
|
|
const sandbox2::Result& result() const { return result_; }
|
|
|
|
|
2020-08-07 15:30:04 +08:00
|
|
|
absl::Status SetWallTimeLimit(absl::Duration limit) const;
|
|
|
|
ABSL_DEPRECATED(
|
|
|
|
"Use sapi::Sandbox::SetWallTimeLimit(absl::Duration) overload instead")
|
2020-02-28 01:23:44 +08:00
|
|
|
absl::Status SetWallTimeLimit(time_t limit) const;
|
2019-03-19 00:21:48 +08:00
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
// Gets the arguments passed to the sandboxee.
|
|
|
|
virtual void GetArgs(std::vector<std::string>* args) const {
|
|
|
|
args->push_back("--logtostderr=true");
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Returns the sandbox policy. Subclasses can modify the default policy
|
|
|
|
// builder, or return a completely new policy.
|
|
|
|
virtual std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
|
|
|
sandbox2::PolicyBuilder* builder);
|
|
|
|
|
|
|
|
// Path of the sandboxee:
|
2021-01-14 21:10:54 +08:00
|
|
|
// - relative to runfiles directory: ::sapi::GetDataDependencyFilePath()
|
2019-03-19 00:21:48 +08:00
|
|
|
// will be applied to it,
|
|
|
|
// - absolute: will be used as is.
|
|
|
|
virtual std::string GetLibPath() const { return ""; }
|
|
|
|
|
|
|
|
// Gets the environment varialbes passed to the sandboxee.
|
|
|
|
virtual void GetEnvs(std::vector<std::string>* envs) const {}
|
|
|
|
|
|
|
|
// Modifies the Executor object if needed.
|
|
|
|
virtual void ModifyExecutor(sandbox2::Executor* executor) {}
|
|
|
|
|
2020-09-28 22:38:07 +08:00
|
|
|
// Provides a custom notifier for sandboxee events. May return nullptr.
|
|
|
|
virtual std::unique_ptr<sandbox2::Notify> CreateNotifier() { return nullptr; }
|
|
|
|
|
2019-03-19 00:21:48 +08:00
|
|
|
// Exits the sandboxee.
|
|
|
|
void Exit() const;
|
|
|
|
|
|
|
|
// The client to the library forkserver.
|
|
|
|
std::unique_ptr<sandbox2::ForkClient> fork_client_;
|
|
|
|
std::unique_ptr<sandbox2::Executor> forkserver_executor_;
|
|
|
|
|
|
|
|
// The main sandbox2::Sandbox2 object.
|
|
|
|
std::unique_ptr<sandbox2::Sandbox2> s2_;
|
|
|
|
|
|
|
|
// Result of the most recent sandbox execution
|
|
|
|
sandbox2::Result result_;
|
|
|
|
|
|
|
|
// Comms with the sandboxee.
|
2020-08-07 15:30:04 +08:00
|
|
|
sandbox2::Comms* comms_ = nullptr;
|
2019-03-19 00:21:48 +08:00
|
|
|
// RPCChannel object.
|
|
|
|
std::unique_ptr<RPCChannel> rpc_channel_;
|
|
|
|
// The main pid of the sandboxee.
|
2020-08-07 15:30:04 +08:00
|
|
|
pid_t pid_ = 0;
|
2019-03-19 00:21:48 +08:00
|
|
|
|
|
|
|
// FileTOC with the embedded library, takes precedence over GetLibPath if
|
|
|
|
// present (not nullptr).
|
|
|
|
const FileToc* embed_lib_toc_;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace sapi
|
|
|
|
|
|
|
|
#endif // SANDBOXED_API_SANDBOX_H_
|