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