1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2017 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker #![deny(missing_docs)]
6*bb4ee6a4SAndroid Build Coastguard Worker #![allow(dead_code)]
7*bb4ee6a4SAndroid Build Coastguard Worker
8*bb4ee6a4SAndroid Build Coastguard Worker use std::path::Path;
9*bb4ee6a4SAndroid Build Coastguard Worker use std::str;
10*bb4ee6a4SAndroid Build Coastguard Worker
11*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::bail;
12*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Context;
13*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Result;
14*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "seccomp_trace")]
15*bb4ee6a4SAndroid Build Coastguard Worker use base::debug;
16*bb4ee6a4SAndroid Build Coastguard Worker use base::getegid;
17*bb4ee6a4SAndroid Build Coastguard Worker use base::geteuid;
18*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "seccomp_trace")]
19*bb4ee6a4SAndroid Build Coastguard Worker use base::warn;
20*bb4ee6a4SAndroid Build Coastguard Worker use libc::c_ulong;
21*bb4ee6a4SAndroid Build Coastguard Worker use minijail::Minijail;
22*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(not(feature = "seccomp_trace"))]
23*bb4ee6a4SAndroid Build Coastguard Worker use once_cell::sync::Lazy;
24*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "seccomp_trace")]
25*bb4ee6a4SAndroid Build Coastguard Worker use static_assertions::assert_eq_size;
26*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "seccomp_trace")]
27*bb4ee6a4SAndroid Build Coastguard Worker use zerocopy::AsBytes;
28*bb4ee6a4SAndroid Build Coastguard Worker
29*bb4ee6a4SAndroid Build Coastguard Worker use crate::config::JailConfig;
30*bb4ee6a4SAndroid Build Coastguard Worker
31*bb4ee6a4SAndroid Build Coastguard Worker // ANDROID: b/246968493
32*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(not(feature = "seccomp_trace"))]
33*bb4ee6a4SAndroid Build Coastguard Worker static EMBEDDED_BPFS: Lazy<std::collections::HashMap<&str, Vec<u8>>> =
34*bb4ee6a4SAndroid Build Coastguard Worker Lazy::new(|| std::collections::HashMap::<&str, Vec<u8>>::new());
35*bb4ee6a4SAndroid Build Coastguard Worker
36*bb4ee6a4SAndroid Build Coastguard Worker /// Most devices don't need to open many fds.
37*bb4ee6a4SAndroid Build Coastguard Worker pub const MAX_OPEN_FILES_DEFAULT: u64 = 1024;
38*bb4ee6a4SAndroid Build Coastguard Worker /// The max open files for gpu processes.
39*bb4ee6a4SAndroid Build Coastguard Worker const MAX_OPEN_FILES_FOR_GPU: u64 = 32768;
40*bb4ee6a4SAndroid Build Coastguard Worker /// The max open files for jail warden, matching FD_RAW_FAILURE.
41*bb4ee6a4SAndroid Build Coastguard Worker pub const MAX_OPEN_FILES_FOR_JAIL_WARDEN: u64 = 65536;
42*bb4ee6a4SAndroid Build Coastguard Worker
43*bb4ee6a4SAndroid Build Coastguard Worker /// The user in the jail to run as.
44*bb4ee6a4SAndroid Build Coastguard Worker pub enum RunAsUser {
45*bb4ee6a4SAndroid Build Coastguard Worker /// Do not specify the user
46*bb4ee6a4SAndroid Build Coastguard Worker Unspecified,
47*bb4ee6a4SAndroid Build Coastguard Worker /// Runs as the same user in the jail as the current user.
48*bb4ee6a4SAndroid Build Coastguard Worker CurrentUser,
49*bb4ee6a4SAndroid Build Coastguard Worker /// Runs as the root user in the jail.
50*bb4ee6a4SAndroid Build Coastguard Worker Root,
51*bb4ee6a4SAndroid Build Coastguard Worker /// Runs as the specified uid and gid.
52*bb4ee6a4SAndroid Build Coastguard Worker /// This requires `SandboxConfig::ugid_map` to be set.
53*bb4ee6a4SAndroid Build Coastguard Worker Specified(u32, u32),
54*bb4ee6a4SAndroid Build Coastguard Worker }
55*bb4ee6a4SAndroid Build Coastguard Worker
56*bb4ee6a4SAndroid Build Coastguard Worker /// Config for the sandbox to be created by [Minijail].
57*bb4ee6a4SAndroid Build Coastguard Worker pub struct SandboxConfig<'a> {
58*bb4ee6a4SAndroid Build Coastguard Worker /// Whether or not to drop all capabilities in the sandbox.
59*bb4ee6a4SAndroid Build Coastguard Worker pub limit_caps: bool,
60*bb4ee6a4SAndroid Build Coastguard Worker log_failures: bool,
61*bb4ee6a4SAndroid Build Coastguard Worker seccomp_policy_dir: Option<&'a Path>,
62*bb4ee6a4SAndroid Build Coastguard Worker seccomp_policy_name: &'a str,
63*bb4ee6a4SAndroid Build Coastguard Worker /// The pair of `uid_map` and `gid_map`.
64*bb4ee6a4SAndroid Build Coastguard Worker pub ugid_map: Option<(&'a str, &'a str)>,
65*bb4ee6a4SAndroid Build Coastguard Worker /// The remount mode instead of default MS_PRIVATE.
66*bb4ee6a4SAndroid Build Coastguard Worker pub remount_mode: Option<c_ulong>,
67*bb4ee6a4SAndroid Build Coastguard Worker /// Whether to use empty net namespace. Enabled by default.
68*bb4ee6a4SAndroid Build Coastguard Worker pub namespace_net: bool,
69*bb4ee6a4SAndroid Build Coastguard Worker /// Whether or not to configure the jail to support bind-mounts.
70*bb4ee6a4SAndroid Build Coastguard Worker ///
71*bb4ee6a4SAndroid Build Coastguard Worker /// Note that most device processes deny `open(2)` and `openat(2)` by seccomp policy and just
72*bb4ee6a4SAndroid Build Coastguard Worker /// returns `ENOENT`. Passing opened file descriptors is recommended over opening files in the
73*bb4ee6a4SAndroid Build Coastguard Worker /// sandbox.
74*bb4ee6a4SAndroid Build Coastguard Worker pub bind_mounts: bool,
75*bb4ee6a4SAndroid Build Coastguard Worker /// Specify the user in the jail to run as.
76*bb4ee6a4SAndroid Build Coastguard Worker pub run_as: RunAsUser,
77*bb4ee6a4SAndroid Build Coastguard Worker }
78*bb4ee6a4SAndroid Build Coastguard Worker
79*bb4ee6a4SAndroid Build Coastguard Worker impl<'a> SandboxConfig<'a> {
80*bb4ee6a4SAndroid Build Coastguard Worker /// Creates [SandboxConfig].
new(jail_config: &'a JailConfig, policy: &'a str) -> Self81*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(jail_config: &'a JailConfig, policy: &'a str) -> Self {
82*bb4ee6a4SAndroid Build Coastguard Worker Self {
83*bb4ee6a4SAndroid Build Coastguard Worker limit_caps: true,
84*bb4ee6a4SAndroid Build Coastguard Worker log_failures: jail_config.seccomp_log_failures,
85*bb4ee6a4SAndroid Build Coastguard Worker seccomp_policy_dir: jail_config.seccomp_policy_dir.as_ref().map(Path::new),
86*bb4ee6a4SAndroid Build Coastguard Worker seccomp_policy_name: policy,
87*bb4ee6a4SAndroid Build Coastguard Worker ugid_map: None,
88*bb4ee6a4SAndroid Build Coastguard Worker remount_mode: None,
89*bb4ee6a4SAndroid Build Coastguard Worker namespace_net: true,
90*bb4ee6a4SAndroid Build Coastguard Worker bind_mounts: false,
91*bb4ee6a4SAndroid Build Coastguard Worker run_as: RunAsUser::Unspecified,
92*bb4ee6a4SAndroid Build Coastguard Worker }
93*bb4ee6a4SAndroid Build Coastguard Worker }
94*bb4ee6a4SAndroid Build Coastguard Worker }
95*bb4ee6a4SAndroid Build Coastguard Worker
96*bb4ee6a4SAndroid Build Coastguard Worker /// Wrapper that cleans up a [Minijail] when it is dropped
97*bb4ee6a4SAndroid Build Coastguard Worker pub struct ScopedMinijail(pub Minijail);
98*bb4ee6a4SAndroid Build Coastguard Worker
99*bb4ee6a4SAndroid Build Coastguard Worker impl Drop for ScopedMinijail {
drop(&mut self)100*bb4ee6a4SAndroid Build Coastguard Worker fn drop(&mut self) {
101*bb4ee6a4SAndroid Build Coastguard Worker let _ = self.0.kill();
102*bb4ee6a4SAndroid Build Coastguard Worker }
103*bb4ee6a4SAndroid Build Coastguard Worker }
104*bb4ee6a4SAndroid Build Coastguard Worker
105*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a [Minijail] instance which just changes the root using pivot_root(2) path and
106*bb4ee6a4SAndroid Build Coastguard Worker /// `max_open_files` using `RLIMIT_NOFILE`.
107*bb4ee6a4SAndroid Build Coastguard Worker ///
108*bb4ee6a4SAndroid Build Coastguard Worker /// If `root` path is "/", the minijail don't change the root.
109*bb4ee6a4SAndroid Build Coastguard Worker ///
110*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments
111*bb4ee6a4SAndroid Build Coastguard Worker ///
112*bb4ee6a4SAndroid Build Coastguard Worker /// * `root` - The root path to be changed to by minijail.
113*bb4ee6a4SAndroid Build Coastguard Worker /// * `max_open_files` - The maximum number of file descriptors to allow a jailed process to open.
114*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::unnecessary_cast)]
create_base_minijail(root: &Path, max_open_files: u64) -> Result<Minijail>115*bb4ee6a4SAndroid Build Coastguard Worker pub fn create_base_minijail(root: &Path, max_open_files: u64) -> Result<Minijail> {
116*bb4ee6a4SAndroid Build Coastguard Worker // Validate new root directory. Path::is_dir() also checks the existence.
117*bb4ee6a4SAndroid Build Coastguard Worker if !root.is_dir() {
118*bb4ee6a4SAndroid Build Coastguard Worker bail!("{:?} is not a directory, cannot create jail", root);
119*bb4ee6a4SAndroid Build Coastguard Worker }
120*bb4ee6a4SAndroid Build Coastguard Worker // chroot accepts absolute path only.
121*bb4ee6a4SAndroid Build Coastguard Worker if !root.is_absolute() {
122*bb4ee6a4SAndroid Build Coastguard Worker bail!("{:?} is not absolute path", root);
123*bb4ee6a4SAndroid Build Coastguard Worker }
124*bb4ee6a4SAndroid Build Coastguard Worker
125*bb4ee6a4SAndroid Build Coastguard Worker let mut jail = Minijail::new().context("failed to jail device")?;
126*bb4ee6a4SAndroid Build Coastguard Worker
127*bb4ee6a4SAndroid Build Coastguard Worker // Only pivot_root if we are not re-using the current root directory.
128*bb4ee6a4SAndroid Build Coastguard Worker if root != Path::new("/") {
129*bb4ee6a4SAndroid Build Coastguard Worker // Run in a new mount namespace.
130*bb4ee6a4SAndroid Build Coastguard Worker jail.namespace_vfs();
131*bb4ee6a4SAndroid Build Coastguard Worker jail.enter_pivot_root(root)
132*bb4ee6a4SAndroid Build Coastguard Worker .context("failed to pivot root device")?;
133*bb4ee6a4SAndroid Build Coastguard Worker }
134*bb4ee6a4SAndroid Build Coastguard Worker
135*bb4ee6a4SAndroid Build Coastguard Worker jail.set_rlimit(libc::RLIMIT_NOFILE as i32, max_open_files, max_open_files)
136*bb4ee6a4SAndroid Build Coastguard Worker .context("error setting max open files")?;
137*bb4ee6a4SAndroid Build Coastguard Worker
138*bb4ee6a4SAndroid Build Coastguard Worker Ok(jail)
139*bb4ee6a4SAndroid Build Coastguard Worker }
140*bb4ee6a4SAndroid Build Coastguard Worker
141*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a [Minijail] instance which just invokes a jail process and sets
142*bb4ee6a4SAndroid Build Coastguard Worker /// `max_open_files` using `RLIMIT_NOFILE`. This is helpful with crosvm process
143*bb4ee6a4SAndroid Build Coastguard Worker /// runs as a non-root user without SYS_ADMIN capabilities.
144*bb4ee6a4SAndroid Build Coastguard Worker ///
145*bb4ee6a4SAndroid Build Coastguard Worker /// Unlike `create_base_minijail`, this function doesn't call `pivot_root`
146*bb4ee6a4SAndroid Build Coastguard Worker /// and `mount namespace`. So, it runs as a non-root user without
147*bb4ee6a4SAndroid Build Coastguard Worker /// SYS_ADMIN capabilities.
148*bb4ee6a4SAndroid Build Coastguard Worker ///
149*bb4ee6a4SAndroid Build Coastguard Worker /// Note that since there is no file system isolation provided by this function,
150*bb4ee6a4SAndroid Build Coastguard Worker /// caller of this function should enforce other security mechanisum such as selinux
151*bb4ee6a4SAndroid Build Coastguard Worker /// on the host to protect directories.
152*bb4ee6a4SAndroid Build Coastguard Worker ///
153*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments
154*bb4ee6a4SAndroid Build Coastguard Worker ///
155*bb4ee6a4SAndroid Build Coastguard Worker /// * `root` - The root path to checked before the process is jailed
156*bb4ee6a4SAndroid Build Coastguard Worker /// * `max_open_files` - The maximum number of file descriptors to allow a jailed process to open.
157*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::unnecessary_cast)]
create_base_minijail_without_pivot_root( root: &Path, max_open_files: u64, ) -> Result<Minijail>158*bb4ee6a4SAndroid Build Coastguard Worker pub fn create_base_minijail_without_pivot_root(
159*bb4ee6a4SAndroid Build Coastguard Worker root: &Path,
160*bb4ee6a4SAndroid Build Coastguard Worker max_open_files: u64,
161*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<Minijail> {
162*bb4ee6a4SAndroid Build Coastguard Worker // Validate new root directory. Path::is_dir() also checks the existence.
163*bb4ee6a4SAndroid Build Coastguard Worker if !root.is_dir() {
164*bb4ee6a4SAndroid Build Coastguard Worker bail!("{:?} is not a directory, cannot create jail", root);
165*bb4ee6a4SAndroid Build Coastguard Worker }
166*bb4ee6a4SAndroid Build Coastguard Worker if !root.is_absolute() {
167*bb4ee6a4SAndroid Build Coastguard Worker bail!("{:?} is not absolute path", root);
168*bb4ee6a4SAndroid Build Coastguard Worker }
169*bb4ee6a4SAndroid Build Coastguard Worker
170*bb4ee6a4SAndroid Build Coastguard Worker let mut jail = Minijail::new().context("failed to jail device")?;
171*bb4ee6a4SAndroid Build Coastguard Worker jail.set_rlimit(libc::RLIMIT_NOFILE as i32, max_open_files, max_open_files)
172*bb4ee6a4SAndroid Build Coastguard Worker .context("error setting max open files")?;
173*bb4ee6a4SAndroid Build Coastguard Worker
174*bb4ee6a4SAndroid Build Coastguard Worker Ok(jail)
175*bb4ee6a4SAndroid Build Coastguard Worker }
176*bb4ee6a4SAndroid Build Coastguard Worker
177*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a [Minijail] instance which creates a sandbox.
178*bb4ee6a4SAndroid Build Coastguard Worker ///
179*bb4ee6a4SAndroid Build Coastguard Worker /// # Arguments
180*bb4ee6a4SAndroid Build Coastguard Worker ///
181*bb4ee6a4SAndroid Build Coastguard Worker /// * `root` - The root path to be changed to by minijail.
182*bb4ee6a4SAndroid Build Coastguard Worker /// * `max_open_files` - The maximum number of file descriptors to allow a jailed process to open.
183*bb4ee6a4SAndroid Build Coastguard Worker /// * `config` - The [SandboxConfig] to control details of the sandbox.
create_sandbox_minijail( root: &Path, max_open_files: u64, config: &SandboxConfig, ) -> Result<Minijail>184*bb4ee6a4SAndroid Build Coastguard Worker pub fn create_sandbox_minijail(
185*bb4ee6a4SAndroid Build Coastguard Worker root: &Path,
186*bb4ee6a4SAndroid Build Coastguard Worker max_open_files: u64,
187*bb4ee6a4SAndroid Build Coastguard Worker config: &SandboxConfig,
188*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<Minijail> {
189*bb4ee6a4SAndroid Build Coastguard Worker let mut jail = create_base_minijail(root, max_open_files)?;
190*bb4ee6a4SAndroid Build Coastguard Worker
191*bb4ee6a4SAndroid Build Coastguard Worker jail.namespace_pids();
192*bb4ee6a4SAndroid Build Coastguard Worker jail.namespace_user();
193*bb4ee6a4SAndroid Build Coastguard Worker jail.namespace_user_disable_setgroups();
194*bb4ee6a4SAndroid Build Coastguard Worker if config.limit_caps {
195*bb4ee6a4SAndroid Build Coastguard Worker // Don't need any capabilities.
196*bb4ee6a4SAndroid Build Coastguard Worker jail.use_caps(0);
197*bb4ee6a4SAndroid Build Coastguard Worker }
198*bb4ee6a4SAndroid Build Coastguard Worker match config.run_as {
199*bb4ee6a4SAndroid Build Coastguard Worker RunAsUser::Unspecified => {
200*bb4ee6a4SAndroid Build Coastguard Worker if config.bind_mounts && config.ugid_map.is_none() {
201*bb4ee6a4SAndroid Build Coastguard Worker // Minijail requires to set user/group map to mount extra directories.
202*bb4ee6a4SAndroid Build Coastguard Worker add_current_user_to_jail(&mut jail)?;
203*bb4ee6a4SAndroid Build Coastguard Worker }
204*bb4ee6a4SAndroid Build Coastguard Worker }
205*bb4ee6a4SAndroid Build Coastguard Worker RunAsUser::CurrentUser => {
206*bb4ee6a4SAndroid Build Coastguard Worker add_current_user_to_jail(&mut jail)?;
207*bb4ee6a4SAndroid Build Coastguard Worker }
208*bb4ee6a4SAndroid Build Coastguard Worker RunAsUser::Root => {
209*bb4ee6a4SAndroid Build Coastguard Worker // Add the current user as root in the jail.
210*bb4ee6a4SAndroid Build Coastguard Worker let crosvm_uid = geteuid();
211*bb4ee6a4SAndroid Build Coastguard Worker let crosvm_gid = getegid();
212*bb4ee6a4SAndroid Build Coastguard Worker jail.uidmap(&format!("0 {} 1", crosvm_uid))
213*bb4ee6a4SAndroid Build Coastguard Worker .context("error setting UID map")?;
214*bb4ee6a4SAndroid Build Coastguard Worker jail.gidmap(&format!("0 {} 1", crosvm_gid))
215*bb4ee6a4SAndroid Build Coastguard Worker .context("error setting GID map")?;
216*bb4ee6a4SAndroid Build Coastguard Worker }
217*bb4ee6a4SAndroid Build Coastguard Worker RunAsUser::Specified(uid, gid) => {
218*bb4ee6a4SAndroid Build Coastguard Worker if uid != 0 {
219*bb4ee6a4SAndroid Build Coastguard Worker jail.change_uid(uid)
220*bb4ee6a4SAndroid Build Coastguard Worker }
221*bb4ee6a4SAndroid Build Coastguard Worker if gid != 0 {
222*bb4ee6a4SAndroid Build Coastguard Worker jail.change_gid(gid)
223*bb4ee6a4SAndroid Build Coastguard Worker }
224*bb4ee6a4SAndroid Build Coastguard Worker }
225*bb4ee6a4SAndroid Build Coastguard Worker }
226*bb4ee6a4SAndroid Build Coastguard Worker if config.bind_mounts {
227*bb4ee6a4SAndroid Build Coastguard Worker // Create a tmpfs in the device's root directory so that we can bind mount files.
228*bb4ee6a4SAndroid Build Coastguard Worker // The size=67108864 is size=64*1024*1024 or size=64MB.
229*bb4ee6a4SAndroid Build Coastguard Worker // TODO(b/267581374): Use appropriate size for tmpfs.
230*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_with_data(
231*bb4ee6a4SAndroid Build Coastguard Worker Path::new("none"),
232*bb4ee6a4SAndroid Build Coastguard Worker Path::new("/"),
233*bb4ee6a4SAndroid Build Coastguard Worker "tmpfs",
234*bb4ee6a4SAndroid Build Coastguard Worker (libc::MS_NOSUID | libc::MS_NODEV | libc::MS_NOEXEC) as usize,
235*bb4ee6a4SAndroid Build Coastguard Worker "size=67108864",
236*bb4ee6a4SAndroid Build Coastguard Worker )?;
237*bb4ee6a4SAndroid Build Coastguard Worker }
238*bb4ee6a4SAndroid Build Coastguard Worker if let Some((uid_map, gid_map)) = config.ugid_map {
239*bb4ee6a4SAndroid Build Coastguard Worker jail.uidmap(uid_map).context("error setting UID map")?;
240*bb4ee6a4SAndroid Build Coastguard Worker jail.gidmap(gid_map).context("error setting GID map")?;
241*bb4ee6a4SAndroid Build Coastguard Worker }
242*bb4ee6a4SAndroid Build Coastguard Worker // Run in a new mount namespace.
243*bb4ee6a4SAndroid Build Coastguard Worker jail.namespace_vfs();
244*bb4ee6a4SAndroid Build Coastguard Worker
245*bb4ee6a4SAndroid Build Coastguard Worker if config.namespace_net {
246*bb4ee6a4SAndroid Build Coastguard Worker // Run in an empty network namespace.
247*bb4ee6a4SAndroid Build Coastguard Worker jail.namespace_net();
248*bb4ee6a4SAndroid Build Coastguard Worker }
249*bb4ee6a4SAndroid Build Coastguard Worker
250*bb4ee6a4SAndroid Build Coastguard Worker // Don't allow the device to gain new privileges.
251*bb4ee6a4SAndroid Build Coastguard Worker jail.no_new_privs();
252*bb4ee6a4SAndroid Build Coastguard Worker
253*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "seccomp_trace")]
254*bb4ee6a4SAndroid Build Coastguard Worker {
255*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)]
256*bb4ee6a4SAndroid Build Coastguard Worker #[derive(AsBytes)]
257*bb4ee6a4SAndroid Build Coastguard Worker struct sock_filter {
258*bb4ee6a4SAndroid Build Coastguard Worker /* Filter block */
259*bb4ee6a4SAndroid Build Coastguard Worker code: u16, /* Actual filter code */
260*bb4ee6a4SAndroid Build Coastguard Worker jt: u8, /* Jump true */
261*bb4ee6a4SAndroid Build Coastguard Worker jf: u8, /* Jump false */
262*bb4ee6a4SAndroid Build Coastguard Worker k: u32, /* Generic multiuse field */
263*bb4ee6a4SAndroid Build Coastguard Worker }
264*bb4ee6a4SAndroid Build Coastguard Worker
265*bb4ee6a4SAndroid Build Coastguard Worker // BPF constant is defined in https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/bpf_common.h
266*bb4ee6a4SAndroid Build Coastguard Worker // BPF parser/assembler is defined in https://elixir.bootlin.com/linux/v4.9/source/tools/net/bpf_exp.y
267*bb4ee6a4SAndroid Build Coastguard Worker const SECCOMP_RET_TRACE: u32 = 0x7ff00000;
268*bb4ee6a4SAndroid Build Coastguard Worker const SECCOMP_RET_LOG: u32 = 0x7ffc0000;
269*bb4ee6a4SAndroid Build Coastguard Worker const BPF_RET: u16 = 0x06;
270*bb4ee6a4SAndroid Build Coastguard Worker const BPF_K: u16 = 0x00;
271*bb4ee6a4SAndroid Build Coastguard Worker
272*bb4ee6a4SAndroid Build Coastguard Worker // return SECCOMP_RET_LOG for all syscalls
273*bb4ee6a4SAndroid Build Coastguard Worker const FILTER_RET_LOG_BLOCK: sock_filter = sock_filter {
274*bb4ee6a4SAndroid Build Coastguard Worker code: BPF_RET | BPF_K,
275*bb4ee6a4SAndroid Build Coastguard Worker jt: 0,
276*bb4ee6a4SAndroid Build Coastguard Worker jf: 0,
277*bb4ee6a4SAndroid Build Coastguard Worker k: SECCOMP_RET_LOG,
278*bb4ee6a4SAndroid Build Coastguard Worker };
279*bb4ee6a4SAndroid Build Coastguard Worker
280*bb4ee6a4SAndroid Build Coastguard Worker warn!("The running crosvm is compiled with seccomp_trace feature, and is striclty used for debugging purpose only. DO NOT USE IN PRODUCTION!!!");
281*bb4ee6a4SAndroid Build Coastguard Worker debug!(
282*bb4ee6a4SAndroid Build Coastguard Worker "seccomp_trace {{\"event\": \"minijail_create\", \"name\": \"{}\", \"jail_addr\": \"0x{:x}\"}}",
283*bb4ee6a4SAndroid Build Coastguard Worker config.seccomp_policy_name,
284*bb4ee6a4SAndroid Build Coastguard Worker read_jail_addr(&jail),
285*bb4ee6a4SAndroid Build Coastguard Worker );
286*bb4ee6a4SAndroid Build Coastguard Worker jail.parse_seccomp_bytes(FILTER_RET_LOG_BLOCK.as_bytes())
287*bb4ee6a4SAndroid Build Coastguard Worker .unwrap();
288*bb4ee6a4SAndroid Build Coastguard Worker }
289*bb4ee6a4SAndroid Build Coastguard Worker
290*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(not(feature = "seccomp_trace"))]
291*bb4ee6a4SAndroid Build Coastguard Worker if let Some(seccomp_policy_dir) = config.seccomp_policy_dir {
292*bb4ee6a4SAndroid Build Coastguard Worker let seccomp_policy_path = seccomp_policy_dir.join(config.seccomp_policy_name);
293*bb4ee6a4SAndroid Build Coastguard Worker // By default we'll prioritize using the pre-compiled .bpf over the .policy file (the .bpf
294*bb4ee6a4SAndroid Build Coastguard Worker // is expected to be compiled using "trap" as the failure behavior instead of the default
295*bb4ee6a4SAndroid Build Coastguard Worker // "kill" behavior) when a policy path is supplied in the command line arugments. Otherwise
296*bb4ee6a4SAndroid Build Coastguard Worker // the built-in pre-compiled policies will be used.
297*bb4ee6a4SAndroid Build Coastguard Worker // Refer to the code comment for the "seccomp-log-failures" command-line parameter for an
298*bb4ee6a4SAndroid Build Coastguard Worker // explanation about why the |log_failures| flag forces the use of .policy files (and the
299*bb4ee6a4SAndroid Build Coastguard Worker // build-time alternative to this run-time flag).
300*bb4ee6a4SAndroid Build Coastguard Worker let bpf_policy_file = seccomp_policy_path.with_extension("bpf");
301*bb4ee6a4SAndroid Build Coastguard Worker if bpf_policy_file.exists() && !config.log_failures {
302*bb4ee6a4SAndroid Build Coastguard Worker jail.parse_seccomp_program(&bpf_policy_file)
303*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| {
304*bb4ee6a4SAndroid Build Coastguard Worker format!(
305*bb4ee6a4SAndroid Build Coastguard Worker "failed to parse precompiled seccomp policy: {}",
306*bb4ee6a4SAndroid Build Coastguard Worker bpf_policy_file.display()
307*bb4ee6a4SAndroid Build Coastguard Worker )
308*bb4ee6a4SAndroid Build Coastguard Worker })?;
309*bb4ee6a4SAndroid Build Coastguard Worker } else {
310*bb4ee6a4SAndroid Build Coastguard Worker // Use TSYNC only for the side effect of it using SECCOMP_RET_TRAP, which will correctly
311*bb4ee6a4SAndroid Build Coastguard Worker // kill the entire device process if a worker thread commits a seccomp violation.
312*bb4ee6a4SAndroid Build Coastguard Worker jail.set_seccomp_filter_tsync();
313*bb4ee6a4SAndroid Build Coastguard Worker if config.log_failures {
314*bb4ee6a4SAndroid Build Coastguard Worker jail.log_seccomp_filter_failures();
315*bb4ee6a4SAndroid Build Coastguard Worker }
316*bb4ee6a4SAndroid Build Coastguard Worker let bpf_policy_file = seccomp_policy_path.with_extension("policy");
317*bb4ee6a4SAndroid Build Coastguard Worker jail.parse_seccomp_filters(&bpf_policy_file)
318*bb4ee6a4SAndroid Build Coastguard Worker .with_context(|| {
319*bb4ee6a4SAndroid Build Coastguard Worker format!(
320*bb4ee6a4SAndroid Build Coastguard Worker "failed to parse seccomp policy: {}",
321*bb4ee6a4SAndroid Build Coastguard Worker bpf_policy_file.display()
322*bb4ee6a4SAndroid Build Coastguard Worker )
323*bb4ee6a4SAndroid Build Coastguard Worker })?;
324*bb4ee6a4SAndroid Build Coastguard Worker }
325*bb4ee6a4SAndroid Build Coastguard Worker } else {
326*bb4ee6a4SAndroid Build Coastguard Worker set_embedded_bpf_program(&mut jail, config.seccomp_policy_name)?;
327*bb4ee6a4SAndroid Build Coastguard Worker }
328*bb4ee6a4SAndroid Build Coastguard Worker
329*bb4ee6a4SAndroid Build Coastguard Worker jail.use_seccomp_filter();
330*bb4ee6a4SAndroid Build Coastguard Worker // Don't do init setup.
331*bb4ee6a4SAndroid Build Coastguard Worker jail.run_as_init();
332*bb4ee6a4SAndroid Build Coastguard Worker // Set up requested remount mode instead of default MS_PRIVATE.
333*bb4ee6a4SAndroid Build Coastguard Worker if let Some(mode) = config.remount_mode {
334*bb4ee6a4SAndroid Build Coastguard Worker jail.set_remount_mode(mode);
335*bb4ee6a4SAndroid Build Coastguard Worker }
336*bb4ee6a4SAndroid Build Coastguard Worker
337*bb4ee6a4SAndroid Build Coastguard Worker Ok(jail)
338*bb4ee6a4SAndroid Build Coastguard Worker }
339*bb4ee6a4SAndroid Build Coastguard Worker
340*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a basic [Minijail] if `jail_config` is present.
341*bb4ee6a4SAndroid Build Coastguard Worker ///
342*bb4ee6a4SAndroid Build Coastguard Worker /// Returns `None` if `jail_config` is none.
simple_jail(jail_config: &Option<JailConfig>, policy: &str) -> Result<Option<Minijail>>343*bb4ee6a4SAndroid Build Coastguard Worker pub fn simple_jail(jail_config: &Option<JailConfig>, policy: &str) -> Result<Option<Minijail>> {
344*bb4ee6a4SAndroid Build Coastguard Worker if let Some(jail_config) = jail_config {
345*bb4ee6a4SAndroid Build Coastguard Worker let config = SandboxConfig::new(jail_config, policy);
346*bb4ee6a4SAndroid Build Coastguard Worker Ok(Some(create_sandbox_minijail(
347*bb4ee6a4SAndroid Build Coastguard Worker &jail_config.pivot_root,
348*bb4ee6a4SAndroid Build Coastguard Worker MAX_OPEN_FILES_DEFAULT,
349*bb4ee6a4SAndroid Build Coastguard Worker &config,
350*bb4ee6a4SAndroid Build Coastguard Worker )?))
351*bb4ee6a4SAndroid Build Coastguard Worker } else {
352*bb4ee6a4SAndroid Build Coastguard Worker Ok(None)
353*bb4ee6a4SAndroid Build Coastguard Worker }
354*bb4ee6a4SAndroid Build Coastguard Worker }
355*bb4ee6a4SAndroid Build Coastguard Worker
356*bb4ee6a4SAndroid Build Coastguard Worker /// Creates [Minijail] for gpu processes.
create_gpu_minijail( root: &Path, config: &SandboxConfig, render_node_only: bool, ) -> Result<Minijail>357*bb4ee6a4SAndroid Build Coastguard Worker pub fn create_gpu_minijail(
358*bb4ee6a4SAndroid Build Coastguard Worker root: &Path,
359*bb4ee6a4SAndroid Build Coastguard Worker config: &SandboxConfig,
360*bb4ee6a4SAndroid Build Coastguard Worker render_node_only: bool,
361*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<Minijail> {
362*bb4ee6a4SAndroid Build Coastguard Worker let mut jail = create_sandbox_minijail(root, MAX_OPEN_FILES_FOR_GPU, config)?;
363*bb4ee6a4SAndroid Build Coastguard Worker
364*bb4ee6a4SAndroid Build Coastguard Worker // Device nodes required for DRM.
365*bb4ee6a4SAndroid Build Coastguard Worker let sys_dev_char_path = Path::new("/sys/dev/char");
366*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(sys_dev_char_path, sys_dev_char_path, false)?;
367*bb4ee6a4SAndroid Build Coastguard Worker
368*bb4ee6a4SAndroid Build Coastguard Worker // Necessary for CGROUP control of the vGPU threads
369*bb4ee6a4SAndroid Build Coastguard Worker // This is not necessary UNLESS one wants to make use
370*bb4ee6a4SAndroid Build Coastguard Worker // of the gpu cgroup command line options.
371*bb4ee6a4SAndroid Build Coastguard Worker let sys_cpuset_path = Path::new("/sys/fs/cgroup/cpuset");
372*bb4ee6a4SAndroid Build Coastguard Worker if sys_cpuset_path.exists() {
373*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(sys_cpuset_path, sys_cpuset_path, true)?;
374*bb4ee6a4SAndroid Build Coastguard Worker }
375*bb4ee6a4SAndroid Build Coastguard Worker
376*bb4ee6a4SAndroid Build Coastguard Worker let sys_devices_path = Path::new("/sys/devices");
377*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(sys_devices_path, sys_devices_path, false)?;
378*bb4ee6a4SAndroid Build Coastguard Worker
379*bb4ee6a4SAndroid Build Coastguard Worker jail_mount_bind_drm(&mut jail, render_node_only)?;
380*bb4ee6a4SAndroid Build Coastguard Worker
381*bb4ee6a4SAndroid Build Coastguard Worker // If the ARM specific devices exist on the host, bind mount them in.
382*bb4ee6a4SAndroid Build Coastguard Worker let mali0_path = Path::new("/dev/mali0");
383*bb4ee6a4SAndroid Build Coastguard Worker if mali0_path.exists() {
384*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(mali0_path, mali0_path, true)?;
385*bb4ee6a4SAndroid Build Coastguard Worker }
386*bb4ee6a4SAndroid Build Coastguard Worker
387*bb4ee6a4SAndroid Build Coastguard Worker let pvr_sync_path = Path::new("/dev/pvr_sync");
388*bb4ee6a4SAndroid Build Coastguard Worker if pvr_sync_path.exists() {
389*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(pvr_sync_path, pvr_sync_path, true)?;
390*bb4ee6a4SAndroid Build Coastguard Worker }
391*bb4ee6a4SAndroid Build Coastguard Worker
392*bb4ee6a4SAndroid Build Coastguard Worker // If the udmabuf driver exists on the host, bind mount it in.
393*bb4ee6a4SAndroid Build Coastguard Worker let udmabuf_path = Path::new("/dev/udmabuf");
394*bb4ee6a4SAndroid Build Coastguard Worker if udmabuf_path.exists() {
395*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(udmabuf_path, udmabuf_path, true)?;
396*bb4ee6a4SAndroid Build Coastguard Worker }
397*bb4ee6a4SAndroid Build Coastguard Worker
398*bb4ee6a4SAndroid Build Coastguard Worker // Libraries that are required when mesa drivers are dynamically loaded.
399*bb4ee6a4SAndroid Build Coastguard Worker jail_mount_bind_if_exists(
400*bb4ee6a4SAndroid Build Coastguard Worker &mut jail,
401*bb4ee6a4SAndroid Build Coastguard Worker &[
402*bb4ee6a4SAndroid Build Coastguard Worker "/usr/lib",
403*bb4ee6a4SAndroid Build Coastguard Worker "/usr/lib64",
404*bb4ee6a4SAndroid Build Coastguard Worker "/lib",
405*bb4ee6a4SAndroid Build Coastguard Worker "/lib64",
406*bb4ee6a4SAndroid Build Coastguard Worker "/usr/share/drirc.d",
407*bb4ee6a4SAndroid Build Coastguard Worker "/usr/share/glvnd",
408*bb4ee6a4SAndroid Build Coastguard Worker "/usr/share/libdrm",
409*bb4ee6a4SAndroid Build Coastguard Worker "/usr/share/vulkan",
410*bb4ee6a4SAndroid Build Coastguard Worker ],
411*bb4ee6a4SAndroid Build Coastguard Worker )?;
412*bb4ee6a4SAndroid Build Coastguard Worker
413*bb4ee6a4SAndroid Build Coastguard Worker // pvr driver requires read access to /proc/self/task/*/comm.
414*bb4ee6a4SAndroid Build Coastguard Worker mount_proc(&mut jail)?;
415*bb4ee6a4SAndroid Build Coastguard Worker
416*bb4ee6a4SAndroid Build Coastguard Worker // To enable perfetto tracing, we need to give access to the perfetto service IPC
417*bb4ee6a4SAndroid Build Coastguard Worker // endpoints.
418*bb4ee6a4SAndroid Build Coastguard Worker let perfetto_path = Path::new("/run/perfetto");
419*bb4ee6a4SAndroid Build Coastguard Worker if perfetto_path.exists() {
420*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(perfetto_path, perfetto_path, true)?;
421*bb4ee6a4SAndroid Build Coastguard Worker }
422*bb4ee6a4SAndroid Build Coastguard Worker
423*bb4ee6a4SAndroid Build Coastguard Worker Ok(jail)
424*bb4ee6a4SAndroid Build Coastguard Worker }
425*bb4ee6a4SAndroid Build Coastguard Worker
426*bb4ee6a4SAndroid Build Coastguard Worker /// Selectively bind mount drm nodes into `jail` based on `render_node_only`
427*bb4ee6a4SAndroid Build Coastguard Worker ///
428*bb4ee6a4SAndroid Build Coastguard Worker /// This function will not return an error if drm nodes don't exist
jail_mount_bind_drm(jail: &mut Minijail, render_node_only: bool) -> Result<()>429*bb4ee6a4SAndroid Build Coastguard Worker pub fn jail_mount_bind_drm(jail: &mut Minijail, render_node_only: bool) -> Result<()> {
430*bb4ee6a4SAndroid Build Coastguard Worker if render_node_only {
431*bb4ee6a4SAndroid Build Coastguard Worker const DRM_NUM_NODES: u32 = 63;
432*bb4ee6a4SAndroid Build Coastguard Worker const DRM_RENDER_NODE_START: u32 = 128;
433*bb4ee6a4SAndroid Build Coastguard Worker for offset in 0..DRM_NUM_NODES {
434*bb4ee6a4SAndroid Build Coastguard Worker let path_str = format!("/dev/dri/renderD{}", DRM_RENDER_NODE_START + offset);
435*bb4ee6a4SAndroid Build Coastguard Worker let drm_dri_path = Path::new(&path_str);
436*bb4ee6a4SAndroid Build Coastguard Worker if !drm_dri_path.exists() {
437*bb4ee6a4SAndroid Build Coastguard Worker break;
438*bb4ee6a4SAndroid Build Coastguard Worker }
439*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(drm_dri_path, drm_dri_path, false)?;
440*bb4ee6a4SAndroid Build Coastguard Worker }
441*bb4ee6a4SAndroid Build Coastguard Worker } else {
442*bb4ee6a4SAndroid Build Coastguard Worker let drm_dri_path = Path::new("/dev/dri");
443*bb4ee6a4SAndroid Build Coastguard Worker if drm_dri_path.exists() {
444*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(drm_dri_path, drm_dri_path, false)?;
445*bb4ee6a4SAndroid Build Coastguard Worker }
446*bb4ee6a4SAndroid Build Coastguard Worker }
447*bb4ee6a4SAndroid Build Coastguard Worker
448*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
449*bb4ee6a4SAndroid Build Coastguard Worker }
450*bb4ee6a4SAndroid Build Coastguard Worker
451*bb4ee6a4SAndroid Build Coastguard Worker /// Mirror-mount all the directories in `dirs` into `jail` on a best-effort basis.
452*bb4ee6a4SAndroid Build Coastguard Worker ///
453*bb4ee6a4SAndroid Build Coastguard Worker /// This function will not return an error if any of the directories in `dirs` is missing.
jail_mount_bind_if_exists<P: AsRef<std::ffi::OsStr>>( jail: &mut Minijail, dirs: &[P], ) -> Result<()>454*bb4ee6a4SAndroid Build Coastguard Worker pub fn jail_mount_bind_if_exists<P: AsRef<std::ffi::OsStr>>(
455*bb4ee6a4SAndroid Build Coastguard Worker jail: &mut Minijail,
456*bb4ee6a4SAndroid Build Coastguard Worker dirs: &[P],
457*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()> {
458*bb4ee6a4SAndroid Build Coastguard Worker for dir in dirs {
459*bb4ee6a4SAndroid Build Coastguard Worker let dir_path = Path::new(dir);
460*bb4ee6a4SAndroid Build Coastguard Worker if dir_path.exists() {
461*bb4ee6a4SAndroid Build Coastguard Worker jail.mount_bind(dir_path, dir_path, false)?;
462*bb4ee6a4SAndroid Build Coastguard Worker }
463*bb4ee6a4SAndroid Build Coastguard Worker }
464*bb4ee6a4SAndroid Build Coastguard Worker
465*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
466*bb4ee6a4SAndroid Build Coastguard Worker }
467*bb4ee6a4SAndroid Build Coastguard Worker
468*bb4ee6a4SAndroid Build Coastguard Worker /// Mount proc in the sandbox.
mount_proc(jail: &mut Minijail) -> Result<()>469*bb4ee6a4SAndroid Build Coastguard Worker pub fn mount_proc(jail: &mut Minijail) -> Result<()> {
470*bb4ee6a4SAndroid Build Coastguard Worker jail.mount(
471*bb4ee6a4SAndroid Build Coastguard Worker Path::new("proc"),
472*bb4ee6a4SAndroid Build Coastguard Worker Path::new("/proc"),
473*bb4ee6a4SAndroid Build Coastguard Worker "proc",
474*bb4ee6a4SAndroid Build Coastguard Worker (libc::MS_NOSUID | libc::MS_NODEV | libc::MS_NOEXEC | libc::MS_RDONLY) as usize,
475*bb4ee6a4SAndroid Build Coastguard Worker )?;
476*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
477*bb4ee6a4SAndroid Build Coastguard Worker }
478*bb4ee6a4SAndroid Build Coastguard Worker
479*bb4ee6a4SAndroid Build Coastguard Worker /// Read minijail internal struct address for uniquely identifying and tracking jail's lifetime
480*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "seccomp_trace")]
read_jail_addr(jail: &Minijail) -> usize481*bb4ee6a4SAndroid Build Coastguard Worker pub fn read_jail_addr(jail: &Minijail) -> usize {
482*bb4ee6a4SAndroid Build Coastguard Worker // We can only hope minijail's rust object will always only contain a pointer to C jail struct
483*bb4ee6a4SAndroid Build Coastguard Worker assert_eq_size!(Minijail, usize);
484*bb4ee6a4SAndroid Build Coastguard Worker // Safe because it's only doing a read within bound checked by static assert
485*bb4ee6a4SAndroid Build Coastguard Worker unsafe { *(jail as *const Minijail as *const usize) }
486*bb4ee6a4SAndroid Build Coastguard Worker }
487*bb4ee6a4SAndroid Build Coastguard Worker
488*bb4ee6a4SAndroid Build Coastguard Worker /// Set the uid/gid for the jailed process and give a basic id map. This is
489*bb4ee6a4SAndroid Build Coastguard Worker /// required for bind mounts to work.
add_current_user_to_jail(jail: &mut Minijail) -> Result<()>490*bb4ee6a4SAndroid Build Coastguard Worker fn add_current_user_to_jail(jail: &mut Minijail) -> Result<()> {
491*bb4ee6a4SAndroid Build Coastguard Worker let crosvm_uid = geteuid();
492*bb4ee6a4SAndroid Build Coastguard Worker let crosvm_gid = getegid();
493*bb4ee6a4SAndroid Build Coastguard Worker
494*bb4ee6a4SAndroid Build Coastguard Worker jail.uidmap(&format!("{0} {0} 1", crosvm_uid))
495*bb4ee6a4SAndroid Build Coastguard Worker .context("error setting UID map")?;
496*bb4ee6a4SAndroid Build Coastguard Worker jail.gidmap(&format!("{0} {0} 1", crosvm_gid))
497*bb4ee6a4SAndroid Build Coastguard Worker .context("error setting GID map")?;
498*bb4ee6a4SAndroid Build Coastguard Worker
499*bb4ee6a4SAndroid Build Coastguard Worker if crosvm_uid != 0 {
500*bb4ee6a4SAndroid Build Coastguard Worker jail.change_uid(crosvm_uid);
501*bb4ee6a4SAndroid Build Coastguard Worker }
502*bb4ee6a4SAndroid Build Coastguard Worker if crosvm_gid != 0 {
503*bb4ee6a4SAndroid Build Coastguard Worker jail.change_gid(crosvm_gid);
504*bb4ee6a4SAndroid Build Coastguard Worker }
505*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
506*bb4ee6a4SAndroid Build Coastguard Worker }
507*bb4ee6a4SAndroid Build Coastguard Worker
508*bb4ee6a4SAndroid Build Coastguard Worker /// Set the seccomp policy for a jail from embedded bpfs
set_embedded_bpf_program(jail: &mut Minijail, seccomp_policy_name: &str) -> Result<()>509*bb4ee6a4SAndroid Build Coastguard Worker pub fn set_embedded_bpf_program(jail: &mut Minijail, seccomp_policy_name: &str) -> Result<()> {
510*bb4ee6a4SAndroid Build Coastguard Worker let bpf_program = EMBEDDED_BPFS.get(seccomp_policy_name).with_context(|| {
511*bb4ee6a4SAndroid Build Coastguard Worker format!(
512*bb4ee6a4SAndroid Build Coastguard Worker "failed to find embedded seccomp policy: {}",
513*bb4ee6a4SAndroid Build Coastguard Worker seccomp_policy_name
514*bb4ee6a4SAndroid Build Coastguard Worker )
515*bb4ee6a4SAndroid Build Coastguard Worker })?;
516*bb4ee6a4SAndroid Build Coastguard Worker jail.parse_seccomp_bytes(bpf_program).with_context(|| {
517*bb4ee6a4SAndroid Build Coastguard Worker format!(
518*bb4ee6a4SAndroid Build Coastguard Worker "failed to parse embedded seccomp policy: {}",
519*bb4ee6a4SAndroid Build Coastguard Worker seccomp_policy_name
520*bb4ee6a4SAndroid Build Coastguard Worker )
521*bb4ee6a4SAndroid Build Coastguard Worker })?;
522*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
523*bb4ee6a4SAndroid Build Coastguard Worker }
524