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