• 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 #include "host/commands/process_sandboxer/policies.h"
17 
18 #include <linux/bpf_common.h>
19 #include <linux/filter.h>
20 #include <linux/prctl.h>
21 #include <sys/mman.h>
22 #include <sys/socket.h>
23 #include <sys/stat.h>
24 #include <syscall.h>
25 #include <unistd.h>
26 
27 #include <cstdint>
28 #include <string>
29 #include <vector>
30 
31 #include <absl/strings/str_cat.h>
32 #include <absl/strings/str_replace.h>
33 #include <sandboxed_api/sandbox2/policybuilder.h>
34 #include <sandboxed_api/sandbox2/util/bpf_helper.h>
35 #include <sandboxed_api/util/path.h>
36 
37 namespace cuttlefish::process_sandboxer {
38 
39 using sapi::file::JoinPath;
40 
RunCvdPolicy(const HostInfo & host)41 sandbox2::PolicyBuilder RunCvdPolicy(const HostInfo& host) {
42   std::string sandboxer_proxy = host.HostToolExe("sandboxer_proxy");
43   return BaselinePolicy(host, host.HostToolExe("run_cvd"))
44       .AddDirectory(host.runtime_dir, /* is_ro= */ false)
45       .AddDirectory(
46           JoinPath(host.host_artifacts_path, "etc", "default_input_devices"))
47       .AddFile(host.cuttlefish_config_path)
48       .AddFile("/dev/null", /* is_ro= */ false)
49       .AddFileAt(sandboxer_proxy, host.HostToolExe("adb_connector"))
50       .AddFileAt(sandboxer_proxy, host.HostToolExe("casimir_control_server"))
51       .AddFileAt(sandboxer_proxy, host.HostToolExe("cf_vhost_user_input"))
52       .AddFileAt(sandboxer_proxy, host.HostToolExe("control_env_proxy_server"))
53       .AddFileAt(sandboxer_proxy, host.HostToolExe("crosvm"))
54       .AddFileAt(sandboxer_proxy, host.HostToolExe("echo_server"))
55       .AddFileAt(sandboxer_proxy, host.HostToolExe("gnss_grpc_proxy"))
56       .AddFileAt(sandboxer_proxy, host.HostToolExe("kernel_log_monitor"))
57       .AddFileAt(sandboxer_proxy, host.HostToolExe("log_tee"))
58       .AddFileAt(sandboxer_proxy, host.HostToolExe("logcat_receiver"))
59       .AddFileAt(sandboxer_proxy, host.HostToolExe("metrics"))
60       .AddFileAt(sandboxer_proxy, host.HostToolExe("modem_simulator"))
61       .AddFileAt(sandboxer_proxy, host.HostToolExe("netsimd"))
62       .AddFileAt(sandboxer_proxy, host.HostToolExe("openwrt_control_server"))
63       .AddFileAt(sandboxer_proxy, host.HostToolExe("operator_proxy"))
64       .AddFileAt(sandboxer_proxy, host.HostToolExe("process_restarter"))
65       .AddFileAt(sandboxer_proxy, host.HostToolExe("screen_recording_server"))
66       .AddFileAt(sandboxer_proxy, host.HostToolExe("secure_env"))
67       .AddFileAt(sandboxer_proxy, host.HostToolExe("socket_vsock_proxy"))
68       .AddFileAt(sandboxer_proxy, host.HostToolExe("tcp_connector"))
69       .AddFileAt(sandboxer_proxy, host.HostToolExe("tombstone_receiver"))
70       .AddFileAt(sandboxer_proxy, host.HostToolExe("webRTC"))
71       .AddFileAt(sandboxer_proxy, host.HostToolExe("webrtc_operator"))
72       .AddFileAt(sandboxer_proxy, host.HostToolExe("wmediumd"))
73       .AddFileAt(sandboxer_proxy, host.HostToolExe("wmediumd_gen_config"))
74       .AddDirectory(host.environments_dir)
75       .AddDirectory(host.EnvironmentsUdsDir(), /* is_ro= */ false)
76       .AddDirectory(host.InstanceUdsDir(), /* is_ro= */ false)
77       .AddDirectory(host.VsockDeviceDir(), /* is_ro= */ false)
78       // The UID inside the sandbox2 namespaces is always 1000.
79       .AddDirectoryAt(host.EnvironmentsUdsDir(),
80                       absl::StrReplaceAll(
81                           host.EnvironmentsUdsDir(),
82                           {{absl::StrCat("cf_env_", getuid()), "cf_env_1000"}}),
83                       false)
84       .AddDirectoryAt(host.InstanceUdsDir(),
85                       absl::StrReplaceAll(
86                           host.InstanceUdsDir(),
87                           {{absl::StrCat("cf_avd_", getuid()), "cf_avd_1000"}}),
88                       false)
89       .AddPolicyOnSyscall(__NR_madvise,
90                           {ARG_32(2), JEQ32(MADV_DONTNEED, ALLOW)})
91       .AddPolicyOnSyscall(
92           __NR_mknodat,
93           [](bpf_labels& labels) -> std::vector<sock_filter> {
94             return {
95                 ARG_32(2),
96                 // a <- a & S_IFMT // Mask to only the file type bits
97                 BPF_STMT(BPF_ALU + BPF_AND + BPF_K,
98                          static_cast<uint32_t>(S_IFMT)),
99                 // Only allow `mkfifo`
100                 JNE32(S_IFIFO, JUMP(&labels, cf_mknodat_end)),
101                 ARG_32(3),
102                 JEQ32(0, ALLOW),
103                 LABEL(&labels, cf_mknodat_end),
104             };
105           })
106       .AddPolicyOnSyscall(__NR_prctl,
107                           {ARG_32(0), JEQ32(PR_SET_PDEATHSIG, ALLOW),
108                            JEQ32(PR_SET_CHILD_SUBREAPER, ALLOW)})
109       .AddPolicyOnSyscall(
110           __NR_setsockopt,
111           [](bpf_labels& labels) -> std::vector<sock_filter> {
112             return {
113                 ARG_32(1),
114                 JNE32(SOL_SOCKET, JUMP(&labels, cf_setsockopt_end)),
115                 ARG_32(2),
116                 JEQ32(SO_REUSEADDR, ALLOW),
117                 JEQ32(SO_RCVTIMEO, ALLOW),
118                 LABEL(&labels, cf_setsockopt_end),
119             };
120           })
121       .AddPolicyOnSyscall(__NR_socket, {ARG_32(0), JEQ32(AF_UNIX, ALLOW),
122                                         JEQ32(AF_VSOCK, ALLOW)})
123       .AllowChmod()
124       .AllowDup()
125       .AllowEventFd()
126       .AllowFork()  // Multithreading, sandboxer_proxy, process monitor
127       .AllowGetIDs()
128       .AllowInotifyInit()
129       .AllowMkdir()
130       .AllowPipe()
131       .AllowSafeFcntl()
132       .AllowSelect()
133       .AllowSyscall(__NR_accept)
134       .AllowSyscall(__NR_bind)
135       .AllowSyscall(__NR_connect)
136       .AllowSyscall(__NR_execve)  // sandboxer_proxy
137       .AllowSyscall(__NR_getsid)
138       .AllowSyscall(__NR_inotify_add_watch)
139       .AllowSyscall(__NR_inotify_rm_watch)
140       .AllowSyscall(__NR_listen)
141       .AllowSyscall(__NR_msgget)  // Metrics SysV RPC
142       .AllowSyscall(__NR_msgsnd)  // Metrics SysV RPC
143       .AllowSyscall(__NR_recvmsg)
144       .AllowSyscall(__NR_sendmsg)
145       .AllowSyscall(__NR_setpgid)
146       .AllowSyscall(__NR_shutdown)
147       .AllowSyscall(__NR_socketpair)
148       .AllowSyscall(__NR_waitid)  // Not covered by `AllowWait()`
149       .AllowTCGETS()
150       .AllowUnlink()
151       .AllowWait();
152 }
153 
154 }  // namespace cuttlefish::process_sandboxer
155