1 // Copyright 2020 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 #include "sandboxed_api/sandbox2/fork_client.h"
16
17 #include <sys/types.h>
18
19 #include <cstdint>
20
21 #include "absl/log/check.h"
22 #include "absl/log/log.h"
23 #include "absl/synchronization/mutex.h"
24 #include "sandboxed_api/sandbox2/comms.h"
25 #include "sandboxed_api/sandbox2/forkserver.pb.h"
26 #include "sandboxed_api/util/fileops.h"
27
28 namespace sandbox2 {
29
30 using ::sapi::file_util::fileops::FDCloser;
31
ForkClient(pid_t pid,Comms * comms,bool is_global)32 ForkClient::ForkClient(pid_t pid, Comms* comms, bool is_global)
33 : pid_(pid), comms_(comms), is_global_(is_global) {
34 }
35
~ForkClient()36 ForkClient::~ForkClient() {
37 }
38
SendRequest(const ForkRequest & request,int exec_fd,int comms_fd)39 SandboxeeProcess ForkClient::SendRequest(const ForkRequest& request,
40 int exec_fd, int comms_fd) {
41 SandboxeeProcess process;
42 // Acquire the channel ownership for this request (transaction).
43 absl::MutexLock l(&comms_mutex_);
44
45 if (!comms_->SendProtoBuf(request)) {
46 LOG(ERROR) << "Sending PB to the ForkServer failed";
47 return process;
48 }
49 CHECK(comms_fd != -1) << "comms_fd was not properly set up";
50 if (!comms_->SendFD(comms_fd)) {
51 LOG(ERROR) << "Sending Comms FD (" << comms_fd
52 << ") to the ForkServer failed";
53 return process;
54 }
55 if (request.mode() == FORKSERVER_FORK_EXECVE ||
56 request.mode() == FORKSERVER_FORK_EXECVE_SANDBOX) {
57 CHECK(exec_fd != -1) << "exec_fd cannot be -1 in execve mode";
58 if (!comms_->SendFD(exec_fd)) {
59 LOG(ERROR) << "Sending Exec FD (" << exec_fd
60 << ") to the ForkServer failed";
61 return process;
62 }
63 }
64
65 int32_t pid;
66 // Receive init process ID.
67 if (!comms_->RecvInt32(&pid)) {
68 LOG(ERROR) << "Receiving init PID from the ForkServer failed";
69 return process;
70 }
71 process.init_pid = static_cast<pid_t>(pid);
72
73 // Receive sandboxee process ID.
74 if (!comms_->RecvInt32(&pid)) {
75 LOG(ERROR) << "Receiving sandboxee PID from the ForkServer failed";
76 return process;
77 }
78 process.main_pid = static_cast<pid_t>(pid);
79 if (request.monitor_type() == FORKSERVER_MONITOR_UNOTIFY) {
80 int fd = -1;
81 if (!comms_->RecvFD(&fd)) {
82 LOG(ERROR) << "Receiving status fd from the ForkServer failed";
83 return process;
84 }
85 process.status_fd = FDCloser(fd);
86 }
87 return process;
88 }
89
90 } // namespace sandbox2
91