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 <sys/socket.h>
18 #include <sys/un.h>
19
20 #include <iostream>
21
22 #include <absl/status/status.h>
23 #include <absl/status/statusor.h>
24 #include <absl/strings/numbers.h>
25
26 #include "proxy_common.h"
27
28 namespace cuttlefish::process_sandboxer {
29 namespace {
30
31 template <typename T>
UnwrapStatusOr(absl::StatusOr<T> status_or)32 T UnwrapStatusOr(absl::StatusOr<T> status_or) {
33 if (!status_or.ok()) {
34 std::cerr << status_or.status().ToString() << '\n';
35 abort();
36 }
37 return std::move(*status_or);
38 }
39
40 template <typename T>
AtoiOr(std::string_view str)41 absl::StatusOr<T> AtoiOr(std::string_view str) {
42 T out;
43 if (!absl::SimpleAtoi(str, &out)) {
44 return absl::InvalidArgumentError("Not an integer");
45 }
46 return out;
47 }
48
OpenSandboxManagerSocket()49 absl::StatusOr<int> OpenSandboxManagerSocket() {
50 int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
51 if (sock < 0) {
52 return absl::ErrnoToStatus(errno, "`socket` failed");
53 }
54
55 sockaddr_un addr = sockaddr_un{
56 .sun_family = AF_UNIX,
57 };
58 size_t size = std::min(sizeof(addr.sun_path), kManagerSocketPath.size());
59 strncpy(addr.sun_path, kManagerSocketPath.data(), size);
60
61 if (connect(sock, (sockaddr*)&addr, sizeof(addr)) < 0) {
62 return absl::ErrnoToStatus(errno, "`connect` failed");
63 }
64
65 return sock;
66 }
67
ProcessSandboxerMain()68 int ProcessSandboxerMain() {
69 int sock = UnwrapStatusOr(OpenSandboxManagerSocket());
70 UnwrapStatusOr(SendStringMsg(sock, kHandshakeBegin));
71 UnwrapStatusOr(SendStringMsg(sock, std::to_string(sock)));
72 Message pingback = UnwrapStatusOr(Message::RecvFrom(sock));
73 UnwrapStatusOr(SendStringMsg(sock, pingback.Data()));
74
75 // If signals other than SIGKILL become relevant, this should `poll` to check
76 // both `sock` and a `signalfd`.
77 while (true) {
78 Message command = UnwrapStatusOr(Message::RecvFrom(sock));
79 if (command.Data() == "exit") {
80 Message message = UnwrapStatusOr(Message::RecvFrom(sock));
81 return UnwrapStatusOr(AtoiOr<int>(message.Data()));
82 }
83 std::cerr << "Unexpected message: '" << command.Data() << "'\n";
84 return 1;
85 }
86
87 return 0;
88 }
89
90 } // namespace
91 } // namespace cuttlefish::process_sandboxer
92
main()93 int main() { return cuttlefish::process_sandboxer::ProcessSandboxerMain(); }
94