xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/ipc.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2019 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 // Implementation of the sandbox2::IPC class
16 
17 #include "sandboxed_api/sandbox2/ipc.h"
18 
19 #include <sys/socket.h>
20 #include <unistd.h>
21 
22 #include <memory>
23 #include <string>
24 #include <tuple>
25 #include <vector>
26 #include <thread>
27 
28 #include "absl/log/log.h"
29 #include "absl/strings/string_view.h"
30 #include "sandboxed_api/sandbox2/comms.h"
31 #include "sandboxed_api/sandbox2/logserver.h"
32 #include "sandboxed_api/sandbox2/logsink.h"
33 #include "sandboxed_api/util/raw_logging.h"
34 
35 namespace sandbox2 {
36 
SetUpServerSideComms(int fd)37 void IPC::SetUpServerSideComms(int fd) { comms_ = std::make_unique<Comms>(fd); }
38 
MapFd(int local_fd,int remote_fd)39 void IPC::MapFd(int local_fd, int remote_fd) {
40   VLOG(3) << "Will send: " << local_fd << ", to overwrite: " << remote_fd;
41   fd_map_.push_back(std::make_tuple(local_fd, remote_fd, ""));
42 }
43 
MapDupedFd(int local_fd,int remote_fd)44 void IPC::MapDupedFd(int local_fd, int remote_fd) {
45   const int dup_local_fd = dup(local_fd);
46   if (dup_local_fd == -1) {
47     PLOG(FATAL) << "dup(" << local_fd << ")";
48   }
49   VLOG(3) << "Will send: " << dup_local_fd << " (dup of " << local_fd
50           << "), to overwrite: " << remote_fd;
51   fd_map_.push_back(std::make_tuple(dup_local_fd, remote_fd, ""));
52 }
53 
ReceiveFd(int remote_fd)54 int IPC::ReceiveFd(int remote_fd) { return ReceiveFd(remote_fd, ""); }
55 
ReceiveFd(absl::string_view name)56 int IPC::ReceiveFd(absl::string_view name) { return ReceiveFd(-1, name); }
57 
ReceiveFd(int remote_fd,absl::string_view name)58 int IPC::ReceiveFd(int remote_fd, absl::string_view name) {
59   int sv[2];
60   if (socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) == -1) {
61     PLOG(FATAL) << "socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)";
62   }
63   VLOG(3) << "Created a socketpair (" << sv[0] << "/" << sv[1] << "), "
64           << "which will overwrite remote_fd: " << remote_fd;
65   fd_map_.push_back(std::make_tuple(sv[1], remote_fd, std::string(name)));
66   return sv[0];
67 }
68 
SendFdsOverComms()69 bool IPC::SendFdsOverComms() {
70   if (!(comms_->SendUint32(fd_map_.size()))) {
71     LOG(ERROR) << "Couldn't send IPC fd size";
72     return false;
73   }
74 
75   for (const auto& fd_tuple : fd_map_) {
76     if (!(comms_->SendInt32(std::get<1>(fd_tuple)))) {
77       LOG(ERROR) << "SendInt32: Couldn't send " << std::get<1>(fd_tuple);
78       return false;
79     }
80     if (!(comms_->SendFD(std::get<0>(fd_tuple)))) {
81       LOG(ERROR) << "SendFd: Couldn't send " << std::get<0>(fd_tuple);
82       return false;
83     }
84 
85     if (!(comms_->SendString(std::get<2>(fd_tuple)))) {
86       LOG(ERROR) << "SendString: Couldn't send " << std::get<2>(fd_tuple);
87       return false;
88     }
89     VLOG(3) << "IPC: local_fd: " << std::get<0>(fd_tuple)
90             << ", remote_fd: " << std::get<1>(fd_tuple) << " sent";
91   }
92 
93   return true;
94 }
95 
InternalCleanupFdMap()96 void IPC::InternalCleanupFdMap() {
97   for (const auto& fd_tuple : fd_map_) {
98     close(std::get<0>(fd_tuple));
99   }
100   fd_map_.clear();
101 }
102 
EnableLogServer()103 void IPC::EnableLogServer() {
104   int fd = ReceiveFd(LogSink::kLogFDName);
105   auto logger = [fd] {
106     LogServer log_server(fd);
107     log_server.Run();
108   };
109   std::thread log_thread{logger};
110   log_thread.detach();
111 }
112 
113 }  // namespace sandbox2
114