sandbox_core/
privilege.rs1use crate::capabilities::SystemCapabilities;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
7pub enum PrivilegeMode {
8 Unprivileged,
11
12 Privileged,
15
16 #[default]
19 Auto,
20}
21
22impl PrivilegeMode {
23 pub fn resolve(&self, caps: &SystemCapabilities) -> ResolvedMode {
25 match self {
26 PrivilegeMode::Privileged => ResolvedMode::Privileged,
27 PrivilegeMode::Unprivileged => ResolvedMode::Unprivileged,
28 PrivilegeMode::Auto => {
29 if caps.has_root && caps.has_cgroup_v2 {
30 ResolvedMode::Privileged
31 } else {
32 ResolvedMode::Unprivileged
33 }
34 }
35 }
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum ResolvedMode {
42 Unprivileged,
43 Privileged,
44}
45
46impl ResolvedMode {
47 pub fn is_privileged(&self) -> bool {
48 matches!(self, ResolvedMode::Privileged)
49 }
50
51 pub fn is_unprivileged(&self) -> bool {
52 matches!(self, ResolvedMode::Unprivileged)
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn default_is_auto() {
62 assert_eq!(PrivilegeMode::default(), PrivilegeMode::Auto);
63 }
64
65 #[test]
66 fn privileged_always_resolves_to_privileged() {
67 let caps = SystemCapabilities {
68 has_root: false,
69 has_user_namespaces: false,
70 has_seccomp: false,
71 has_landlock: false,
72 has_cgroup_v2: false,
73 has_cgroup_delegation: false,
74 };
75 assert_eq!(
76 PrivilegeMode::Privileged.resolve(&caps),
77 ResolvedMode::Privileged
78 );
79 }
80
81 #[test]
82 fn unprivileged_always_resolves_to_unprivileged() {
83 let caps = SystemCapabilities {
84 has_root: true,
85 has_user_namespaces: true,
86 has_seccomp: true,
87 has_landlock: true,
88 has_cgroup_v2: true,
89 has_cgroup_delegation: true,
90 };
91 assert_eq!(
92 PrivilegeMode::Unprivileged.resolve(&caps),
93 ResolvedMode::Unprivileged
94 );
95 }
96
97 #[test]
98 fn auto_resolves_to_privileged_when_root_with_cgroups() {
99 let caps = SystemCapabilities {
100 has_root: true,
101 has_user_namespaces: true,
102 has_seccomp: true,
103 has_landlock: true,
104 has_cgroup_v2: true,
105 has_cgroup_delegation: true,
106 };
107 assert_eq!(PrivilegeMode::Auto.resolve(&caps), ResolvedMode::Privileged);
108 }
109
110 #[test]
111 fn auto_resolves_to_unprivileged_without_root() {
112 let caps = SystemCapabilities {
113 has_root: false,
114 has_user_namespaces: true,
115 has_seccomp: true,
116 has_landlock: true,
117 has_cgroup_v2: true,
118 has_cgroup_delegation: false,
119 };
120 assert_eq!(
121 PrivilegeMode::Auto.resolve(&caps),
122 ResolvedMode::Unprivileged
123 );
124 }
125
126 #[test]
127 fn resolved_mode_helpers() {
128 assert!(ResolvedMode::Privileged.is_privileged());
129 assert!(!ResolvedMode::Privileged.is_unprivileged());
130 assert!(ResolvedMode::Unprivileged.is_unprivileged());
131 assert!(!ResolvedMode::Unprivileged.is_privileged());
132 }
133}