jail/
config.rs

1// Copyright 2023 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::path::PathBuf;
6
7use serde::Deserialize;
8use serde::Serialize;
9use serde_keyvalue::FromKeyValues;
10
11fn jail_config_default_pivot_root() -> PathBuf {
12    PathBuf::from(option_env!("DEFAULT_PIVOT_ROOT").unwrap_or("/var/empty"))
13}
14
15#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, FromKeyValues)]
16#[serde(deny_unknown_fields, rename_all = "kebab-case")]
17pub struct JailConfig {
18    #[serde(default = "jail_config_default_pivot_root")]
19    pub pivot_root: PathBuf,
20    #[cfg(any(target_os = "android", target_os = "linux"))]
21    #[serde(default)]
22    pub seccomp_policy_dir: Option<PathBuf>,
23    #[serde(default)]
24    pub seccomp_log_failures: bool,
25}
26
27impl Default for JailConfig {
28    fn default() -> Self {
29        JailConfig {
30            pivot_root: jail_config_default_pivot_root(),
31            #[cfg(any(target_os = "android", target_os = "linux"))]
32            seccomp_policy_dir: None,
33            seccomp_log_failures: false,
34        }
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use serde_keyvalue::from_key_values;
41
42    use super::*;
43
44    #[test]
45    fn parse_jailconfig() {
46        let config: JailConfig = Default::default();
47        assert_eq!(
48            config,
49            JailConfig {
50                pivot_root: jail_config_default_pivot_root(),
51                #[cfg(any(target_os = "android", target_os = "linux"))]
52                seccomp_policy_dir: None,
53                seccomp_log_failures: false,
54            }
55        );
56
57        let config: JailConfig = from_key_values("").unwrap();
58        assert_eq!(config, Default::default());
59
60        let config: JailConfig = from_key_values("pivot-root=/path/to/pivot/root").unwrap();
61        assert_eq!(
62            config,
63            JailConfig {
64                pivot_root: "/path/to/pivot/root".into(),
65                ..Default::default()
66            }
67        );
68
69        cfg_if::cfg_if! {
70            if #[cfg(any(target_os = "android", target_os = "linux"))] {
71                let config: JailConfig =
72                    from_key_values("seccomp-policy-dir=/path/to/seccomp/dir").unwrap();
73                assert_eq!(config, JailConfig {
74                    seccomp_policy_dir: Some("/path/to/seccomp/dir".into()),
75                    ..Default::default()
76                });
77            }
78        }
79
80        let config: JailConfig = from_key_values("seccomp-log-failures").unwrap();
81        assert_eq!(
82            config,
83            JailConfig {
84                seccomp_log_failures: true,
85                ..Default::default()
86            }
87        );
88
89        let config: JailConfig = from_key_values("seccomp-log-failures=false").unwrap();
90        assert_eq!(
91            config,
92            JailConfig {
93                seccomp_log_failures: false,
94                ..Default::default()
95            }
96        );
97
98        let config: JailConfig =
99            from_key_values("pivot-root=/path/to/pivot/root,seccomp-log-failures=true").unwrap();
100        #[allow(clippy::needless_update)]
101        let expected = JailConfig {
102            pivot_root: "/path/to/pivot/root".into(),
103            seccomp_log_failures: true,
104            ..Default::default()
105        };
106        assert_eq!(config, expected);
107
108        let config: std::result::Result<JailConfig, _> =
109            from_key_values("seccomp-log-failures,invalid-arg=value");
110        assert!(config.is_err());
111    }
112}