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