• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdlib.h>
18 #include <sys/socket.h>
19 #include <sys/un.h>
20 
21 #include <algorithm>
22 #include <cerrno>
23 #include <cstddef>
24 #include <cstring>
25 #include <iostream>
26 #include <string>
27 #include <string_view>
28 
29 #include <absl/status/status.h>
30 #include <absl/status/statusor.h>
31 #include <absl/strings/numbers.h>
32 
33 #include "host/commands/process_sandboxer/proxy_common.h"
34 
35 namespace cuttlefish::process_sandboxer {
36 namespace {
37 
38 template <typename T>
UnwrapStatusOr(absl::StatusOr<T> status_or)39 T UnwrapStatusOr(absl::StatusOr<T> status_or) {
40   if (!status_or.ok()) {
41     std::cerr << status_or.status().ToString() << '\n';
42     abort();
43   }
44   return std::move(*status_or);
45 }
46 
47 template <typename T>
AtoiOr(std::string_view str)48 absl::StatusOr<T> AtoiOr(std::string_view str) {
49   T out;
50   if (!absl::SimpleAtoi(str, &out)) {
51     return absl::InvalidArgumentError("Not an integer");
52   }
53   return out;
54 }
55 
OpenSandboxManagerSocket()56 absl::StatusOr<int> OpenSandboxManagerSocket() {
57   int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
58   if (sock < 0) {
59     return absl::ErrnoToStatus(errno, "`socket` failed");
60   }
61 
62   sockaddr_un addr = sockaddr_un{
63       .sun_family = AF_UNIX,
64   };
65   size_t size = std::min(sizeof(addr.sun_path), kManagerSocketPath.size());
66   strncpy(addr.sun_path, kManagerSocketPath.data(), size);
67 
68   if (connect(sock, (sockaddr*)&addr, sizeof(addr)) < 0) {
69     return absl::ErrnoToStatus(errno, "`connect` failed");
70   }
71 
72   return sock;
73 }
74 
ProcessSandboxerMain()75 int ProcessSandboxerMain() {
76   int sock = UnwrapStatusOr(OpenSandboxManagerSocket());
77   UnwrapStatusOr(SendStringMsg(sock, kHandshakeBegin));
78   UnwrapStatusOr(SendStringMsg(sock, std::to_string(sock)));
79   Message pingback = UnwrapStatusOr(Message::RecvFrom(sock));
80   UnwrapStatusOr(SendStringMsg(sock, pingback.Data()));
81 
82   // If signals other than SIGKILL become relevant, this should `poll` to check
83   // both `sock` and a `signalfd`.
84   while (true) {
85     Message command = UnwrapStatusOr(Message::RecvFrom(sock));
86     if (command.Data() == "exit") {
87       Message message = UnwrapStatusOr(Message::RecvFrom(sock));
88       return UnwrapStatusOr(AtoiOr<int>(message.Data()));
89     }
90     std::cerr << "Unexpected message: '" << command.Data() << "'\n";
91     return 1;
92   }
93 
94   return 0;
95 }
96 
97 }  // namespace
98 }  // namespace cuttlefish::process_sandboxer
99 
main()100 int main() { return cuttlefish::process_sandboxer::ProcessSandboxerMain(); }
101