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