Skip to content

Commit ca62992

Browse files
Sandboxed API Teamcopybara-github
authored andcommitted
Automated rollback of commit 2c6a392.
PiperOrigin-RevId: 907728147 Change-Id: I12162497cb7fbeee2cdd98195f0aff1514db6ded
1 parent 9d1e59c commit ca62992

14 files changed

Lines changed: 159 additions & 232 deletions

sandboxed_api/sandbox2/BUILD

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,6 @@ cc_library(
357357
deps = [
358358
":buffer",
359359
":client",
360-
":client_cc_proto",
361360
":comms",
362361
":executor",
363362
":fork_client",
@@ -443,7 +442,6 @@ cc_library(
443442
copts = sapi_platform_copts(),
444443
deps = [
445444
":client",
446-
":client_cc_proto",
447445
":comms",
448446
":executor",
449447
":flags",
@@ -485,7 +483,6 @@ cc_library(
485483
deps = [
486484
":bpf_evaluator",
487485
":client",
488-
":client_cc_proto",
489486
":executor",
490487
":flags",
491488
":forkserver_cc_proto",
@@ -523,7 +520,6 @@ cc_library(
523520
copts = sapi_platform_copts(),
524521
deps = [
525522
":client",
526-
":client_cc_proto",
527523
":comms",
528524
":executor",
529525
":flags",
@@ -597,11 +593,6 @@ cc_library(
597593
],
598594
)
599595

600-
sapi_proto_library(
601-
name = "client_proto",
602-
srcs = ["client.proto"],
603-
)
604-
605596
# Should be used in sandboxee code instead of :sandbox2 if it uses just
606597
# sandbox2::Client::SandboxMeHere() and sandbox2::Comms
607598
cc_library(
@@ -612,7 +603,6 @@ cc_library(
612603
visibility = ["//visibility:public"],
613604
deps = [
614605
":buffer",
615-
":client_cc_proto",
616606
":comms",
617607
":logsink",
618608
":policy",

sandboxed_api/sandbox2/CMakeLists.txt

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,6 @@ target_link_libraries(sandbox2_monitor_base
438438
PUBLIC absl::status
439439
absl::statusor
440440
absl::synchronization
441-
sandbox2::client_proto
442441
sandbox2::comms
443442
sandbox2::executor
444443
sandbox2::fork_client
@@ -475,7 +474,6 @@ target_link_libraries(sandbox2_monitor_ptrace
475474
sapi::fileops
476475
sapi::status
477476
sandbox2::client
478-
sandbox2::client_proto
479477
sandbox2::comms
480478
sandbox2::result
481479
sandbox2::sanitizer
@@ -517,7 +515,6 @@ target_link_libraries(sandbox2_monitor_unotify
517515
sapi::base
518516
sandbox2::bpf_evaluator
519517
sandbox2::client
520-
sandbox2::client_proto
521518
sandbox2::flags
522519
sandbox2::forkserver_proto
523520
sandbox2::seccomp_unotify
@@ -572,20 +569,6 @@ target_link_libraries(sandbox2_policybuilder
572569
sandbox2::policy
573570
)
574571

575-
# sandboxed_api/sandbox2:client_proto
576-
sapi_protobuf_generate_cpp(_sandbox2_client_pb_h _sandbox2_client_pb_cc
577-
client.proto
578-
)
579-
add_library(sandbox2_client_proto ${SAPI_LIB_TYPE}
580-
${_sandbox2_client_pb_cc}
581-
${_sandbox2_client_pb_h}
582-
)
583-
add_library(sandbox2::client_proto ALIAS sandbox2_client_proto)
584-
target_link_libraries(sandbox2_client_proto PRIVATE
585-
protobuf::libprotobuf
586-
sapi::base
587-
)
588-
589572
# sandboxed_api/sandbox2:client
590573
add_library(sandbox2_client ${SAPI_LIB_TYPE}
591574
client.cc
@@ -608,7 +591,6 @@ target_link_libraries(sandbox2_client
608591
sapi::status
609592
PUBLIC absl::flat_hash_map
610593
absl::status
611-
sandbox2::client_proto
612594
sandbox2::comms
613595
sandbox2::logsink
614596
sandbox2::network_proxy_client

sandboxed_api/sandbox2/client.cc

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
#include "absl/strings/string_view.h"
5151
#include "sandboxed_api/config.h"
5252
#include "sandboxed_api/sandbox2/buffer.h"
53-
#include "sandboxed_api/sandbox2/client.pb.h"
5453
#include "sandboxed_api/sandbox2/comms.h"
5554
#include "sandboxed_api/sandbox2/logsink.h"
5655
#include "sandboxed_api/sandbox2/network_proxy/client.h"
@@ -190,7 +189,6 @@ std::string Client::GetFdMapEnvVar() const {
190189
}
191190

192191
void Client::PrepareEnvironment(int* preserved_fd) {
193-
ReceiveClientConfig();
194192
SetUpIPC(preserved_fd);
195193
SetUpCwd();
196194
}
@@ -206,19 +204,41 @@ void Client::SandboxMeHere() {
206204
}
207205

208206
void Client::SetUpCwd() {
209-
// Receive the user-supplied current working directory and change into it.
210-
if (client_config_.cwd().empty()) {
211-
return;
207+
{
208+
// Get the current working directory to check if we are in a mount
209+
// namespace.
210+
// Note: glibc 2.27 no longer returns a relative path in that case, but
211+
// fails with ENOENT and returns a nullptr instead. The code still
212+
// needs to run on lower version for the time being.
213+
char cwd_buf[PATH_MAX + 1] = {0};
214+
char* cwd = getcwd(cwd_buf, ABSL_ARRAYSIZE(cwd_buf));
215+
SAPI_RAW_PCHECK(cwd != nullptr || errno == ENOENT,
216+
"no current working directory");
217+
218+
// Outside of the mount namespace, the path is of the form
219+
// '(unreachable)/...'. Only check for the slash, since Linux might make up
220+
// other prefixes in the future.
221+
if (errno == ENOENT || cwd_buf[0] != '/') {
222+
SAPI_RAW_VLOG(1, "chdir into mount namespace, cwd was '%s'", cwd_buf);
223+
// If we are in a mount namespace but fail to chdir, then it can lead to a
224+
// sandbox escape -- we need to fail with FATAL if the chdir fails.
225+
SAPI_RAW_PCHECK(chdir("/") != -1, "corrective chdir");
226+
}
212227
}
213-
std::string cwd(client_config_.cwd());
214-
// This chdir can fail without a sandbox escape. It will probably not have
215-
// the intended behavior though.
216-
if (chdir(cwd.c_str()) == -1 && SAPI_RAW_VLOG_IS_ON(1)) {
217-
SAPI_RAW_PLOG(
218-
INFO,
219-
"chdir(%s) failed, falling back to previous cwd or / (with "
220-
"namespaces). Use Executor::SetCwd() to set a working directory",
221-
cwd.c_str());
228+
229+
// Receive the user-supplied current working directory and change into it.
230+
std::string cwd;
231+
SAPI_RAW_CHECK(comms_->RecvString(&cwd), "receiving working directory");
232+
if (!cwd.empty()) {
233+
// On the other hand this chdir can fail without a sandbox escape. It will
234+
// probably not have the intended behavior though.
235+
if (chdir(cwd.c_str()) == -1 && SAPI_RAW_VLOG_IS_ON(1)) {
236+
SAPI_RAW_PLOG(
237+
INFO,
238+
"chdir(%s) failed, falling back to previous cwd or / (with "
239+
"namespaces). Use Executor::SetCwd() to set a working directory",
240+
cwd.c_str());
241+
}
222242
}
223243
}
224244

@@ -294,12 +314,9 @@ void Client::SetUpIPC(int* preserved_fd) {
294314
}
295315

296316
void Client::ReceivePolicy() {
297-
SAPI_RAW_CHECK(comms_->RecvBytes(&policy_), "receive bytes");
298-
}
299-
300-
void Client::ReceiveClientConfig() {
301-
SAPI_RAW_CHECK(comms_->RecvProtoBuf(&client_config_),
302-
"receive client config");
317+
std::vector<uint8_t> bytes;
318+
SAPI_RAW_CHECK(comms_->RecvBytes(&bytes), "receive bytes");
319+
policy_ = std::move(bytes);
303320
}
304321

305322
void Client::ApplyPolicyAndBecomeTracee() {
@@ -308,13 +325,18 @@ void Client::ApplyPolicyAndBecomeTracee() {
308325
// this function does nothing.
309326
sanitizer::WaitForSanitizer();
310327

311-
pid_t ptracer_tid = client_config_.ptracer_tid();
312-
if (ptracer_tid > 0) {
313-
SAPI_RAW_CHECK(prctl(PR_SET_DUMPABLE, 1) == 0,
314-
"setting PR_SET_DUMPABLE flag");
315-
if (prctl(PR_SET_PTRACER, ptracer_tid) == -1) {
316-
SAPI_RAW_VLOG(1, "No YAMA on this system. Continuing");
317-
}
328+
// Creds can be received w/o synchronization, once the connection is
329+
// established.
330+
pid_t cred_pid;
331+
uid_t cred_uid ABSL_ATTRIBUTE_UNUSED;
332+
gid_t cred_gid ABSL_ATTRIBUTE_UNUSED;
333+
SAPI_RAW_CHECK(comms_->GetPeerCreds(&cred_pid, &cred_uid, &cred_gid),
334+
"receiving credentials");
335+
336+
SAPI_RAW_CHECK(prctl(PR_SET_DUMPABLE, 1) == 0,
337+
"setting PR_SET_DUMPABLE flag");
338+
if (prctl(PR_SET_PTRACER, cred_pid) == -1) {
339+
SAPI_RAW_VLOG(1, "No YAMA on this system. Continuing");
318340
}
319341

320342
SAPI_RAW_CHECK(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == 0,
@@ -342,9 +364,7 @@ void Client::ApplyPolicyAndBecomeTracee() {
342364
uint32_t message; // wait for confirmation
343365
SAPI_RAW_CHECK(comms_->RecvUint32(&message),
344366
"receving confirmation from executor");
345-
SAPI_RAW_CHECK(message == kSandbox2MonitorReady,
346-
"invalid confirmation from executor");
347-
bool allow_speculation = client_config_.seccomp_allow_speculation();
367+
bool allow_speculation = message & kAllowSpeculationBit;
348368
if (!allow_speculation) {
349369
if constexpr (sapi::host_cpu::IsX8664() || sapi::host_cpu::IsArm64()) {
350370
SAPI_RAW_PCHECK(prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS,
@@ -361,13 +381,12 @@ void Client::ApplyPolicyAndBecomeTracee() {
361381
}
362382
uint32_t seccomp_extra_flags =
363383
allow_speculation ? SECCOMP_FILTER_FLAG_SPEC_ALLOW : 0;
364-
if (client_config_.monitor_type() == ClientConfig::CLIENT_MONITOR_UNOTIFY) {
384+
uint32_t monitor_type = message & kMonitorTypeMask;
385+
if (monitor_type == kSandbox2ClientUnotify) {
365386
InitSeccompUnotify(prog, comms_, seccomp_extra_flags);
366387
} else {
367-
SAPI_RAW_CHECK(
368-
client_config_.monitor_type() == ClientConfig::CLIENT_MONITOR_PTRACE,
369-
absl::StrCat("invalid monitor type: ", client_config_.monitor_type())
370-
.c_str());
388+
SAPI_RAW_CHECK(monitor_type == kSandbox2ClientPtrace,
389+
"invalid confirmation from executor");
371390
InitSeccompRegular(prog, seccomp_extra_flags);
372391
}
373392
}

sandboxed_api/sandbox2/client.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "absl/status/status.h"
2828
#include "absl/status/statusor.h"
2929
#include "sandboxed_api/sandbox2/buffer.h"
30-
#include "sandboxed_api/sandbox2/client.pb.h"
3130
#include "sandboxed_api/sandbox2/comms.h"
3231
#include "sandboxed_api/sandbox2/logsink.h"
3332
#include "sandboxed_api/sandbox2/network_proxy/client.h"
@@ -39,8 +38,12 @@ class Client {
3938
// Client is ready to be sandboxed.
4039
static constexpr uint32_t kClient2SandboxReady = 0x0A0B0C01;
4140

42-
// Sandbox is ready to monitor the sandboxee.
43-
static constexpr uint32_t kSandbox2MonitorReady = 0x0A0B0D01;
41+
// Sandbox is ready to monitor the sandboxee. Used with PtraceMonitor.
42+
static constexpr uint32_t kSandbox2ClientPtrace = 0x0A0B0C02;
43+
44+
// Sandboxee should setup seccomp_unotify and send back the FD. Used with
45+
// UnotifyMonitor.
46+
static constexpr uint32_t kSandbox2ClientUnotify = 0x0A0B0C03;
4447

4548
// Sandboxee can proceed after seccomp_unotify setup as limits have been
4649
// applied by the monitor.
@@ -94,9 +97,6 @@ class Client {
9497

9598
friend class ForkServer;
9699

97-
// Client configuration received from the monitor.
98-
ClientConfig client_config_;
99-
100100
// Seccomp-bpf policy received from the monitor.
101101
std::vector<uint8_t> policy_;
102102

@@ -130,9 +130,6 @@ class Client {
130130
// Receives seccomp-bpf policy from the monitor.
131131
void ReceivePolicy();
132132

133-
// Receives client configuration from the monitor.
134-
void ReceiveClientConfig();
135-
136133
// Applies sandbox-bpf policy, have limits applied on us, and become ptrace'd.
137134
void ApplyPolicyAndBecomeTracee();
138135

sandboxed_api/sandbox2/client.proto

Lines changed: 0 additions & 36 deletions
This file was deleted.

sandboxed_api/sandbox2/monitor_base.cc

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,14 @@ void MonitorBase::Launch() {
220220
SetExitStatusCode(Result::SETUP_ERROR, Result::FAILED_NOTIFY);
221221
return;
222222
}
223-
if (!InitSendClientConfig()) {
224-
SetExitStatusCode(Result::SETUP_ERROR, Result::FAILED_CLIENT_CONFIG);
225-
return;
226-
}
227223
if (!InitSendIPC()) {
228224
SetExitStatusCode(Result::SETUP_ERROR, Result::FAILED_IPC);
229225
return;
230226
}
227+
if (!InitSendCwd()) {
228+
SetExitStatusCode(Result::SETUP_ERROR, Result::FAILED_CWD);
229+
return;
230+
}
231231
if (!InitSendPolicy()) {
232232
SetExitStatusCode(Result::SETUP_ERROR, Result::FAILED_POLICY);
233233
return;
@@ -267,8 +267,12 @@ absl::Status MonitorBase::SendPolicy(const std::vector<sock_filter>& policy) {
267267
return absl::OkStatus();
268268
}
269269

270-
bool MonitorBase::SendMonitorReadyMessage() {
271-
return comms_->SendUint32(Client::kSandbox2MonitorReady);
270+
bool MonitorBase::SendMonitorReadyMessageAndFlags(uint32_t monitor_type) {
271+
uint32_t message = monitor_type;
272+
if (policy_->allow_speculation_) {
273+
message |= Client::kAllowSpeculationBit;
274+
}
275+
return comms_->SendUint32(message);
272276
}
273277

274278
bool MonitorBase::InitSendPolicy() {
@@ -283,6 +287,15 @@ bool MonitorBase::InitSendPolicy() {
283287
return true;
284288
}
285289

290+
bool MonitorBase::InitSendCwd() {
291+
if (!comms_->SendString(executor_->cwd_)) {
292+
PLOG(ERROR) << "Couldn't send cwd";
293+
return false;
294+
}
295+
296+
return true;
297+
}
298+
286299
bool MonitorBase::InitApplyLimit(pid_t pid, int resource,
287300
const rlimit64& rlim) const {
288301
using RlimitResource = __rlimit_resource;
@@ -322,21 +335,6 @@ bool MonitorBase::InitApplyLimits() {
322335
InitApplyLimit(process_.main_pid, RLIMIT_CORE, limits->rlimit_core());
323336
}
324337

325-
ClientConfig MonitorBase::CreateClientConfig() const {
326-
ClientConfig client_config;
327-
client_config.set_cwd(executor_->cwd_);
328-
client_config.set_seccomp_allow_speculation(policy_->allow_speculation_);
329-
return client_config;
330-
}
331-
332-
bool MonitorBase::InitSendClientConfig() {
333-
if (!comms_->SendProtoBuf(CreateClientConfig())) {
334-
LOG(ERROR) << "Couldn't send client config";
335-
return false;
336-
}
337-
return true;
338-
}
339-
340338
bool MonitorBase::InitSendIPC() { return ipc_->SendFdsOverComms(); }
341339

342340
bool MonitorBase::WaitForSandboxReady() {

0 commit comments

Comments
 (0)