1#![warn(variant_size_differences)]
6
7pub mod local_cache;
8pub mod permission_check;
9pub mod policy;
10pub mod security_server;
11
12mod new_policy;
13
14pub use access_vector_cache::{AccessQueryArgs, DEFAULT_SHARED_SIZE, QueryCacheCapacity};
15pub use concurrent_access_cache::{AccessCacheStorage, ConcurrentAccessCache};
16pub use security_server::{PolicySeqNo, SecurityServer};
17
18mod access_vector_cache;
19mod cache_stats;
20mod concurrent_access_cache;
21mod concurrent_cache;
22mod exceptions_config;
23mod kernel_permissions;
24mod sid_table;
25mod sync;
26
27pub use kernel_permissions::*;
29
30pub use policy::ClassId;
32
33pub use starnix_uapi::selinux::{InitialSid, ReferenceInitialSid, SecurityId, TaskAttrs};
34
35use policy::arrays::FsUseType;
36
37#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
39pub enum ObjectClass {
40 Kernel(KernelClass),
42 ClassId(ClassId),
45}
46
47impl From<ClassId> for ObjectClass {
48 fn from(id: ClassId) -> Self {
49 Self::ClassId(id)
50 }
51}
52
53impl<T: Into<KernelClass>> From<T> for ObjectClass {
54 fn from(class: T) -> Self {
55 Self::Kernel(class.into())
56 }
57}
58
59#[derive(Clone, Copy, Debug, PartialEq)]
62pub struct NullessByteStr<'a>(&'a [u8]);
63
64impl<'a> NullessByteStr<'a> {
65 pub fn as_bytes(&self) -> &[u8] {
67 &self.0
68 }
69}
70
71impl<'a, S: AsRef<[u8]> + ?Sized> From<&'a S> for NullessByteStr<'a> {
72 fn from(s: &'a S) -> Self {
76 let value = s.as_ref();
77 match value.iter().position(|c| *c == 0) {
78 Some(end) => Self(&value[..end]),
79 None => Self(value),
80 }
81 }
82}
83
84#[derive(Clone, Debug, PartialEq)]
85pub struct FileSystemMountSids {
86 pub context: Option<SecurityId>,
87 pub fs_context: Option<SecurityId>,
88 pub def_context: Option<SecurityId>,
89 pub root_context: Option<SecurityId>,
90}
91
92#[derive(Clone, Debug, PartialEq)]
93pub struct FileSystemLabel {
94 pub sid: SecurityId,
95 pub scheme: FileSystemLabelingScheme,
96 pub mount_sids: FileSystemMountSids,
98}
99
100#[derive(Clone, Debug, PartialEq)]
101pub enum FileSystemLabelingScheme {
102 Mountpoint { sid: SecurityId },
104 FsUse { fs_use_type: FsUseType, default_sid: SecurityId },
108 GenFsCon { supports_seclabel: bool },
111}
112
113#[derive(Clone, Debug, Default, PartialEq)]
117pub struct FileSystemMountOptions {
118 pub context: Option<Vec<u8>>,
122 pub def_context: Option<Vec<u8>>,
125 pub fs_context: Option<Vec<u8>>,
128 pub root_context: Option<Vec<u8>>,
131}
132
133pub struct SeLinuxStatus {
135 pub is_enforcing: bool,
137 pub change_count: u32,
139 pub deny_unknown: bool,
141}
142
143pub trait SeLinuxStatusPublisher: Send + Sync {
145 fn set_status(&mut self, policy_status: SeLinuxStatus);
147}
148
149pub use new_policy::PolicyCap;
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn object_class_permissions() {
157 let test_class_id = ClassId::for_test(20);
158 assert_eq!(ObjectClass::ClassId(test_class_id), test_class_id.into());
159 for variant in ProcessPermission::PERMISSIONS {
160 assert_eq!(KernelClass::Process, variant.class());
161 assert_eq!("process", variant.class().name());
162 assert_eq!(ObjectClass::Kernel(KernelClass::Process), variant.class().into());
163 }
164 }
165
166 #[test]
167 fn nulless_byte_str_equivalence() {
168 let unterminated: NullessByteStr<'_> = b"u:object_r:test_valid_t:s0".into();
169 let nul_terminated: NullessByteStr<'_> = b"u:object_r:test_valid_t:s0\0".into();
170 let nul_containing: NullessByteStr<'_> =
171 b"u:object_r:test_valid_t:s0\0IGNORE THIS\0!\0".into();
172
173 for context in [nul_terminated, nul_containing] {
174 assert_eq!(unterminated, context);
175 assert_eq!(unterminated.as_bytes(), context.as_bytes());
176 }
177 }
178}