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
5 use std::path::PathBuf;
6
7 use serde::Deserialize;
8 use serde::Serialize;
9 use serde_keyvalue::FromKeyValues;
10
jail_config_default_pivot_root() -> PathBuf11 fn 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")]
17 pub 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
27 impl Default for JailConfig {
default() -> Self28 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)]
39 mod tests {
40 use serde_keyvalue::from_key_values;
41
42 use super::*;
43
44 #[test]
parse_jailconfig()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 }
113