1use crate::access_vector_cache::{
6 AccessVectorCache, CacheStats, KernelXpermsAccessDecision, Query,
7};
8use crate::exceptions_config::ExceptionsConfig;
9use crate::new_policy::HandleUnknown;
10use crate::new_policy::traits::{HasName, HasPolicyId};
11use crate::permission_check::{PerThreadCache, PermissionCheck};
12use crate::policy::parser::PolicyData;
13use crate::policy::{
14 AccessDecision, AccessVector, AccessVectorComputer, ClassId, FsUseLabelAndType, FsUseType,
15 KernelAccessDecision, PermissionId, Policy, SELINUX_AVD_FLAGS_PERMISSIVE, SecurityContext,
16 XpermsBitmap, XpermsKind, parse_policy_by_value,
17};
18use crate::sid_table::SidTable;
19use crate::sync::RwLock;
20use crate::{
21 ClassPermission, FileSystemLabel, FileSystemLabelingScheme, FileSystemMountOptions,
22 FileSystemMountSids, FsNodeClass, InitialSid, KernelClass, KernelPermission, NullessByteStr,
23 ObjectClass, PolicyCap, SeLinuxStatus, SeLinuxStatusPublisher, SecurityId,
24};
25use anyhow::Context as _;
26use std::collections::HashMap;
27use std::ops::DerefMut;
28use std::sync::Arc;
29use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
30
31const ROOT_PATH: &'static str = "/";
32
33struct ActivePolicy {
34 parsed: Arc<Policy>,
36
37 sid_table: SidTable,
39
40 exceptions: ExceptionsConfig,
42}
43
44#[derive(Default)]
45struct SeLinuxBooleans {
46 active: HashMap<String, bool>,
49 pending: HashMap<String, bool>,
51}
52
53impl SeLinuxBooleans {
54 fn reset(&mut self, booleans: Vec<(String, bool)>) {
55 self.active = HashMap::from_iter(booleans);
56 self.pending.clear();
57 }
58 fn names(&self) -> Vec<String> {
59 self.active.keys().cloned().collect()
60 }
61 fn set_pending(&mut self, name: &str, value: bool) -> Result<(), ()> {
62 if !self.active.contains_key(name) {
63 return Err(());
64 }
65 self.pending.insert(name.into(), value);
66 Ok(())
67 }
68 fn get(&self, name: &str) -> Result<(bool, bool), ()> {
69 let active = self.active.get(name).ok_or(())?;
70 let pending = self.pending.get(name).unwrap_or(active);
71 Ok((*active, *pending))
72 }
73 fn commit_pending(&mut self) {
74 self.active.extend(self.pending.drain());
75 }
76}
77
78struct SecurityServerState {
79 active_policy: Option<ActivePolicy>,
81
82 booleans: SeLinuxBooleans,
84
85 status_publisher: Option<Box<dyn SeLinuxStatusPublisher>>,
87}
88
89impl SecurityServerState {
90 fn deny_unknown(&self) -> bool {
91 self.active_policy
92 .as_ref()
93 .map_or(true, |p| p.parsed.handle_unknown() != HandleUnknown::Allow)
94 }
95 fn reject_unknown(&self) -> bool {
96 self.active_policy
97 .as_ref()
98 .map_or(false, |p| p.parsed.handle_unknown() == HandleUnknown::Reject)
99 }
100
101 fn expect_active_policy(&self) -> &ActivePolicy {
102 &self.active_policy.as_ref().expect("policy should be loaded")
103 }
104
105 fn expect_active_policy_mut(&mut self) -> &mut ActivePolicy {
106 self.active_policy.as_mut().expect("policy should be loaded")
107 }
108
109 fn compute_access_decision_raw(
110 &self,
111 source_sid: SecurityId,
112 target_sid: SecurityId,
113 target_class: ObjectClass,
114 ) -> AccessDecision {
115 let Some(active_policy) = self.active_policy.as_ref() else {
116 return AccessDecision::allow(AccessVector::ALL);
118 };
119
120 let source_context = active_policy.sid_table.sid_to_security_context(source_sid);
121 let target_context = active_policy.sid_table.sid_to_security_context(target_sid);
122
123 let mut decision = active_policy.parsed.compute_access_decision(
124 &source_context,
125 &target_context,
126 target_class,
127 );
128
129 decision.todo_bug = active_policy.exceptions.lookup(
130 source_context.type_(),
131 target_context.type_(),
132 target_class,
133 );
134
135 decision
136 }
137}
138
139pub(crate) struct SecurityServerBackend {
140 state: RwLock<SecurityServerState>,
142
143 is_enforcing: AtomicBool,
146
147 policy_change_count: AtomicU32,
152}
153
154#[derive(Clone, Copy, Debug, PartialEq, Eq)]
156pub struct PolicySeqNo(u32);
157
158pub struct SecurityServer {
159 access_vector_cache: AccessVectorCache,
162
163 backend: Arc<SecurityServerBackend>,
165
166 exceptions: Vec<String>,
168}
169
170impl SecurityServer {
171 pub fn new_default() -> Arc<Self> {
173 Self::new(String::new(), Vec::new())
174 }
175
176 pub fn new(options: String, exceptions: Vec<String>) -> Arc<Self> {
178 assert_eq!(options, String::new());
180
181 let backend = Arc::new(SecurityServerBackend {
182 state: RwLock::new(SecurityServerState {
183 active_policy: None,
184 booleans: SeLinuxBooleans::default(),
185 status_publisher: None,
186 }),
187 is_enforcing: AtomicBool::new(false),
188 policy_change_count: AtomicU32::new(0),
189 });
190
191 let access_vector_cache = AccessVectorCache::new(backend.clone());
192
193 Arc::new(Self { access_vector_cache, backend, exceptions })
194 }
195
196 pub fn as_permission_check<'a>(
199 self: &'a Self,
200 local_cache: &'a PerThreadCache,
201 ) -> PermissionCheck<'a> {
202 PermissionCheck::new(self, &self.access_vector_cache, local_cache)
203 }
204
205 pub fn security_context_to_sid(
209 &self,
210 security_context: NullessByteStr<'_>,
211 ) -> Result<SecurityId, anyhow::Error> {
212 self.backend.compute_sid(|active_policy| {
213 active_policy
214 .parsed
215 .parse_security_context(security_context)
216 .map_err(anyhow::Error::from)
217 })
218 }
219
220 pub fn sid_to_security_context(&self, sid: SecurityId) -> Option<Vec<u8>> {
225 let locked_state = self.backend.state.read();
226 let active_policy = locked_state.active_policy.as_ref()?;
227 let context = active_policy.sid_table.try_sid_to_security_context(sid)?;
228 Some(active_policy.parsed.serialize_security_context(context))
229 }
230
231 pub fn sid_to_security_context_with_nul(&self, sid: SecurityId) -> Option<Vec<u8>> {
233 self.sid_to_security_context(sid).map(|mut context| {
234 context.push(0u8);
235 context
236 })
237 }
238
239 pub fn load_policy(&self, binary_policy: Vec<u8>) -> Result<(), anyhow::Error> {
241 let unvalidated_policy = parse_policy_by_value(binary_policy)?;
244 let parsed = Arc::new(unvalidated_policy.validate()?);
245
246 let exceptions = self.exceptions.iter().map(String::as_str).collect::<Vec<&str>>();
247 let exceptions = ExceptionsConfig::new(&parsed, &exceptions)?;
248
249 self.with_mut_state_and_update_status(|state| {
251 let sid_table = if let Some(previous_active_policy) = &state.active_policy {
252 SidTable::new_from_previous(parsed.clone(), &previous_active_policy.sid_table)
253 } else {
254 SidTable::new(parsed.clone())
255 };
256
257 state.booleans.reset(
260 parsed
261 .conditional_booleans()
262 .iter()
263 .map(|(name, value)| (String::from_utf8((*name).to_vec()).unwrap(), *value))
265 .collect(),
266 );
267
268 state.active_policy = Some(ActivePolicy { parsed, sid_table, exceptions });
269 self.backend.policy_change_count.fetch_add(1, Ordering::Relaxed);
270 });
271
272 Ok(())
273 }
274
275 pub fn has_policy(&self) -> bool {
277 self.backend.state.read().active_policy.is_some()
278 }
279
280 pub fn get_binary_policy(&self) -> Option<PolicyData> {
282 let state = self.backend.state.read();
283 let active_policy = state.active_policy.as_ref()?;
284 Some(active_policy.parsed.serialize())
285 }
286
287 pub fn set_enforcing(&self, enforcing: bool) {
289 self.with_mut_state_and_update_status(|_| {
290 self.backend.is_enforcing.store(enforcing, Ordering::Release);
291 });
292 }
293
294 pub fn is_enforcing(&self) -> bool {
295 self.backend.is_enforcing.load(Ordering::Acquire)
296 }
297
298 pub fn deny_unknown(&self) -> bool {
301 self.backend.state.read().deny_unknown()
302 }
303
304 pub fn reject_unknown(&self) -> bool {
307 self.backend.state.read().reject_unknown()
308 }
309
310 pub fn conditional_booleans(&self) -> Vec<String> {
313 self.backend.state.read().booleans.names()
314 }
315
316 pub fn get_boolean(&self, name: &str) -> Result<(bool, bool), ()> {
318 self.backend.state.read().booleans.get(name)
319 }
320
321 pub fn set_pending_boolean(&self, name: &str, value: bool) -> Result<(), ()> {
323 self.backend.state.write().booleans.set_pending(name, value)
324 }
325
326 pub fn commit_pending_booleans(&self) {
328 self.with_mut_state_and_update_status(|state| {
330 state.booleans.commit_pending();
331 self.backend.policy_change_count.fetch_add(1, Ordering::Relaxed);
332 });
333 }
334
335 pub fn is_policycap_enabled(&self, policy_cap: PolicyCap) -> bool {
337 let locked_state = self.backend.state.read();
338 let Some(policy) = &locked_state.active_policy else {
339 return false;
340 };
341 policy.parsed.has_policycap(policy_cap)
342 }
343
344 pub fn avc_cache_stats(&self) -> CacheStats {
346 self.access_vector_cache.cache_stats()
347 }
348
349 pub fn policy_seqno(&self) -> PolicySeqNo {
351 PolicySeqNo(self.backend.policy_change_count.load(Ordering::Relaxed))
352 }
353
354 pub fn class_names(&self) -> Result<Vec<Vec<u8>>, ()> {
356 let locked_state = self.backend.state.read();
357 let names = locked_state
358 .expect_active_policy()
359 .parsed
360 .classes()
361 .iter()
362 .map(|class| class.name().to_vec())
363 .collect();
364 Ok(names)
365 }
366
367 pub fn class_id_by_name(&self, name: &str) -> Result<ClassId, ()> {
369 let locked_state = self.backend.state.read();
370 Ok(locked_state
371 .expect_active_policy()
372 .parsed
373 .classes()
374 .get_by_name(name.as_bytes())
375 .ok_or(())?
376 .id())
377 }
378
379 pub fn class_permissions_by_name(
383 &self,
384 name: &str,
385 ) -> Result<Vec<(PermissionId, Vec<u8>)>, ()> {
386 let locked_state = self.backend.state.read();
387 locked_state.expect_active_policy().parsed.find_class_permissions_by_name(name)
388 }
389
390 pub fn resolve_fs_label(
394 &self,
395 fs_type: NullessByteStr<'_>,
396 mount_options: &FileSystemMountOptions,
397 ) -> Result<FileSystemLabel, anyhow::Error> {
398 let mut locked_state = self.backend.state.write();
399 let active_policy = locked_state.expect_active_policy_mut();
400
401 let mount_sids = FileSystemMountSids {
402 context: sid_from_mount_option(active_policy, &mount_options.context)?,
403 fs_context: sid_from_mount_option(active_policy, &mount_options.fs_context)?,
404 def_context: sid_from_mount_option(active_policy, &mount_options.def_context)?,
405 root_context: sid_from_mount_option(active_policy, &mount_options.root_context)?,
406 };
407 let label = if let Some(mountpoint_sid) = mount_sids.context {
408 FileSystemLabel {
412 sid: mount_sids.fs_context.unwrap_or(mountpoint_sid),
413 scheme: FileSystemLabelingScheme::Mountpoint { sid: mountpoint_sid },
414 mount_sids,
415 }
416 } else if let Some(FsUseLabelAndType { context, use_type }) =
417 active_policy.parsed.fs_use_label_and_type(fs_type)
418 {
419 let fs_sid_from_policy =
421 active_policy.sid_table.security_context_to_sid(&context).unwrap();
422 let fs_sid = mount_sids.fs_context.unwrap_or(fs_sid_from_policy);
423 FileSystemLabel {
424 sid: fs_sid,
425 scheme: FileSystemLabelingScheme::FsUse {
426 fs_use_type: use_type,
427 default_sid: mount_sids.def_context.unwrap_or_else(|| InitialSid::File.into()),
428 },
429 mount_sids,
430 }
431 } else if let Some(context) =
432 active_policy.parsed.genfscon_label_for_fs_and_path(fs_type, ROOT_PATH.into(), None)
433 {
434 let genfscon_sid = active_policy.sid_table.security_context_to_sid(&context).unwrap();
436 let fs_sid = mount_sids.fs_context.unwrap_or(genfscon_sid);
437
438 let fs_type = fs_type.as_bytes();
448 let mut supports_seclabel = matches!(fs_type, b"sysfs" | b"tracefs" | b"pstore");
449 supports_seclabel |= matches!(fs_type, b"cgroup" | b"cgroup2")
450 && active_policy.parsed.has_policycap(PolicyCap::CgroupSeclabel);
451 supports_seclabel |= fs_type == b"functionfs"
452 && active_policy.parsed.has_policycap(PolicyCap::FunctionfsSeclabel);
453
454 FileSystemLabel {
455 sid: fs_sid,
456 scheme: FileSystemLabelingScheme::GenFsCon { supports_seclabel },
457 mount_sids,
458 }
459 } else {
460 FileSystemLabel {
462 sid: mount_sids.fs_context.unwrap_or_else(|| InitialSid::Unlabeled.into()),
463 scheme: FileSystemLabelingScheme::FsUse {
464 fs_use_type: FsUseType::Xattr,
465 default_sid: mount_sids.def_context.unwrap_or_else(|| InitialSid::File.into()),
466 },
467 mount_sids,
468 }
469 };
470 Ok(label)
471 }
472
473 pub fn genfscon_label_for_fs_and_path(
478 &self,
479 fs_type: NullessByteStr<'_>,
480 node_path: NullessByteStr<'_>,
481 class_id: Option<KernelClass>,
482 ) -> Result<SecurityId, anyhow::Error> {
483 self.backend.compute_sid(|active_policy| {
484 active_policy
485 .parsed
486 .genfscon_label_for_fs_and_path(fs_type, node_path.into(), class_id)
487 .ok_or_else(|| {
488 anyhow::anyhow!("Genfscon label requested for non-genfscon labeled filesystem")
489 })
490 })
491 }
492
493 pub fn is_bounded_by(&self, bounded_sid: SecurityId, parent_sid: SecurityId) -> bool {
498 let locked_state = self.backend.state.read();
499 let active_policy = locked_state.expect_active_policy();
500 let bounded_type = active_policy.sid_table.sid_to_security_context(bounded_sid).type_();
501 let parent_type = active_policy.sid_table.sid_to_security_context(parent_sid).type_();
502 active_policy.parsed.is_bounded_by(bounded_type, parent_type)
503 }
504
505 pub fn set_status_publisher(&self, status_holder: Box<dyn SeLinuxStatusPublisher>) {
512 self.with_mut_state_and_update_status(|state| {
513 assert!(state.status_publisher.is_none());
514 state.status_publisher = Some(status_holder);
515 });
516 }
517
518 fn with_mut_state_and_update_status(&self, f: impl FnOnce(&mut SecurityServerState)) {
522 let mut locked_state = self.backend.state.write();
523 f(locked_state.deref_mut());
524 let new_value = SeLinuxStatus {
525 is_enforcing: self.is_enforcing(),
526 change_count: self.backend.policy_change_count.load(Ordering::Relaxed),
527 deny_unknown: locked_state.deny_unknown(),
528 };
529 if let Some(status_publisher) = &mut locked_state.status_publisher {
530 status_publisher.set_status(new_value);
531 }
532
533 std::mem::drop(locked_state);
536 self.access_vector_cache.reset();
537 }
538
539 pub fn compute_create_sid_raw(
545 &self,
546 source_sid: SecurityId,
547 target_sid: SecurityId,
548 target_class: ClassId,
549 ) -> Result<SecurityId, anyhow::Error> {
550 self.backend.compute_create_sid_raw(source_sid, target_sid, target_class.into())
551 }
552
553 pub fn compute_access_decision_raw(
556 &self,
557 source_sid: SecurityId,
558 target_sid: SecurityId,
559 target_class: ClassId,
560 ) -> AccessDecision {
561 self.backend.compute_access_decision_raw(source_sid, target_sid, target_class.into())
562 }
563}
564
565impl SecurityServerBackend {
566 fn compute_create_sid_raw(
567 &self,
568 source_sid: SecurityId,
569 target_sid: SecurityId,
570 target_class: ObjectClass,
571 ) -> Result<SecurityId, anyhow::Error> {
572 self.compute_sid(|active_policy| {
573 let source_context = active_policy.sid_table.sid_to_security_context(source_sid);
574 let target_context = active_policy.sid_table.sid_to_security_context(target_sid);
575
576 Ok(active_policy.parsed.compute_create_context(
577 source_context,
578 target_context,
579 target_class,
580 ))
581 })
582 .context("computing new security context from policy")
583 }
584
585 fn compute_sid(
587 &self,
588 compute_context: impl Fn(&ActivePolicy) -> Result<SecurityContext, anyhow::Error>,
589 ) -> Result<SecurityId, anyhow::Error> {
590 let readable_state = self.state.read();
593 let policy_change_count = self.policy_change_count.load(Ordering::Relaxed);
594 let policy_state = readable_state
595 .active_policy
596 .as_ref()
597 .ok_or_else(|| anyhow::anyhow!("no policy loaded"))?;
598 let context = compute_context(policy_state)?;
599 if let Some(sid) = policy_state.sid_table.security_context_to_existing_sid(&context) {
600 return Ok(sid);
601 }
602 std::mem::drop(readable_state);
603
604 let mut writable_state = self.state.write();
609 let needs_recompute =
610 policy_change_count != self.policy_change_count.load(Ordering::Relaxed);
611 let policy_state = writable_state.active_policy.as_mut().unwrap();
612 let context = if needs_recompute { compute_context(policy_state)? } else { context };
613 policy_state.sid_table.security_context_to_sid(&context).map_err(anyhow::Error::from)
614 }
615
616 fn compute_access_decision_raw(
617 &self,
618 source_sid: SecurityId,
619 target_sid: SecurityId,
620 target_class: ObjectClass,
621 ) -> AccessDecision {
622 let locked_state = self.state.read();
623
624 locked_state.compute_access_decision_raw(source_sid, target_sid, target_class)
625 }
626}
627
628impl Query for SecurityServerBackend {
629 fn compute_access_decision(
630 &self,
631 source_sid: SecurityId,
632 target_sid: SecurityId,
633 target_class: KernelClass,
634 ) -> KernelAccessDecision {
635 let locked_state = self.state.read();
636 let decision =
637 locked_state.compute_access_decision_raw(source_sid, target_sid, target_class.into());
638 locked_state.access_decision_to_kernel_access_decision(target_class, decision)
639 }
640
641 fn compute_create_sid(
642 &self,
643 source_sid: SecurityId,
644 target_sid: SecurityId,
645 target_class: KernelClass,
646 ) -> Result<SecurityId, anyhow::Error> {
647 self.compute_create_sid_raw(source_sid, target_sid, target_class.into())
648 }
649
650 fn compute_new_fs_node_sid_with_name(
651 &self,
652 source_sid: SecurityId,
653 target_sid: SecurityId,
654 fs_node_class: FsNodeClass,
655 fs_node_name: NullessByteStr<'_>,
656 ) -> Option<SecurityId> {
657 let mut locked_state = self.state.write();
658
659 let active_policy = locked_state.active_policy.as_mut().expect("Policy loaded");
661
662 let source_context = active_policy.sid_table.sid_to_security_context(source_sid);
663 let target_context = active_policy.sid_table.sid_to_security_context(target_sid);
664
665 let new_file_context = active_policy.parsed.compute_create_context_with_name(
666 source_context,
667 target_context,
668 fs_node_class,
669 fs_node_name,
670 )?;
671
672 active_policy.sid_table.security_context_to_sid(&new_file_context).ok()
673 }
674
675 fn compute_xperms_access_decision(
676 &self,
677 xperms_kind: XpermsKind,
678 source_sid: SecurityId,
679 target_sid: SecurityId,
680 permission: KernelPermission,
681 xperms_prefix: u8,
682 ) -> KernelXpermsAccessDecision {
683 let locked_state = self.state.read();
684
685 let active_policy = match &locked_state.active_policy {
686 Some(active_policy) => active_policy,
687 None => {
689 return KernelXpermsAccessDecision {
690 allow: XpermsBitmap::ALL,
691 audit: XpermsBitmap::NONE,
692 permissive: false,
693 has_todo: false,
694 };
695 }
696 };
697
698 let base_decision_raw = locked_state.compute_access_decision_raw(
701 source_sid,
702 target_sid,
703 permission.class().into(),
704 );
705 let base_decision = locked_state
706 .access_decision_to_kernel_access_decision(permission.class(), base_decision_raw);
707 let permission_access_vector = permission.as_access_vector();
708 let base_permit =
709 base_decision.allow & permission_access_vector == permission_access_vector;
710 let base_audit = base_decision.audit & permission_access_vector == permission_access_vector;
711
712 let source_context = active_policy.sid_table.sid_to_security_context(source_sid);
714 let target_context = active_policy.sid_table.sid_to_security_context(target_sid);
715 let xperms_decision = active_policy.parsed.compute_xperms_access_decision(
716 xperms_kind,
717 &source_context,
718 &target_context,
719 permission.class(),
720 xperms_prefix,
721 );
722
723 let allow = if !base_permit { XpermsBitmap::NONE } else { xperms_decision.allow };
725 let audit = if base_audit {
726 XpermsBitmap::ALL
727 } else {
728 (xperms_decision.allow & xperms_decision.auditallow)
729 | (!xperms_decision.allow & xperms_decision.auditdeny)
730 };
731 let permissive = (base_decision.flags & SELINUX_AVD_FLAGS_PERMISSIVE) != 0;
732 let has_todo = base_decision.todo_bug.is_some();
733 KernelXpermsAccessDecision { allow, audit, permissive, has_todo }
734 }
735}
736
737impl AccessVectorComputer for SecurityServerBackend {
738 fn access_decision_to_kernel_access_decision(
739 &self,
740 class: KernelClass,
741 av: AccessDecision,
742 ) -> KernelAccessDecision {
743 self.state.read().access_decision_to_kernel_access_decision(class, av)
744 }
745}
746
747impl AccessVectorComputer for SecurityServerState {
748 fn access_decision_to_kernel_access_decision(
749 &self,
750 class: KernelClass,
751 av: AccessDecision,
752 ) -> KernelAccessDecision {
753 match &self.active_policy {
754 Some(policy) => policy.parsed.access_decision_to_kernel_access_decision(class, av),
755 None => KernelAccessDecision {
756 allow: AccessVector::ALL,
757 audit: AccessVector::NONE,
758 flags: 0,
759 todo_bug: None,
760 },
761 }
762 }
763}
764
765fn sid_from_mount_option(
768 active_policy: &mut ActivePolicy,
769 mount_option: &Option<Vec<u8>>,
770) -> Result<Option<SecurityId>, anyhow::Error> {
771 let Some(label) = mount_option else {
772 return Ok(None);
773 };
774 let context = active_policy.parsed.parse_security_context(label.into())?;
775 let sid = active_policy.sid_table.security_context_to_sid(&context)?;
776 Ok(Some(sid))
777}
778
779#[cfg(test)]
780mod tests {
781 use super::*;
782 use crate::permission_check::PermissionCheckResult;
783 use crate::{
784 CommonFsNodePermission, DirPermission, FileClass, FilePermission, ForClass, KernelClass,
785 ProcessPermission,
786 };
787 use std::num::NonZeroU32;
788
789 const TESTSUITE_BINARY_POLICY: &[u8] = include_bytes!("../testdata/policies/selinux_testsuite");
790 const TESTS_BINARY_POLICY: &[u8] =
791 include_bytes!("../testdata/micro_policies/security_server_tests_policy");
792 const MINIMAL_BINARY_POLICY: &[u8] =
793 include_bytes!("../testdata/composite_policies/compiled/minimal_policy");
794
795 fn security_server_with_tests_policy() -> Arc<SecurityServer> {
796 let policy_bytes = TESTS_BINARY_POLICY.to_vec();
797 let security_server = SecurityServer::new_default();
798 assert_eq!(
799 Ok(()),
800 security_server.load_policy(policy_bytes).map_err(|e| format!("{:?}", e))
801 );
802 security_server
803 }
804
805 #[test]
806 fn compute_access_vector_allows_all() {
807 let security_server = SecurityServer::new_default();
808 let sid1 = InitialSid::Kernel.into();
809 let sid2 = InitialSid::Unlabeled.into();
810 assert_eq!(
811 security_server
812 .backend
813 .compute_access_decision(sid1, sid2, KernelClass::Process.into())
814 .allow,
815 AccessVector::ALL
816 );
817 }
818
819 #[test]
820 fn loaded_policy_can_be_retrieved() {
821 let security_server = security_server_with_tests_policy();
822 assert_eq!(TESTS_BINARY_POLICY, security_server.get_binary_policy().unwrap().as_ref());
823 }
824
825 #[test]
826 fn loaded_policy_is_validated() {
827 let not_really_a_policy = "not a real policy".as_bytes().to_vec();
828 let security_server = SecurityServer::new_default();
829 assert!(security_server.load_policy(not_really_a_policy.clone()).is_err());
830 }
831
832 #[test]
833 fn enforcing_mode_is_reported() {
834 let security_server = SecurityServer::new_default();
835 assert!(!security_server.is_enforcing());
836
837 security_server.set_enforcing(true);
838 assert!(security_server.is_enforcing());
839 }
840
841 #[test]
842 fn without_policy_conditional_booleans_are_empty() {
843 let security_server = SecurityServer::new_default();
844 assert!(security_server.conditional_booleans().is_empty());
845 }
846
847 #[test]
848 fn conditional_booleans_can_be_queried() {
849 let policy_bytes = TESTSUITE_BINARY_POLICY.to_vec();
850 let security_server = SecurityServer::new_default();
851 assert_eq!(
852 Ok(()),
853 security_server.load_policy(policy_bytes).map_err(|e| format!("{:?}", e))
854 );
855
856 let booleans = security_server.conditional_booleans();
857 assert!(!booleans.is_empty());
858 let boolean = booleans[0].as_str();
859
860 assert!(security_server.get_boolean("this_is_not_a_valid_boolean_name").is_err());
861 assert!(security_server.get_boolean(boolean).is_ok());
862 }
863
864 #[test]
865 fn conditional_booleans_can_be_changed() {
866 let policy_bytes = TESTSUITE_BINARY_POLICY.to_vec();
867 let security_server = SecurityServer::new_default();
868 assert_eq!(
869 Ok(()),
870 security_server.load_policy(policy_bytes).map_err(|e| format!("{:?}", e))
871 );
872
873 let booleans = security_server.conditional_booleans();
874 assert!(!booleans.is_empty());
875 let boolean = booleans[0].as_str();
876
877 let (active, pending) = security_server.get_boolean(boolean).unwrap();
878 assert_eq!(active, pending, "Initially active and pending values should match");
879
880 security_server.set_pending_boolean(boolean, !active).unwrap();
881 let (active, pending) = security_server.get_boolean(boolean).unwrap();
882 assert!(active != pending, "Before commit pending should differ from active");
883
884 security_server.commit_pending_booleans();
885 let (final_active, final_pending) = security_server.get_boolean(boolean).unwrap();
886 assert_eq!(final_active, pending, "Pending value should be active after commit");
887 assert_eq!(final_active, final_pending, "Active and pending are the same after commit");
888 }
889
890 #[test]
891 fn parse_security_context_no_policy() {
892 let security_server = SecurityServer::new_default();
893 let error = security_server
894 .security_context_to_sid(b"unconfined_u:unconfined_r:unconfined_t:s0".into())
895 .expect_err("expected error");
896 let error_string = format!("{:?}", error);
897 assert!(error_string.contains("no policy"));
898 }
899
900 #[test]
901 fn compute_new_fs_node_sid_no_defaults() {
902 let security_server = SecurityServer::new_default();
903 let policy_bytes =
904 include_bytes!("../testdata/micro_policies/file_no_defaults_policy").to_vec();
905 security_server.load_policy(policy_bytes).expect("binary policy loads");
906
907 let source_sid = security_server
908 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s1".into())
909 .expect("creating SID from security context should succeed");
910 let target_sid = security_server
911 .security_context_to_sid(b"file_u:object_r:file_t:s0".into())
912 .expect("creating SID from security context should succeed");
913
914 let computed_sid = security_server
915 .as_permission_check(&Default::default())
916 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
917 .expect("new sid computed");
918 let computed_context = security_server
919 .sid_to_security_context(computed_sid)
920 .expect("computed sid associated with context");
921
922 assert_eq!(computed_context, b"user_u:object_r:file_t:s0");
925 }
926
927 #[test]
928 fn compute_new_fs_node_sid_source_defaults() {
929 let security_server = SecurityServer::new_default();
930 let policy_bytes =
931 include_bytes!("../testdata/micro_policies/file_source_defaults_policy").to_vec();
932 security_server.load_policy(policy_bytes).expect("binary policy loads");
933
934 let source_sid = security_server
935 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s2:c0".into())
936 .expect("creating SID from security context should succeed");
937 let target_sid = security_server
938 .security_context_to_sid(b"file_u:object_r:file_t:s1-s3:c0".into())
939 .expect("creating SID from security context should succeed");
940
941 let computed_sid = security_server
942 .as_permission_check(&Default::default())
943 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
944 .expect("new sid computed");
945 let computed_context = security_server
946 .sid_to_security_context(computed_sid)
947 .expect("computed sid associated with context");
948
949 assert_eq!(computed_context, b"user_u:unconfined_r:unconfined_t:s0");
952 }
953
954 #[test]
955 fn compute_new_fs_node_sid_target_defaults() {
956 let security_server = SecurityServer::new_default();
957 let policy_bytes =
958 include_bytes!("../testdata/micro_policies/file_target_defaults_policy").to_vec();
959 security_server.load_policy(policy_bytes).expect("binary policy loads");
960
961 let source_sid = security_server
962 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s2:c0".into())
963 .expect("creating SID from security context should succeed");
964 let target_sid = security_server
965 .security_context_to_sid(b"file_u:object_r:file_t:s1-s3:c0".into())
966 .expect("creating SID from security context should succeed");
967
968 let computed_sid = security_server
969 .as_permission_check(&Default::default())
970 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
971 .expect("new sid computed");
972 let computed_context = security_server
973 .sid_to_security_context(computed_sid)
974 .expect("computed sid associated with context");
975
976 assert_eq!(computed_context, b"file_u:object_r:file_t:s0");
978 }
979
980 #[test]
981 fn compute_new_fs_node_sid_range_source_low_default() {
982 let security_server = SecurityServer::new_default();
983 let policy_bytes =
984 include_bytes!("../testdata/micro_policies/file_range_source_low_policy").to_vec();
985 security_server.load_policy(policy_bytes).expect("binary policy loads");
986
987 let source_sid = security_server
988 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s1:c0".into())
989 .expect("creating SID from security context should succeed");
990 let target_sid = security_server
991 .security_context_to_sid(b"file_u:object_r:file_t:s1".into())
992 .expect("creating SID from security context should succeed");
993
994 let computed_sid = security_server
995 .as_permission_check(&Default::default())
996 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
997 .expect("new sid computed");
998 let computed_context = security_server
999 .sid_to_security_context(computed_sid)
1000 .expect("computed sid associated with context");
1001
1002 assert_eq!(computed_context, b"user_u:object_r:file_t:s0");
1004 }
1005
1006 #[test]
1007 fn compute_new_fs_node_sid_range_source_low_high_default() {
1008 let security_server = SecurityServer::new_default();
1009 let policy_bytes =
1010 include_bytes!("../testdata/micro_policies/file_range_source_low_high_policy").to_vec();
1011 security_server.load_policy(policy_bytes).expect("binary policy loads");
1012
1013 let source_sid = security_server
1014 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s1:c0".into())
1015 .expect("creating SID from security context should succeed");
1016 let target_sid = security_server
1017 .security_context_to_sid(b"file_u:object_r:file_t:s1".into())
1018 .expect("creating SID from security context should succeed");
1019
1020 let computed_sid = security_server
1021 .as_permission_check(&Default::default())
1022 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
1023 .expect("new sid computed");
1024 let computed_context = security_server
1025 .sid_to_security_context(computed_sid)
1026 .expect("computed sid associated with context");
1027
1028 assert_eq!(computed_context, b"user_u:object_r:file_t:s0-s1:c0");
1030 }
1031
1032 #[test]
1033 fn compute_new_fs_node_sid_range_source_high_default() {
1034 let security_server = SecurityServer::new_default();
1035 let policy_bytes =
1036 include_bytes!("../testdata/micro_policies/file_range_source_high_policy").to_vec();
1037 security_server.load_policy(policy_bytes).expect("binary policy loads");
1038
1039 let source_sid = security_server
1040 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s1:c0".into())
1041 .expect("creating SID from security context should succeed");
1042 let target_sid = security_server
1043 .security_context_to_sid(b"file_u:object_r:file_t:s0".into())
1044 .expect("creating SID from security context should succeed");
1045
1046 let computed_sid = security_server
1047 .as_permission_check(&Default::default())
1048 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
1049 .expect("new sid computed");
1050 let computed_context = security_server
1051 .sid_to_security_context(computed_sid)
1052 .expect("computed sid associated with context");
1053
1054 assert_eq!(computed_context, b"user_u:object_r:file_t:s1:c0");
1056 }
1057
1058 #[test]
1059 fn compute_new_fs_node_sid_range_target_low_default() {
1060 let security_server = SecurityServer::new_default();
1061 let policy_bytes =
1062 include_bytes!("../testdata/micro_policies/file_range_target_low_policy").to_vec();
1063 security_server.load_policy(policy_bytes).expect("binary policy loads");
1064
1065 let source_sid = security_server
1066 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s1".into())
1067 .expect("creating SID from security context should succeed");
1068 let target_sid = security_server
1069 .security_context_to_sid(b"file_u:object_r:file_t:s0-s1:c0".into())
1070 .expect("creating SID from security context should succeed");
1071
1072 let computed_sid = security_server
1073 .as_permission_check(&Default::default())
1074 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
1075 .expect("new sid computed");
1076 let computed_context = security_server
1077 .sid_to_security_context(computed_sid)
1078 .expect("computed sid associated with context");
1079
1080 assert_eq!(computed_context, b"user_u:object_r:file_t:s0");
1082 }
1083
1084 #[test]
1085 fn compute_new_fs_node_sid_range_target_low_high_default() {
1086 let security_server = SecurityServer::new_default();
1087 let policy_bytes =
1088 include_bytes!("../testdata/micro_policies/file_range_target_low_high_policy").to_vec();
1089 security_server.load_policy(policy_bytes).expect("binary policy loads");
1090
1091 let source_sid = security_server
1092 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s1".into())
1093 .expect("creating SID from security context should succeed");
1094 let target_sid = security_server
1095 .security_context_to_sid(b"file_u:object_r:file_t:s0-s1:c0".into())
1096 .expect("creating SID from security context should succeed");
1097
1098 let computed_sid = security_server
1099 .as_permission_check(&Default::default())
1100 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
1101 .expect("new sid computed");
1102 let computed_context = security_server
1103 .sid_to_security_context(computed_sid)
1104 .expect("computed sid associated with context");
1105
1106 assert_eq!(computed_context, b"user_u:object_r:file_t:s0-s1:c0");
1108 }
1109
1110 #[test]
1111 fn compute_new_fs_node_sid_range_target_high_default() {
1112 let security_server = SecurityServer::new_default();
1113 let policy_bytes =
1114 include_bytes!("../testdata/micro_policies/file_range_target_high_policy").to_vec();
1115 security_server.load_policy(policy_bytes).expect("binary policy loads");
1116
1117 let source_sid = security_server
1118 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0".into())
1119 .expect("creating SID from security context should succeed");
1120 let target_sid = security_server
1121 .security_context_to_sid(b"file_u:object_r:file_t:s0-s1:c0".into())
1122 .expect("creating SID from security context should succeed");
1123
1124 let computed_sid = security_server
1125 .as_permission_check(&Default::default())
1126 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
1127 .expect("new sid computed");
1128 let computed_context = security_server
1129 .sid_to_security_context(computed_sid)
1130 .expect("computed sid associated with context");
1131
1132 assert_eq!(computed_context, b"user_u:object_r:file_t:s1:c0");
1134 }
1135
1136 #[test]
1137 fn compute_new_fs_node_sid_with_name() {
1138 let security_server = SecurityServer::new_default();
1139 let policy_bytes =
1140 include_bytes!("../testdata/composite_policies/compiled/type_transition_policy")
1141 .to_vec();
1142 security_server.load_policy(policy_bytes).expect("binary policy loads");
1143
1144 let source_sid = security_server
1145 .security_context_to_sid(b"source_u:source_r:source_t:s0".into())
1146 .expect("creating SID from security context should succeed");
1147 let target_sid = security_server
1148 .security_context_to_sid(b"target_u:object_r:target_t:s0".into())
1149 .expect("creating SID from security context should succeed");
1150
1151 const SPECIAL_FILE_NAME: &[u8] = b"special_file";
1152 let computed_sid = security_server
1153 .as_permission_check(&Default::default())
1154 .compute_new_fs_node_sid(
1155 source_sid,
1156 target_sid,
1157 FileClass::File.into(),
1158 SPECIAL_FILE_NAME.into(),
1159 )
1160 .expect("new sid computed");
1161 let computed_context = security_server
1162 .sid_to_security_context(computed_sid)
1163 .expect("computed sid associated with context");
1164
1165 assert_eq!(computed_context, b"source_u:object_r:special_transition_t:s0");
1167
1168 let computed_sid = security_server
1169 .as_permission_check(&Default::default())
1170 .compute_new_fs_node_sid(
1171 source_sid,
1172 target_sid,
1173 FileClass::ChrFile.into(),
1174 SPECIAL_FILE_NAME.into(),
1175 )
1176 .expect("new sid computed");
1177 let computed_context = security_server
1178 .sid_to_security_context(computed_sid)
1179 .expect("computed sid associated with context");
1180
1181 assert_eq!(computed_context, b"source_u:object_r:target_t:s0");
1184
1185 const OTHER_FILE_NAME: &[u8] = b"other_file";
1186 let computed_sid = security_server
1187 .as_permission_check(&Default::default())
1188 .compute_new_fs_node_sid(
1189 source_sid,
1190 target_sid,
1191 FileClass::File.into(),
1192 OTHER_FILE_NAME.into(),
1193 )
1194 .expect("new sid computed");
1195 let computed_context = security_server
1196 .sid_to_security_context(computed_sid)
1197 .expect("computed sid associated with context");
1198
1199 assert_eq!(computed_context, b"source_u:object_r:transition_t:s0");
1202 }
1203
1204 #[test]
1205 fn permissions_are_fresh_after_different_policy_load() {
1206 let minimal_bytes = MINIMAL_BINARY_POLICY.to_vec();
1207 let allow_fork_bytes =
1208 include_bytes!("../testdata/composite_policies/compiled/allow_fork_policy").to_vec();
1209 let context = b"source_u:object_r:source_t:s0:c0";
1210
1211 let security_server = SecurityServer::new_default();
1212 security_server.set_enforcing(true);
1213
1214 let local_cache = Default::default();
1215 let permission_check = security_server.as_permission_check(&local_cache);
1216
1217 assert_eq!(
1219 Ok(()),
1220 security_server.load_policy(minimal_bytes).map_err(|e| format!("{:?}", e))
1221 );
1222 let sid = security_server.security_context_to_sid(context.into()).unwrap();
1223
1224 assert!(!permission_check.has_permission(sid, sid, ProcessPermission::Fork).granted);
1226
1227 assert_eq!(
1229 Ok(()),
1230 security_server.load_policy(allow_fork_bytes).map_err(|e| format!("{:?}", e))
1231 );
1232
1233 let permission_check = security_server.as_permission_check(&local_cache);
1235
1236 assert!(permission_check.has_permission(sid, sid, ProcessPermission::Fork).granted);
1238 }
1239
1240 #[test]
1241 fn unknown_sids_are_effectively_unlabeled() {
1242 let with_unlabeled_access_domain_policy_bytes = include_bytes!(
1243 "../testdata/composite_policies/compiled/with_unlabeled_access_domain_policy"
1244 )
1245 .to_vec();
1246 let with_additional_domain_policy_bytes =
1247 include_bytes!("../testdata/composite_policies/compiled/with_additional_domain_policy")
1248 .to_vec();
1249 let allowed_type_context = b"source_u:object_r:allowed_t:s0:c0";
1250 let additional_type_context = b"source_u:object_r:additional_t:s0:c0";
1251
1252 let security_server = SecurityServer::new_default();
1253 security_server.set_enforcing(true);
1254
1255 assert_eq!(
1258 Ok(()),
1259 security_server
1260 .load_policy(with_unlabeled_access_domain_policy_bytes.clone())
1261 .map_err(|e| format!("{:?}", e))
1262 );
1263 let allowed_type_sid =
1264 security_server.security_context_to_sid(allowed_type_context.into()).unwrap();
1265 assert!(security_server.security_context_to_sid(additional_type_context.into()).is_err());
1266
1267 assert_eq!(
1270 Ok(()),
1271 security_server
1272 .load_policy(with_additional_domain_policy_bytes.clone())
1273 .map_err(|e| format!("{:?}", e))
1274 );
1275 let additional_type_sid =
1276 security_server.security_context_to_sid(additional_type_context.into()).unwrap();
1277 assert_eq!(
1278 allowed_type_sid,
1279 security_server.security_context_to_sid(allowed_type_context.into()).unwrap()
1280 );
1281
1282 let local_cache = Default::default();
1283 let permission_check = security_server.as_permission_check(&local_cache);
1284
1285 assert!(
1289 !permission_check
1290 .has_permission(additional_type_sid, allowed_type_sid, ProcessPermission::GetSched)
1291 .granted
1292 );
1293 assert!(
1294 !permission_check
1295 .has_permission(additional_type_sid, allowed_type_sid, ProcessPermission::SetSched)
1296 .granted
1297 );
1298 assert!(
1299 !permission_check
1300 .has_permission(allowed_type_sid, additional_type_sid, ProcessPermission::GetSched)
1301 .granted
1302 );
1303 assert!(
1304 !permission_check
1305 .has_permission(allowed_type_sid, additional_type_sid, ProcessPermission::SetSched)
1306 .granted
1307 );
1308
1309 assert_eq!(
1311 Ok(()),
1312 security_server
1313 .load_policy(with_unlabeled_access_domain_policy_bytes)
1314 .map_err(|e| format!("{:?}", e))
1315 );
1316
1317 let permission_check = security_server.as_permission_check(&local_cache);
1319
1320 assert!(
1324 permission_check
1325 .has_permission(allowed_type_sid, additional_type_sid, ProcessPermission::GetSched)
1326 .granted
1327 );
1328 assert!(
1329 !permission_check
1330 .has_permission(allowed_type_sid, additional_type_sid, ProcessPermission::SetSched)
1331 .granted
1332 );
1333
1334 assert!(
1339 !permission_check
1340 .has_permission(additional_type_sid, allowed_type_sid, ProcessPermission::GetSched)
1341 .granted
1342 );
1343 assert!(
1344 permission_check
1345 .has_permission(additional_type_sid, allowed_type_sid, ProcessPermission::SetSched)
1346 .granted
1347 );
1348
1349 assert!(security_server.sid_to_security_context(additional_type_sid).is_none());
1351
1352 assert_eq!(
1355 Ok(()),
1356 security_server
1357 .load_policy(with_additional_domain_policy_bytes)
1358 .map_err(|e| format!("{:?}", e))
1359 );
1360 assert_eq!(
1361 additional_type_context.to_vec(),
1362 security_server.sid_to_security_context(additional_type_sid).unwrap()
1363 );
1364 }
1365
1366 #[test]
1367 fn permission_check_permissive() {
1368 let security_server = security_server_with_tests_policy();
1369 security_server.set_enforcing(false);
1370 assert!(!security_server.is_enforcing());
1371
1372 let sid =
1373 security_server.security_context_to_sid("user0:object_r:type0:s0".into()).unwrap();
1374 let local_cache = Default::default();
1375 let permission_check = security_server.as_permission_check(&local_cache);
1376
1377 assert_eq!(
1380 permission_check.has_permission(sid, sid, ProcessPermission::Fork),
1381 PermissionCheckResult {
1382 granted: true,
1383 audit: false,
1384 permissive: false,
1385 todo_bug: None
1386 }
1387 );
1388
1389 let result = permission_check.has_permission(sid, sid, ProcessPermission::GetRlimit);
1393 assert_eq!(
1394 result,
1395 PermissionCheckResult { granted: false, audit: true, permissive: true, todo_bug: None }
1396 );
1397 assert!(result.permit());
1398
1399 let result = permission_check.has_permission(
1403 sid,
1404 sid,
1405 CommonFsNodePermission::GetAttr.for_class(FileClass::BlkFile),
1406 );
1407 assert_eq!(
1408 result,
1409 PermissionCheckResult { granted: false, audit: true, permissive: true, todo_bug: None }
1410 );
1411 assert!(result.permit());
1412 }
1413
1414 #[test]
1415 fn permission_check_enforcing() {
1416 let security_server = security_server_with_tests_policy();
1417 security_server.set_enforcing(true);
1418 assert!(security_server.is_enforcing());
1419
1420 let sid =
1421 security_server.security_context_to_sid("user0:object_r:type0:s0".into()).unwrap();
1422 let local_cache = Default::default();
1423 let permission_check = security_server.as_permission_check(&local_cache);
1424
1425 let result = permission_check.has_permission(sid, sid, ProcessPermission::Fork);
1427 assert_eq!(
1428 result,
1429 PermissionCheckResult {
1430 granted: true,
1431 audit: false,
1432 permissive: false,
1433 todo_bug: None
1434 }
1435 );
1436 assert!(result.permit());
1437
1438 let result = permission_check.has_permission(sid, sid, ProcessPermission::GetRlimit);
1441 assert_eq!(
1442 result,
1443 PermissionCheckResult {
1444 granted: false,
1445 audit: true,
1446 permissive: false,
1447 todo_bug: None
1448 }
1449 );
1450 assert!(!result.permit());
1451
1452 let result = permission_check.has_permission(
1455 sid,
1456 sid,
1457 CommonFsNodePermission::GetAttr.for_class(FileClass::BlkFile),
1458 );
1459 assert_eq!(
1460 result,
1461 PermissionCheckResult {
1462 granted: false,
1463 audit: true,
1464 permissive: false,
1465 todo_bug: None
1466 }
1467 );
1468 assert!(!result.permit());
1469 }
1470
1471 #[test]
1472 fn permissive_domain() {
1473 let security_server = security_server_with_tests_policy();
1474 security_server.set_enforcing(true);
1475 assert!(security_server.is_enforcing());
1476
1477 let permissive_sid = security_server
1478 .security_context_to_sid("user0:object_r:permissive_t:s0".into())
1479 .unwrap();
1480 let non_permissive_sid = security_server
1481 .security_context_to_sid("user0:object_r:non_permissive_t:s0".into())
1482 .unwrap();
1483
1484 let local_cache = Default::default();
1485 let permission_check = security_server.as_permission_check(&local_cache);
1486
1487 let result = permission_check.has_permission(
1489 permissive_sid,
1490 permissive_sid,
1491 ProcessPermission::GetSched,
1492 );
1493 assert_eq!(
1494 result,
1495 PermissionCheckResult { granted: true, audit: false, permissive: true, todo_bug: None }
1496 );
1497 assert!(result.permit());
1498 let result = permission_check.has_permission(
1499 non_permissive_sid,
1500 non_permissive_sid,
1501 ProcessPermission::GetSched,
1502 );
1503 assert_eq!(
1504 result,
1505 PermissionCheckResult {
1506 granted: true,
1507 audit: false,
1508 permissive: false,
1509 todo_bug: None
1510 }
1511 );
1512 assert!(result.permit());
1513
1514 let result = permission_check.has_permission(
1517 permissive_sid,
1518 non_permissive_sid,
1519 ProcessPermission::GetSched,
1520 );
1521 assert_eq!(
1522 result,
1523 PermissionCheckResult { granted: false, audit: true, permissive: true, todo_bug: None }
1524 );
1525 assert!(result.permit());
1526 let result = permission_check.has_permission(
1527 non_permissive_sid,
1528 permissive_sid,
1529 ProcessPermission::GetSched,
1530 );
1531 assert_eq!(
1532 result,
1533 PermissionCheckResult {
1534 granted: false,
1535 audit: true,
1536 permissive: false,
1537 todo_bug: None
1538 }
1539 );
1540 assert!(!result.permit());
1541
1542 let result = permission_check.has_permission(
1547 permissive_sid,
1548 non_permissive_sid,
1549 CommonFsNodePermission::GetAttr.for_class(FileClass::BlkFile),
1550 );
1551 assert_eq!(
1552 result,
1553 PermissionCheckResult { granted: false, audit: true, permissive: true, todo_bug: None }
1554 );
1555 assert!(result.permit());
1556 let result = permission_check.has_permission(
1557 non_permissive_sid,
1558 non_permissive_sid,
1559 CommonFsNodePermission::GetAttr.for_class(FileClass::BlkFile),
1560 );
1561 assert_eq!(
1562 result,
1563 PermissionCheckResult {
1564 granted: false,
1565 audit: true,
1566 permissive: false,
1567 todo_bug: None
1568 }
1569 );
1570 assert!(!result.permit());
1571 }
1572
1573 #[test]
1574 fn auditallow_and_dontaudit() {
1575 let security_server = security_server_with_tests_policy();
1576 security_server.set_enforcing(true);
1577 assert!(security_server.is_enforcing());
1578
1579 let audit_sid = security_server
1580 .security_context_to_sid("user0:object_r:test_audit_t:s0".into())
1581 .unwrap();
1582
1583 let local_cache = Default::default();
1584 let permission_check = security_server.as_permission_check(&local_cache);
1585
1586 let result = permission_check.has_permission(audit_sid, audit_sid, ProcessPermission::Fork);
1588 assert_eq!(
1589 result,
1590 PermissionCheckResult { granted: true, audit: true, permissive: false, todo_bug: None }
1591 );
1592 assert!(result.permit());
1593
1594 let result =
1596 permission_check.has_permission(audit_sid, audit_sid, ProcessPermission::SetSched);
1597 assert_eq!(
1598 result,
1599 PermissionCheckResult {
1600 granted: true,
1601 audit: false,
1602 permissive: false,
1603 todo_bug: None
1604 }
1605 );
1606 assert!(result.permit());
1607
1608 let result =
1610 permission_check.has_permission(audit_sid, audit_sid, ProcessPermission::GetSched);
1611 assert_eq!(
1612 result,
1613 PermissionCheckResult {
1614 granted: false,
1615 audit: false,
1616 permissive: false,
1617 todo_bug: None
1618 }
1619 );
1620 assert!(!result.permit());
1621
1622 let result =
1624 permission_check.has_permission(audit_sid, audit_sid, ProcessPermission::GetPgid);
1625 assert_eq!(
1626 result,
1627 PermissionCheckResult {
1628 granted: false,
1629 audit: true,
1630 permissive: false,
1631 todo_bug: None
1632 }
1633 );
1634 assert!(!result.permit());
1635 }
1636
1637 #[test]
1638 fn access_checks_with_exceptions_config() {
1639 const EXCEPTIONS_CONFIG: &[&str] = &[
1640 "todo_deny b/001 test_exception_source_t test_exception_target_t file",
1642 "todo_deny b/002 test_exception_other_t test_exception_target_t chr_file",
1643 "todo_deny b/003 test_exception_source_t test_exception_other_t anon_inode",
1644 "todo_deny b/004 test_exception_permissive_t test_exception_target_t file",
1645 "todo_permissive b/005 test_exception_todo_permissive_t",
1646 "todo_deny b/101 test_undefined_source_t test_exception_target_t file",
1648 "todo_deny b/102 test_exception_source_t test_undefined_target_t file",
1649 "todo_permissive b/103 test_undefined_source_t",
1650 ];
1651 let exceptions_config = EXCEPTIONS_CONFIG.iter().map(|x| String::from(*x)).collect();
1652 let security_server = SecurityServer::new(String::new(), exceptions_config);
1653 security_server.set_enforcing(true);
1654
1655 const EXCEPTIONS_POLICY: &[u8] =
1656 include_bytes!("../testdata/composite_policies/compiled/exceptions_config_policy");
1657 assert!(security_server.load_policy(EXCEPTIONS_POLICY.into()).is_ok());
1658
1659 let source_sid = security_server
1660 .security_context_to_sid("test_exception_u:object_r:test_exception_source_t:s0".into())
1661 .unwrap();
1662 let target_sid = security_server
1663 .security_context_to_sid("test_exception_u:object_r:test_exception_target_t:s0".into())
1664 .unwrap();
1665 let other_sid = security_server
1666 .security_context_to_sid("test_exception_u:object_r:test_exception_other_t:s0".into())
1667 .unwrap();
1668 let permissive_sid = security_server
1669 .security_context_to_sid(
1670 "test_exception_u:object_r:test_exception_permissive_t:s0".into(),
1671 )
1672 .unwrap();
1673 let unmatched_sid = security_server
1674 .security_context_to_sid(
1675 "test_exception_u:object_r:test_exception_unmatched_t:s0".into(),
1676 )
1677 .unwrap();
1678 let todo_permissive_sid = security_server
1679 .security_context_to_sid(
1680 "test_exception_u:object_r:test_exception_todo_permissive_t:s0".into(),
1681 )
1682 .unwrap();
1683
1684 let local_cache = Default::default();
1685 let permission_check = security_server.as_permission_check(&local_cache);
1686
1687 let result =
1689 permission_check.has_permission(source_sid, target_sid, ProcessPermission::GetPgid);
1690 assert_eq!(
1691 result,
1692 PermissionCheckResult {
1693 granted: false,
1694 audit: true,
1695 permissive: false,
1696 todo_bug: None
1697 }
1698 );
1699 assert!(!result.permit());
1700
1701 let result =
1703 permission_check.has_permission(source_sid, target_sid, FilePermission::Entrypoint);
1704 assert_eq!(
1705 result,
1706 PermissionCheckResult {
1707 granted: true,
1708 audit: true,
1709 permissive: false,
1710 todo_bug: Some(NonZeroU32::new(1).unwrap())
1711 }
1712 );
1713 assert!(result.permit());
1714
1715 let result =
1717 permission_check.has_permission(source_sid, target_sid, FilePermission::ExecuteNoTrans);
1718 assert_eq!(
1719 result,
1720 PermissionCheckResult {
1721 granted: true,
1722 audit: false,
1723 permissive: false,
1724 todo_bug: None,
1725 }
1726 );
1727 assert!(result.permit());
1728
1729 let result =
1731 permission_check.has_permission(other_sid, target_sid, FilePermission::Entrypoint);
1732 assert_eq!(
1733 result,
1734 PermissionCheckResult {
1735 granted: false,
1736 audit: true,
1737 permissive: false,
1738 todo_bug: None
1739 }
1740 );
1741 assert!(!result.permit());
1742
1743 let result = permission_check.has_permission(
1745 other_sid,
1746 target_sid,
1747 CommonFsNodePermission::Read.for_class(FileClass::ChrFile),
1748 );
1749 assert_eq!(
1750 result,
1751 PermissionCheckResult {
1752 granted: true,
1753 audit: true,
1754 permissive: false,
1755 todo_bug: Some(NonZeroU32::new(2).unwrap())
1756 }
1757 );
1758 assert!(result.permit());
1759
1760 let result =
1762 permission_check.has_permission(source_sid, unmatched_sid, FilePermission::Entrypoint);
1763 assert_eq!(
1764 result,
1765 PermissionCheckResult {
1766 granted: false,
1767 audit: true,
1768 permissive: false,
1769 todo_bug: None
1770 }
1771 );
1772 assert!(!result.permit());
1773
1774 let result =
1776 permission_check.has_permission(unmatched_sid, target_sid, FilePermission::Entrypoint);
1777 assert_eq!(
1778 result,
1779 PermissionCheckResult {
1780 granted: false,
1781 audit: true,
1782 permissive: false,
1783 todo_bug: None
1784 }
1785 );
1786 assert!(!result.permit());
1787
1788 let result =
1790 permission_check.has_permission(permissive_sid, target_sid, FilePermission::Entrypoint);
1791 assert_eq!(
1792 result,
1793 PermissionCheckResult {
1794 granted: true,
1795 audit: true,
1796 permissive: true,
1797 todo_bug: Some(NonZeroU32::new(4).unwrap())
1798 }
1799 );
1800 assert!(result.permit());
1801
1802 let result = permission_check.has_permission(
1805 todo_permissive_sid,
1806 target_sid,
1807 FilePermission::Entrypoint,
1808 );
1809 assert_eq!(
1810 result,
1811 PermissionCheckResult {
1812 granted: true,
1813 audit: true,
1814 permissive: false,
1815 todo_bug: Some(NonZeroU32::new(5).unwrap())
1816 }
1817 );
1818 assert!(result.permit());
1819 let result = permission_check.has_permission(
1820 todo_permissive_sid,
1821 todo_permissive_sid,
1822 FilePermission::Entrypoint,
1823 );
1824 assert_eq!(
1825 result,
1826 PermissionCheckResult {
1827 granted: true,
1828 audit: true,
1829 permissive: false,
1830 todo_bug: Some(NonZeroU32::new(5).unwrap())
1831 }
1832 );
1833 assert!(result.permit());
1834 let result = permission_check.has_permission(
1835 todo_permissive_sid,
1836 target_sid,
1837 FilePermission::Entrypoint,
1838 );
1839 assert_eq!(
1840 result,
1841 PermissionCheckResult {
1842 granted: true,
1843 audit: true,
1844 permissive: false,
1845 todo_bug: Some(NonZeroU32::new(5).unwrap())
1846 }
1847 );
1848 assert!(result.permit());
1849 }
1850
1851 #[test]
1852 fn handle_unknown() {
1853 let security_server = security_server_with_tests_policy();
1854
1855 let sid = security_server
1856 .security_context_to_sid("user0:object_r:type0:s0".into())
1857 .expect("Resolve Context to SID");
1858
1859 const REJECT_POLICY: &[u8] =
1863 include_bytes!("../testdata/composite_policies/compiled/handle_unknown_policy-reject");
1864 assert!(security_server.load_policy(REJECT_POLICY.to_vec()).is_err());
1865
1866 security_server.set_enforcing(true);
1867
1868 const DENY_POLICY: &[u8] =
1870 include_bytes!("../testdata/composite_policies/compiled/handle_unknown_policy-deny");
1871 assert!(security_server.load_policy(DENY_POLICY.to_vec()).is_ok());
1872 let local_cache = Default::default();
1873 let permission_check = security_server.as_permission_check(&local_cache);
1874
1875 let result = permission_check.has_permission(sid, sid, ProcessPermission::GetSched);
1877 assert_eq!(
1878 result,
1879 PermissionCheckResult {
1880 granted: false,
1881 audit: true,
1882 permissive: false,
1883 todo_bug: None
1884 }
1885 );
1886 assert!(!result.permit());
1887 let result = permission_check.has_permission(sid, sid, DirPermission::AddName);
1888 assert_eq!(
1889 result,
1890 PermissionCheckResult {
1891 granted: false,
1892 audit: true,
1893 permissive: false,
1894 todo_bug: None
1895 }
1896 );
1897 assert!(!result.permit());
1898
1899 let result = permission_check.has_permission(sid, sid, DirPermission::Search);
1901 assert_eq!(
1902 result,
1903 PermissionCheckResult {
1904 granted: true,
1905 audit: false,
1906 permissive: false,
1907 todo_bug: None
1908 }
1909 );
1910 assert!(result.permit());
1911 let result = permission_check.has_permission(sid, sid, DirPermission::Reparent);
1912 assert_eq!(
1913 result,
1914 PermissionCheckResult {
1915 granted: false,
1916 audit: true,
1917 permissive: false,
1918 todo_bug: None
1919 }
1920 );
1921 assert!(!result.permit());
1922
1923 const ALLOW_POLICY: &[u8] =
1925 include_bytes!("../testdata/composite_policies/compiled/handle_unknown_policy-allow");
1926 assert!(security_server.load_policy(ALLOW_POLICY.to_vec()).is_ok());
1927 let local_cache2 = Default::default();
1928 let permission_check = security_server.as_permission_check(&local_cache2);
1929
1930 let result = permission_check.has_permission(sid, sid, ProcessPermission::GetSched);
1932 assert_eq!(
1933 result,
1934 PermissionCheckResult {
1935 granted: true,
1936 audit: false,
1937 permissive: false,
1938 todo_bug: None
1939 }
1940 );
1941 assert!(result.permit());
1942 let result = permission_check.has_permission(sid, sid, DirPermission::AddName);
1943 assert_eq!(
1944 result,
1945 PermissionCheckResult {
1946 granted: true,
1947 audit: false,
1948 permissive: false,
1949 todo_bug: None
1950 }
1951 );
1952 assert!(result.permit());
1953
1954 let result = permission_check.has_permission(sid, sid, DirPermission::Search);
1956 assert_eq!(
1957 result,
1958 PermissionCheckResult {
1959 granted: true,
1960 audit: false,
1961 permissive: false,
1962 todo_bug: None
1963 }
1964 );
1965 assert!(result.permit());
1966
1967 let result = permission_check.has_permission(sid, sid, DirPermission::Reparent);
1968 assert_eq!(
1969 result,
1970 PermissionCheckResult {
1971 granted: false,
1972 audit: true,
1973 permissive: false,
1974 todo_bug: None
1975 }
1976 );
1977 assert!(!result.permit());
1978 }
1979}