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 "host/commands/process_sandboxer/policies.h"
18
19 #include <memory>
20 #include <ostream>
21 #include <string_view>
22
23 #include <absl/container/flat_hash_map.h>
24 #include <absl/log/log.h>
25 #include <absl/status/status.h>
26 #include <sandboxed_api/sandbox2/policybuilder.h>
27
28 #include "host/commands/process_sandboxer/filesystem.h"
29 #include "host/commands/process_sandboxer/proxy_common.h"
30
31 namespace cuttlefish::process_sandboxer {
32
EnsureOutputDirectoriesExist()33 absl::Status HostInfo::EnsureOutputDirectoriesExist() {
34 if (!CreateDirectoryRecursively(assembly_dir, 0700)) {
35 return absl::ErrnoToStatus(errno, "Failed to create " + assembly_dir);
36 }
37 if (!CreateDirectoryRecursively(environments_dir, 0700)) {
38 return absl::ErrnoToStatus(errno, "Failed to create " + environments_dir);
39 }
40 if (!CreateDirectoryRecursively(environments_uds_dir, 0700)) {
41 return absl::ErrnoToStatus(errno,
42 "Failed to create " + environments_uds_dir);
43 }
44 if (!CreateDirectoryRecursively(instance_uds_dir, 0700)) {
45 return absl::ErrnoToStatus(errno, "Failed to create " + instance_uds_dir);
46 }
47 if (!CreateDirectoryRecursively(log_dir, 0700)) {
48 return absl::ErrnoToStatus(errno, "Failed to create " + log_dir);
49 }
50 if (!CreateDirectoryRecursively(runtime_dir, 0700)) {
51 return absl::ErrnoToStatus(errno, "Failed to create " + runtime_dir);
52 }
53 if (!CreateDirectoryRecursively(vsock_device_dir, 0700)) {
54 return absl::ErrnoToStatus(errno, "Failed to create " + runtime_dir);
55 }
56 return absl::OkStatus();
57 }
58
HostToolExe(std::string_view exe) const59 std::string HostInfo::HostToolExe(std::string_view exe) const {
60 return JoinPath(host_artifacts_path, "bin", exe);
61 }
62
operator <<(std::ostream & out,const HostInfo & host)63 std::ostream& operator<<(std::ostream& out, const HostInfo& host) {
64 out << "HostInfo {\n";
65 out << "\tassembly_dir: \"" << host.assembly_dir << "\"\n";
66 out << "\tcuttlefish_config_path: \"" << host.cuttlefish_config_path
67 << "\"\n";
68 out << "\tearly_tmp_dir: \"" << host.early_tmp_dir << "\"\n";
69 out << "\tenvironments_dir: \"" << host.environments_dir << "\"\n";
70 out << "\tenvironments_uds_dir: " << host.environments_uds_dir << "\"\n";
71 out << "\tguest_image_path: " << host.guest_image_path << "\t\n";
72 out << "\thost_artifacts_path: \"" << host.host_artifacts_path << "\"\n";
73 out << "\tinstance_uds_dir: " << host.instance_uds_dir << "\"\n";
74 out << "\tlog_dir: " << host.log_dir << "\"\n";
75 out << "\truntime_dir: " << host.runtime_dir << "\"\n";
76 return out << "}";
77 }
78
PolicyForExecutable(const HostInfo & host,std::string_view server_socket_outside_path,std::string_view executable)79 std::unique_ptr<sandbox2::Policy> PolicyForExecutable(
80 const HostInfo& host, std::string_view server_socket_outside_path,
81 std::string_view executable) {
82 using Builder = sandbox2::PolicyBuilder(const HostInfo&);
83 absl::flat_hash_map<std::string, Builder*> builders;
84
85 builders[host.HostToolExe("adb_connector")] = AdbConnectorPolicy;
86 builders[host.HostToolExe("assemble_cvd")] = AssembleCvdPolicy;
87 builders[host.HostToolExe("avbtool")] = AvbToolPolicy;
88 builders[host.HostToolExe("casimir")] = CasimirPolicy;
89 builders[host.HostToolExe("casimir_control_server")] =
90 CasimirControlServerPolicy;
91 builders[host.HostToolExe("control_env_proxy_server")] =
92 ControlEnvProxyServerPolicy;
93 builders[host.HostToolExe("cvd_internal_start")] = CvdInternalStartPolicy;
94 builders[host.HostToolExe("echo_server")] = EchoServerPolicy;
95 builders[host.HostToolExe("gnss_grpc_proxy")] = GnssGrpcProxyPolicy;
96 builders[host.HostToolExe("kernel_log_monitor")] = KernelLogMonitorPolicy;
97 builders[host.HostToolExe("log_tee")] = LogTeePolicy;
98 builders[host.HostToolExe("logcat_receiver")] = LogcatReceiverPolicy;
99 builders[host.HostToolExe("metrics")] = MetricsPolicy;
100 builders[host.HostToolExe("mkenvimage_slim")] = MkEnvImgSlimPolicy;
101 builders[host.HostToolExe("modem_simulator")] = ModemSimulatorPolicy;
102 builders[host.HostToolExe("netsimd")] = NetsimdPolicy;
103 builders[host.HostToolExe("newfs_msdos")] = NewFsMsDosPolicy;
104 builders[host.HostToolExe("openwrt_control_server")] =
105 OpenWrtControlServerPolicy;
106 builders[host.HostToolExe("operator_proxy")] = OperatorProxyPolicy;
107 builders[host.HostToolExe("process_restarter")] = ProcessRestarterPolicy;
108 builders[host.HostToolExe("run_cvd")] = RunCvdPolicy;
109 builders[host.HostToolExe("screen_recording_server")] =
110 ScreenRecordingServerPolicy;
111 builders[host.HostToolExe("secure_env")] = SecureEnvPolicy;
112 builders[host.HostToolExe("simg2img")] = Simg2ImgPolicy;
113 builders[host.HostToolExe("socket_vsock_proxy")] = SocketVsockProxyPolicy;
114 builders[host.HostToolExe("tcp_connector")] = TcpConnectorPolicy;
115 builders[host.HostToolExe("tombstone_receiver")] = TombstoneReceiverPolicy;
116 builders[host.HostToolExe("vhost_device_vsock")] = VhostDeviceVsockPolicy;
117 builders[host.HostToolExe("webRTC")] = WebRtcPolicy;
118 builders[host.HostToolExe("webrtc_operator")] = WebRtcOperatorPolicy;
119 builders[host.HostToolExe("wmediumd")] = WmediumdPolicy;
120 builders[host.HostToolExe("wmediumd_gen_config")] = WmediumdGenConfigPolicy;
121
122 std::set<std::string> no_policy_set = NoPolicy(host);
123 for (const auto& [exe, policy_builder] : builders) {
124 if (no_policy_set.count(exe)) {
125 LOG(FATAL) << "Overlap in policy map and no-policy set: '" << exe << "'";
126 }
127 }
128
129 if (auto it = builders.find(executable); it != builders.end()) {
130 // TODO(schuffelen): Only share this with executables known to launch others
131 auto r1 = (it->second)(host);
132 r1.AddFileAt(server_socket_outside_path, kManagerSocketPath, false);
133 auto r2 = r1.TryBuild();
134 if (!r2.ok()) {
135 LOG(INFO) << r2.status().ToString();
136 abort();
137 }
138 return std::move(*r2);
139 } else if (no_policy_set.count(std::string(executable))) {
140 return nullptr;
141 } else {
142 LOG(FATAL) << "Unknown executable '" << executable << "'";
143 }
144 }
145
146 } // namespace cuttlefish::process_sandboxer
147