• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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