1use crate::access_vector_cache::{
6 CacheStats, HasCacheStats, Manager as AvcManager, Query, QueryMut, Reset,
7};
8use crate::exceptions_config::ExceptionsConfig;
9use crate::permission_check::PermissionCheck;
10use crate::policy::metadata::HandleUnknown;
11use crate::policy::parser::ByValue;
12use crate::policy::{
13 parse_policy_by_value, AccessDecision, AccessVector, AccessVectorComputer, ClassId,
14 ClassPermissionId, FsUseLabelAndType, FsUseType, IoctlAccessDecision, Policy,
15};
16use crate::sid_table::SidTable;
17use crate::sync::Mutex;
18use crate::{
19 ClassPermission, FileSystemLabel, FileSystemLabelingScheme, FileSystemMountOptions,
20 FsNodeClass, InitialSid, KernelClass, KernelPermission, NullessByteStr, ObjectClass,
21 SeLinuxStatus, SeLinuxStatusPublisher, SecurityId,
22};
23
24use crate::FileSystemMountSids;
25use anyhow::Context as _;
26use std::collections::HashMap;
27use std::ops::DerefMut;
28use std::sync::Arc;
29
30const ROOT_PATH: &'static str = "/";
31
32struct ActivePolicy {
33 parsed: Arc<Policy<ByValue<Vec<u8>>>>,
35
36 binary: Vec<u8>,
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 enforcing: bool,
92
93 policy_change_count: u32,
97}
98
99impl SecurityServerState {
100 fn deny_unknown(&self) -> bool {
101 self.active_policy
102 .as_ref()
103 .map_or(true, |p| p.parsed.handle_unknown() != HandleUnknown::Allow)
104 }
105 fn reject_unknown(&self) -> bool {
106 self.active_policy
107 .as_ref()
108 .map_or(false, |p| p.parsed.handle_unknown() == HandleUnknown::Reject)
109 }
110
111 fn expect_active_policy(&self) -> &ActivePolicy {
112 &self.active_policy.as_ref().expect("policy should be loaded")
113 }
114
115 fn expect_active_policy_mut(&mut self) -> &mut ActivePolicy {
116 self.active_policy.as_mut().expect("policy should be loaded")
117 }
118}
119
120pub struct SecurityServer {
121 avc_manager: AvcManager<SecurityServer>,
126
127 state: Mutex<SecurityServerState>,
129
130 exceptions_config: String,
132}
133
134impl SecurityServer {
135 pub fn new() -> Arc<Self> {
136 Self::new_with_exceptions(String::new())
137 }
138
139 pub fn new_with_exceptions(exceptions_config: String) -> Arc<Self> {
140 let avc_manager = AvcManager::new();
141 let state = Mutex::new(SecurityServerState {
142 active_policy: None,
143 booleans: SeLinuxBooleans::default(),
144 status_publisher: None,
145 enforcing: false,
146 policy_change_count: 0,
147 });
148
149 let security_server = Arc::new(Self { avc_manager, state, exceptions_config });
150
151 security_server.as_ref().avc_manager.set_security_server(Arc::downgrade(&security_server));
154
155 security_server
156 }
157
158 pub fn as_permission_check<'a>(self: &'a Self) -> PermissionCheck<'a> {
161 PermissionCheck::new(self, self.avc_manager.get_shared_cache())
162 }
163
164 pub fn security_context_to_sid(
168 &self,
169 security_context: NullessByteStr<'_>,
170 ) -> Result<SecurityId, anyhow::Error> {
171 let mut locked_state = self.state.lock();
172 let active_policy = locked_state
173 .active_policy
174 .as_mut()
175 .ok_or_else(|| anyhow::anyhow!("no policy loaded"))?;
176 let context = active_policy
177 .parsed
178 .parse_security_context(security_context)
179 .map_err(anyhow::Error::from)?;
180 active_policy.sid_table.security_context_to_sid(&context).map_err(anyhow::Error::from)
181 }
182
183 pub fn sid_to_security_context(&self, sid: SecurityId) -> Option<Vec<u8>> {
188 let locked_state = self.state.lock();
189 let active_policy = locked_state.active_policy.as_ref()?;
190 let context = active_policy.sid_table.try_sid_to_security_context(sid)?;
191 Some(active_policy.parsed.serialize_security_context(context))
192 }
193
194 pub fn load_policy(&self, binary_policy: Vec<u8>) -> Result<(), anyhow::Error> {
196 let (parsed, binary) = parse_policy_by_value(binary_policy)?;
199 let parsed = Arc::new(parsed.validate()?);
200
201 let exceptions = ExceptionsConfig::new(&parsed, &self.exceptions_config)?;
202
203 self.with_state_and_update_status(|state| {
205 let sid_table = if let Some(previous_active_policy) = &state.active_policy {
206 SidTable::new_from_previous(parsed.clone(), &previous_active_policy.sid_table)
207 } else {
208 SidTable::new(parsed.clone())
209 };
210
211 state.booleans.reset(
214 parsed
215 .conditional_booleans()
216 .iter()
217 .map(|(name, value)| (String::from_utf8((*name).to_vec()).unwrap(), *value))
219 .collect(),
220 );
221
222 state.active_policy = Some(ActivePolicy { parsed, binary, sid_table, exceptions });
223 state.policy_change_count += 1;
224 });
225
226 self.avc_manager.reset();
229
230 Ok(())
231 }
232
233 pub fn get_binary_policy(&self) -> Vec<u8> {
235 self.state.lock().active_policy.as_ref().map_or(Vec::new(), |p| p.binary.clone())
236 }
237
238 pub fn has_policy(&self) -> bool {
240 self.state.lock().active_policy.is_some()
241 }
242
243 pub fn set_enforcing(&self, enforcing: bool) {
245 self.with_state_and_update_status(|state| state.enforcing = enforcing);
246 }
247
248 pub fn is_enforcing(&self) -> bool {
249 self.state.lock().enforcing
250 }
251
252 pub fn deny_unknown(&self) -> bool {
255 self.state.lock().deny_unknown()
256 }
257
258 pub fn reject_unknown(&self) -> bool {
261 self.state.lock().reject_unknown()
262 }
263
264 pub fn conditional_booleans(&self) -> Vec<String> {
267 self.state.lock().booleans.names()
268 }
269
270 pub fn get_boolean(&self, name: &str) -> Result<(bool, bool), ()> {
272 self.state.lock().booleans.get(name)
273 }
274
275 pub fn set_pending_boolean(&self, name: &str, value: bool) -> Result<(), ()> {
277 self.state.lock().booleans.set_pending(name, value)
278 }
279
280 pub fn commit_pending_booleans(&self) {
282 self.with_state_and_update_status(|state| {
284 state.booleans.commit_pending();
285 state.policy_change_count += 1;
286 });
287 }
288
289 pub fn avc_cache_stats(&self) -> CacheStats {
291 self.avc_manager.get_shared_cache().cache_stats()
292 }
293
294 pub fn class_names(&self) -> Result<Vec<Vec<u8>>, ()> {
296 let locked_state = self.state.lock();
297 let names = locked_state
298 .expect_active_policy()
299 .parsed
300 .classes()
301 .iter()
302 .map(|class| class.class_name.to_vec())
303 .collect();
304 Ok(names)
305 }
306
307 pub fn class_id_by_name(&self, name: &str) -> Result<ClassId, ()> {
309 let locked_state = self.state.lock();
310 Ok(locked_state
311 .expect_active_policy()
312 .parsed
313 .classes()
314 .iter()
315 .find(|class| class.class_name == name.as_bytes())
316 .ok_or(())?
317 .class_id)
318 }
319
320 pub fn class_permissions_by_name(
324 &self,
325 name: &str,
326 ) -> Result<Vec<(ClassPermissionId, Vec<u8>)>, ()> {
327 let locked_state = self.state.lock();
328 locked_state.expect_active_policy().parsed.find_class_permissions_by_name(name)
329 }
330
331 pub fn resolve_fs_label(
335 &self,
336 fs_type: NullessByteStr<'_>,
337 mount_options: &FileSystemMountOptions,
338 ) -> FileSystemLabel {
339 let mut locked_state = self.state.lock();
340 let active_policy = locked_state.expect_active_policy_mut();
341
342 let mount_sids = FileSystemMountSids {
343 context: sid_from_mount_option(active_policy, &mount_options.context),
344 fs_context: sid_from_mount_option(active_policy, &mount_options.fs_context),
345 def_context: sid_from_mount_option(active_policy, &mount_options.def_context),
346 root_context: sid_from_mount_option(active_policy, &mount_options.root_context),
347 };
348 if let Some(mountpoint_sid) = mount_sids.context {
349 FileSystemLabel {
353 sid: mount_sids.fs_context.unwrap_or(mountpoint_sid),
354 scheme: FileSystemLabelingScheme::Mountpoint { sid: mountpoint_sid },
355 mount_sids,
356 }
357 } else if let Some(FsUseLabelAndType { context, use_type }) =
358 active_policy.parsed.fs_use_label_and_type(fs_type)
359 {
360 let fs_sid_from_policy =
362 active_policy.sid_table.security_context_to_sid(&context).unwrap();
363 let fs_sid = mount_sids.fs_context.unwrap_or(fs_sid_from_policy);
364 FileSystemLabel {
365 sid: fs_sid,
366 scheme: FileSystemLabelingScheme::FsUse {
367 fs_use_type: use_type,
368 computed_def_sid: mount_sids
369 .def_context
370 .unwrap_or_else(|| SecurityId::initial(InitialSid::File)),
371 },
372 mount_sids,
373 }
374 } else if let Some(context) =
375 active_policy.parsed.genfscon_label_for_fs_and_path(fs_type, ROOT_PATH.into(), None)
376 {
377 let genfscon_sid = active_policy.sid_table.security_context_to_sid(&context).unwrap();
379 let fs_sid = mount_sids.fs_context.unwrap_or(genfscon_sid);
380 FileSystemLabel { sid: fs_sid, scheme: FileSystemLabelingScheme::GenFsCon, mount_sids }
381 } else {
382 FileSystemLabel {
384 sid: mount_sids
385 .fs_context
386 .unwrap_or_else(|| SecurityId::initial(InitialSid::Unlabeled)),
387 scheme: FileSystemLabelingScheme::FsUse {
388 fs_use_type: FsUseType::Xattr,
389 computed_def_sid: mount_sids
390 .def_context
391 .unwrap_or_else(|| SecurityId::initial(InitialSid::File)),
392 },
393 mount_sids,
394 }
395 }
396 }
397
398 pub fn genfscon_label_for_fs_and_path(
402 &self,
403 fs_type: NullessByteStr<'_>,
404 node_path: NullessByteStr<'_>,
405 class_id: Option<ClassId>,
406 ) -> Option<SecurityId> {
407 let mut locked_state = self.state.lock();
408 let active_policy = locked_state.expect_active_policy_mut();
409 let security_context = active_policy.parsed.genfscon_label_for_fs_and_path(
410 fs_type,
411 node_path.into(),
412 class_id,
413 )?;
414 Some(active_policy.sid_table.security_context_to_sid(&security_context).unwrap())
415 }
416
417 pub fn is_bounded_by(&self, bounded_sid: SecurityId, parent_sid: SecurityId) -> bool {
422 let locked_state = self.state.lock();
423 let active_policy = locked_state.expect_active_policy();
424 let bounded_type = active_policy.sid_table.sid_to_security_context(bounded_sid).type_();
425 let parent_type = active_policy.sid_table.sid_to_security_context(parent_sid).type_();
426 active_policy.parsed.is_bounded_by(bounded_type, parent_type)
427 }
428
429 pub fn set_status_publisher(&self, status_holder: Box<dyn SeLinuxStatusPublisher>) {
436 self.with_state_and_update_status(|state| {
437 assert!(state.status_publisher.is_none());
438 state.status_publisher = Some(status_holder);
439 });
440 }
441
442 #[allow(dead_code)]
446 pub(super) fn get_shared_avc(&self) -> &impl Query {
447 self.avc_manager.get_shared_cache()
448 }
449
450 #[allow(dead_code)]
456 pub(super) fn new_thread_local_avc(&self) -> impl QueryMut {
457 self.avc_manager.new_thread_local_cache()
458 }
459
460 fn with_state_and_update_status(&self, f: impl FnOnce(&mut SecurityServerState)) {
463 let mut locked_state = self.state.lock();
464 f(locked_state.deref_mut());
465 let new_value = SeLinuxStatus {
466 is_enforcing: locked_state.enforcing,
467 change_count: locked_state.policy_change_count,
468 deny_unknown: locked_state.deny_unknown(),
469 };
470 if let Some(status_publisher) = &mut locked_state.status_publisher {
471 status_publisher.set_status(new_value);
472 }
473 }
474
475 pub fn compute_new_sid(
480 &self,
481 source_sid: SecurityId,
482 target_sid: SecurityId,
483 target_class: KernelClass,
484 ) -> Result<SecurityId, anyhow::Error> {
485 let mut locked_state = self.state.lock();
486 let active_policy = locked_state.expect_active_policy_mut();
487
488 let source_context = active_policy.sid_table.sid_to_security_context(source_sid);
490 let target_context = active_policy.sid_table.sid_to_security_context(target_sid);
491
492 active_policy
493 .sid_table
494 .security_context_to_sid(&active_policy.parsed.new_security_context(
495 source_context,
496 target_context,
497 &target_class,
498 ))
499 .map_err(anyhow::Error::from)
500 .context("computing new security context from policy")
501 }
502}
503
504impl Query for SecurityServer {
505 fn compute_access_decision(
506 &self,
507 source_sid: SecurityId,
508 target_sid: SecurityId,
509 target_class: ObjectClass,
510 ) -> AccessDecision {
511 let locked_state = self.state.lock();
512
513 let active_policy = match &locked_state.active_policy {
514 Some(active_policy) => active_policy,
515 None => return AccessDecision::allow(AccessVector::ALL),
517 };
518
519 let source_context = active_policy.sid_table.sid_to_security_context(source_sid);
520 let target_context = active_policy.sid_table.sid_to_security_context(target_sid);
521
522 match target_class {
523 ObjectClass::System(target_class) => {
524 let mut decision = active_policy.parsed.compute_access_decision(
525 &source_context,
526 &target_context,
527 &target_class,
528 );
529 decision.todo_bug = active_policy.exceptions.lookup(
530 source_context.type_(),
531 target_context.type_(),
532 target_class,
533 );
534 decision
535 }
536 ObjectClass::Custom(target_class) => active_policy
537 .parsed
538 .compute_access_decision_custom(&source_context, &target_context, &target_class),
539 }
540 }
541
542 fn compute_new_fs_node_sid(
543 &self,
544 source_sid: SecurityId,
545 target_sid: SecurityId,
546 fs_node_class: FsNodeClass,
547 ) -> Result<SecurityId, anyhow::Error> {
548 let mut locked_state = self.state.lock();
549
550 let active_policy = locked_state.active_policy.as_mut().expect("Policy loaded");
552
553 let source_context = active_policy.sid_table.sid_to_security_context(source_sid);
554 let target_context = active_policy.sid_table.sid_to_security_context(target_sid);
555
556 let new_file_context = active_policy.parsed.new_file_security_context(
558 source_context,
559 target_context,
560 &fs_node_class,
561 );
562
563 active_policy
564 .sid_table
565 .security_context_to_sid(&new_file_context)
566 .map_err(anyhow::Error::from)
567 .context("computing new file security context from policy")
568 }
569
570 fn compute_new_fs_node_sid_with_name(
571 &self,
572 source_sid: SecurityId,
573 target_sid: SecurityId,
574 fs_node_class: FsNodeClass,
575 fs_node_name: NullessByteStr<'_>,
576 ) -> Option<SecurityId> {
577 let mut locked_state = self.state.lock();
578
579 let active_policy = locked_state.active_policy.as_mut().expect("Policy loaded");
581
582 let source_context = active_policy.sid_table.sid_to_security_context(source_sid);
583 let target_context = active_policy.sid_table.sid_to_security_context(target_sid);
584
585 let new_file_context = active_policy.parsed.new_file_security_context_by_name(
586 source_context,
587 target_context,
588 &fs_node_class,
589 fs_node_name,
590 )?;
591
592 active_policy.sid_table.security_context_to_sid(&new_file_context).ok()
593 }
594
595 fn compute_ioctl_access_decision(
596 &self,
597 source_sid: SecurityId,
598 target_sid: SecurityId,
599 target_class: ObjectClass,
600 ioctl_prefix: u8,
601 ) -> IoctlAccessDecision {
602 let locked_state = self.state.lock();
603
604 let active_policy = match &locked_state.active_policy {
605 Some(active_policy) => active_policy,
606 None => return IoctlAccessDecision::ALLOW_ALL,
608 };
609
610 let source_context = active_policy.sid_table.sid_to_security_context(source_sid);
611 let target_context = active_policy.sid_table.sid_to_security_context(target_sid);
612
613 match target_class {
614 ObjectClass::System(target_class) => {
615 active_policy.parsed.compute_ioctl_access_decision(
616 &source_context,
617 &target_context,
618 &target_class,
619 ioctl_prefix,
620 )
621 }
622 ObjectClass::Custom(target_class) => {
623 active_policy.parsed.compute_ioctl_access_decision_custom(
624 &source_context,
625 &target_context,
626 &target_class,
627 ioctl_prefix,
628 )
629 }
630 }
631 }
632}
633
634impl AccessVectorComputer for SecurityServer {
635 fn access_vector_from_permissions<
636 P: ClassPermission + Into<KernelPermission> + Clone + 'static,
637 >(
638 &self,
639 permissions: &[P],
640 ) -> Option<AccessVector> {
641 match &self.state.lock().active_policy {
642 Some(policy) => policy.parsed.access_vector_from_permissions(permissions),
643 None => Some(AccessVector::NONE),
644 }
645 }
646}
647
648fn sid_from_mount_option(
651 active_policy: &mut ActivePolicy,
652 mount_option: &Option<Vec<u8>>,
653) -> Option<SecurityId> {
654 if let Some(label) = mount_option.as_ref() {
655 Some(
656 if let Some(context) = active_policy.parsed.parse_security_context(label.into()).ok() {
657 active_policy.sid_table.security_context_to_sid(&context).unwrap()
658 } else {
659 SecurityId::initial(InitialSid::Unlabeled)
661 },
662 )
663 } else {
664 None
665 }
666}
667
668#[cfg(test)]
669mod tests {
670 use super::*;
671 use crate::permission_check::PermissionCheckResult;
672 use crate::{
673 CommonFsNodePermission, DirPermission, FileClass, FilePermission, ProcessPermission,
674 };
675 use std::num::NonZeroU64;
676
677 const TESTSUITE_BINARY_POLICY: &[u8] = include_bytes!("../testdata/policies/selinux_testsuite");
678 const TESTS_BINARY_POLICY: &[u8] =
679 include_bytes!("../testdata/micro_policies/security_server_tests_policy.pp");
680 const MINIMAL_BINARY_POLICY: &[u8] =
681 include_bytes!("../testdata/composite_policies/compiled/minimal_policy.pp");
682
683 fn security_server_with_tests_policy() -> Arc<SecurityServer> {
684 let policy_bytes = TESTS_BINARY_POLICY.to_vec();
685 let security_server = SecurityServer::new();
686 assert_eq!(
687 Ok(()),
688 security_server.load_policy(policy_bytes).map_err(|e| format!("{:?}", e))
689 );
690 security_server
691 }
692
693 #[test]
694 fn compute_access_vector_allows_all() {
695 let security_server = SecurityServer::new();
696 let sid1 = SecurityId::initial(InitialSid::Kernel);
697 let sid2 = SecurityId::initial(InitialSid::Unlabeled);
698 assert_eq!(
699 security_server.compute_access_decision(sid1, sid2, KernelClass::Process.into()).allow,
700 AccessVector::ALL
701 );
702 }
703
704 #[test]
705 fn loaded_policy_can_be_retrieved() {
706 let security_server = security_server_with_tests_policy();
707 assert_eq!(TESTS_BINARY_POLICY, security_server.get_binary_policy().as_slice());
708 }
709
710 #[test]
711 fn loaded_policy_is_validated() {
712 let not_really_a_policy = "not a real policy".as_bytes().to_vec();
713 let security_server = SecurityServer::new();
714 assert!(security_server.load_policy(not_really_a_policy.clone()).is_err());
715 }
716
717 #[test]
718 fn enforcing_mode_is_reported() {
719 let security_server = SecurityServer::new();
720 assert!(!security_server.is_enforcing());
721
722 security_server.set_enforcing(true);
723 assert!(security_server.is_enforcing());
724 }
725
726 #[test]
727 fn without_policy_conditional_booleans_are_empty() {
728 let security_server = SecurityServer::new();
729 assert!(security_server.conditional_booleans().is_empty());
730 }
731
732 #[test]
733 fn conditional_booleans_can_be_queried() {
734 let policy_bytes = TESTSUITE_BINARY_POLICY.to_vec();
735 let security_server = SecurityServer::new();
736 assert_eq!(
737 Ok(()),
738 security_server.load_policy(policy_bytes).map_err(|e| format!("{:?}", e))
739 );
740
741 let booleans = security_server.conditional_booleans();
742 assert!(!booleans.is_empty());
743 let boolean = booleans[0].as_str();
744
745 assert!(security_server.get_boolean("this_is_not_a_valid_boolean_name").is_err());
746 assert!(security_server.get_boolean(boolean).is_ok());
747 }
748
749 #[test]
750 fn conditional_booleans_can_be_changed() {
751 let policy_bytes = TESTSUITE_BINARY_POLICY.to_vec();
752 let security_server = SecurityServer::new();
753 assert_eq!(
754 Ok(()),
755 security_server.load_policy(policy_bytes).map_err(|e| format!("{:?}", e))
756 );
757
758 let booleans = security_server.conditional_booleans();
759 assert!(!booleans.is_empty());
760 let boolean = booleans[0].as_str();
761
762 let (active, pending) = security_server.get_boolean(boolean).unwrap();
763 assert_eq!(active, pending, "Initially active and pending values should match");
764
765 security_server.set_pending_boolean(boolean, !active).unwrap();
766 let (active, pending) = security_server.get_boolean(boolean).unwrap();
767 assert!(active != pending, "Before commit pending should differ from active");
768
769 security_server.commit_pending_booleans();
770 let (final_active, final_pending) = security_server.get_boolean(boolean).unwrap();
771 assert_eq!(final_active, pending, "Pending value should be active after commit");
772 assert_eq!(final_active, final_pending, "Active and pending are the same after commit");
773 }
774
775 #[test]
776 fn parse_security_context_no_policy() {
777 let security_server = SecurityServer::new();
778 let error = security_server
779 .security_context_to_sid(b"unconfined_u:unconfined_r:unconfined_t:s0".into())
780 .expect_err("expected error");
781 let error_string = format!("{:?}", error);
782 assert!(error_string.contains("no policy"));
783 }
784
785 #[test]
786 fn compute_new_fs_node_sid_no_defaults() {
787 let security_server = SecurityServer::new();
788 let policy_bytes =
789 include_bytes!("../testdata/micro_policies/file_no_defaults_policy.pp").to_vec();
790 security_server.load_policy(policy_bytes).expect("binary policy loads");
791
792 let source_sid = security_server
793 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s1".into())
794 .expect("creating SID from security context should succeed");
795 let target_sid = security_server
796 .security_context_to_sid(b"file_u:object_r:file_t:s0".into())
797 .expect("creating SID from security context should succeed");
798
799 let computed_sid = security_server
800 .as_permission_check()
801 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
802 .expect("new sid computed");
803 let computed_context = security_server
804 .sid_to_security_context(computed_sid)
805 .expect("computed sid associated with context");
806
807 assert_eq!(computed_context, b"user_u:object_r:file_t:s0");
810 }
811
812 #[test]
813 fn compute_new_fs_node_sid_source_defaults() {
814 let security_server = SecurityServer::new();
815 let policy_bytes =
816 include_bytes!("../testdata/micro_policies/file_source_defaults_policy.pp").to_vec();
817 security_server.load_policy(policy_bytes).expect("binary policy loads");
818
819 let source_sid = security_server
820 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s2:c0".into())
821 .expect("creating SID from security context should succeed");
822 let target_sid = security_server
823 .security_context_to_sid(b"file_u:object_r:file_t:s1-s3:c0".into())
824 .expect("creating SID from security context should succeed");
825
826 let computed_sid = security_server
827 .as_permission_check()
828 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
829 .expect("new sid computed");
830 let computed_context = security_server
831 .sid_to_security_context(computed_sid)
832 .expect("computed sid associated with context");
833
834 assert_eq!(computed_context, b"user_u:unconfined_r:unconfined_t:s0");
837 }
838
839 #[test]
840 fn compute_new_fs_node_sid_target_defaults() {
841 let security_server = SecurityServer::new();
842 let policy_bytes =
843 include_bytes!("../testdata/micro_policies/file_target_defaults_policy.pp").to_vec();
844 security_server.load_policy(policy_bytes).expect("binary policy loads");
845
846 let source_sid = security_server
847 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s2:c0".into())
848 .expect("creating SID from security context should succeed");
849 let target_sid = security_server
850 .security_context_to_sid(b"file_u:object_r:file_t:s1-s3:c0".into())
851 .expect("creating SID from security context should succeed");
852
853 let computed_sid = security_server
854 .as_permission_check()
855 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
856 .expect("new sid computed");
857 let computed_context = security_server
858 .sid_to_security_context(computed_sid)
859 .expect("computed sid associated with context");
860
861 assert_eq!(computed_context, b"file_u:object_r:file_t:s0");
863 }
864
865 #[test]
866 fn compute_new_fs_node_sid_range_source_low_default() {
867 let security_server = SecurityServer::new();
868 let policy_bytes =
869 include_bytes!("../testdata/micro_policies/file_range_source_low_policy.pp").to_vec();
870 security_server.load_policy(policy_bytes).expect("binary policy loads");
871
872 let source_sid = security_server
873 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s1:c0".into())
874 .expect("creating SID from security context should succeed");
875 let target_sid = security_server
876 .security_context_to_sid(b"file_u:object_r:file_t:s1".into())
877 .expect("creating SID from security context should succeed");
878
879 let computed_sid = security_server
880 .as_permission_check()
881 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
882 .expect("new sid computed");
883 let computed_context = security_server
884 .sid_to_security_context(computed_sid)
885 .expect("computed sid associated with context");
886
887 assert_eq!(computed_context, b"user_u:object_r:file_t:s0");
889 }
890
891 #[test]
892 fn compute_new_fs_node_sid_range_source_low_high_default() {
893 let security_server = SecurityServer::new();
894 let policy_bytes =
895 include_bytes!("../testdata/micro_policies/file_range_source_low_high_policy.pp")
896 .to_vec();
897 security_server.load_policy(policy_bytes).expect("binary policy loads");
898
899 let source_sid = security_server
900 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s1:c0".into())
901 .expect("creating SID from security context should succeed");
902 let target_sid = security_server
903 .security_context_to_sid(b"file_u:object_r:file_t:s1".into())
904 .expect("creating SID from security context should succeed");
905
906 let computed_sid = security_server
907 .as_permission_check()
908 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
909 .expect("new sid computed");
910 let computed_context = security_server
911 .sid_to_security_context(computed_sid)
912 .expect("computed sid associated with context");
913
914 assert_eq!(computed_context, b"user_u:object_r:file_t:s0-s1:c0");
916 }
917
918 #[test]
919 fn compute_new_fs_node_sid_range_source_high_default() {
920 let security_server = SecurityServer::new();
921 let policy_bytes =
922 include_bytes!("../testdata/micro_policies/file_range_source_high_policy.pp").to_vec();
923 security_server.load_policy(policy_bytes).expect("binary policy loads");
924
925 let source_sid = security_server
926 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0-s1:c0".into())
927 .expect("creating SID from security context should succeed");
928 let target_sid = security_server
929 .security_context_to_sid(b"file_u:object_r:file_t:s0".into())
930 .expect("creating SID from security context should succeed");
931
932 let computed_sid = security_server
933 .as_permission_check()
934 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
935 .expect("new sid computed");
936 let computed_context = security_server
937 .sid_to_security_context(computed_sid)
938 .expect("computed sid associated with context");
939
940 assert_eq!(computed_context, b"user_u:object_r:file_t:s1:c0");
942 }
943
944 #[test]
945 fn compute_new_fs_node_sid_range_target_low_default() {
946 let security_server = SecurityServer::new();
947 let policy_bytes =
948 include_bytes!("../testdata/micro_policies/file_range_target_low_policy.pp").to_vec();
949 security_server.load_policy(policy_bytes).expect("binary policy loads");
950
951 let source_sid = security_server
952 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s1".into())
953 .expect("creating SID from security context should succeed");
954 let target_sid = security_server
955 .security_context_to_sid(b"file_u:object_r:file_t:s0-s1:c0".into())
956 .expect("creating SID from security context should succeed");
957
958 let computed_sid = security_server
959 .as_permission_check()
960 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
961 .expect("new sid computed");
962 let computed_context = security_server
963 .sid_to_security_context(computed_sid)
964 .expect("computed sid associated with context");
965
966 assert_eq!(computed_context, b"user_u:object_r:file_t:s0");
968 }
969
970 #[test]
971 fn compute_new_fs_node_sid_range_target_low_high_default() {
972 let security_server = SecurityServer::new();
973 let policy_bytes =
974 include_bytes!("../testdata/micro_policies/file_range_target_low_high_policy.pp")
975 .to_vec();
976 security_server.load_policy(policy_bytes).expect("binary policy loads");
977
978 let source_sid = security_server
979 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s1".into())
980 .expect("creating SID from security context should succeed");
981 let target_sid = security_server
982 .security_context_to_sid(b"file_u:object_r:file_t:s0-s1:c0".into())
983 .expect("creating SID from security context should succeed");
984
985 let computed_sid = security_server
986 .as_permission_check()
987 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
988 .expect("new sid computed");
989 let computed_context = security_server
990 .sid_to_security_context(computed_sid)
991 .expect("computed sid associated with context");
992
993 assert_eq!(computed_context, b"user_u:object_r:file_t:s0-s1:c0");
995 }
996
997 #[test]
998 fn compute_new_fs_node_sid_range_target_high_default() {
999 let security_server = SecurityServer::new();
1000 let policy_bytes =
1001 include_bytes!("../testdata/micro_policies/file_range_target_high_policy.pp").to_vec();
1002 security_server.load_policy(policy_bytes).expect("binary policy loads");
1003
1004 let source_sid = security_server
1005 .security_context_to_sid(b"user_u:unconfined_r:unconfined_t:s0".into())
1006 .expect("creating SID from security context should succeed");
1007 let target_sid = security_server
1008 .security_context_to_sid(b"file_u:object_r:file_t:s0-s1:c0".into())
1009 .expect("creating SID from security context should succeed");
1010
1011 let computed_sid = security_server
1012 .as_permission_check()
1013 .compute_new_fs_node_sid(source_sid, target_sid, FileClass::File.into(), "".into())
1014 .expect("new sid computed");
1015 let computed_context = security_server
1016 .sid_to_security_context(computed_sid)
1017 .expect("computed sid associated with context");
1018
1019 assert_eq!(computed_context, b"user_u:object_r:file_t:s1:c0");
1021 }
1022
1023 #[test]
1024 fn compute_new_fs_node_sid_with_name() {
1025 let security_server = SecurityServer::new();
1026 let policy_bytes =
1027 include_bytes!("../testdata/composite_policies/compiled/type_transition_policy.pp")
1028 .to_vec();
1029 security_server.load_policy(policy_bytes).expect("binary policy loads");
1030
1031 let source_sid = security_server
1032 .security_context_to_sid(b"source_u:source_r:source_t:s0".into())
1033 .expect("creating SID from security context should succeed");
1034 let target_sid = security_server
1035 .security_context_to_sid(b"target_u:object_r:target_t:s0".into())
1036 .expect("creating SID from security context should succeed");
1037
1038 const SPECIAL_FILE_NAME: &[u8] = b"special_file";
1039 let computed_sid = security_server
1040 .as_permission_check()
1041 .compute_new_fs_node_sid(
1042 source_sid,
1043 target_sid,
1044 FileClass::File.into(),
1045 SPECIAL_FILE_NAME.into(),
1046 )
1047 .expect("new sid computed");
1048 let computed_context = security_server
1049 .sid_to_security_context(computed_sid)
1050 .expect("computed sid associated with context");
1051
1052 assert_eq!(computed_context, b"source_u:object_r:special_transition_t:s0");
1054
1055 let computed_sid = security_server
1056 .as_permission_check()
1057 .compute_new_fs_node_sid(
1058 source_sid,
1059 target_sid,
1060 FileClass::Character.into(),
1061 SPECIAL_FILE_NAME.into(),
1062 )
1063 .expect("new sid computed");
1064 let computed_context = security_server
1065 .sid_to_security_context(computed_sid)
1066 .expect("computed sid associated with context");
1067
1068 assert_eq!(computed_context, b"source_u:object_r:target_t:s0");
1071
1072 const OTHER_FILE_NAME: &[u8] = b"other_file";
1073 let computed_sid = security_server
1074 .as_permission_check()
1075 .compute_new_fs_node_sid(
1076 source_sid,
1077 target_sid,
1078 FileClass::File.into(),
1079 OTHER_FILE_NAME.into(),
1080 )
1081 .expect("new sid computed");
1082 let computed_context = security_server
1083 .sid_to_security_context(computed_sid)
1084 .expect("computed sid associated with context");
1085
1086 assert_eq!(computed_context, b"source_u:object_r:transition_t:s0");
1089 }
1090
1091 #[test]
1092 fn permissions_are_fresh_after_different_policy_load() {
1093 let minimal_bytes = MINIMAL_BINARY_POLICY.to_vec();
1094 let allow_fork_bytes =
1095 include_bytes!("../testdata/composite_policies/compiled/allow_fork.pp").to_vec();
1096 let context = b"source_u:object_r:source_t:s0:c0";
1097
1098 let security_server = SecurityServer::new();
1099 security_server.set_enforcing(true);
1100
1101 let permission_check = security_server.as_permission_check();
1102
1103 assert_eq!(
1105 Ok(()),
1106 security_server.load_policy(minimal_bytes).map_err(|e| format!("{:?}", e))
1107 );
1108 let sid = security_server.security_context_to_sid(context.into()).unwrap();
1109
1110 assert!(!permission_check.has_permission(sid, sid, ProcessPermission::Fork).permit);
1112
1113 assert_eq!(
1115 Ok(()),
1116 security_server.load_policy(allow_fork_bytes).map_err(|e| format!("{:?}", e))
1117 );
1118
1119 assert!(permission_check.has_permission(sid, sid, ProcessPermission::Fork).permit);
1121 }
1122
1123 #[test]
1124 fn unknown_sids_are_effectively_unlabeled() {
1125 let with_unlabeled_access_domain_policy_bytes = include_bytes!(
1126 "../testdata/composite_policies/compiled/with_unlabeled_access_domain_policy.pp"
1127 )
1128 .to_vec();
1129 let with_additional_domain_policy_bytes = include_bytes!(
1130 "../testdata/composite_policies/compiled/with_additional_domain_policy.pp"
1131 )
1132 .to_vec();
1133 let allowed_type_context = b"source_u:object_r:allowed_t:s0:c0";
1134 let additional_type_context = b"source_u:object_r:additional_t:s0:c0";
1135
1136 let security_server = SecurityServer::new();
1137 security_server.set_enforcing(true);
1138
1139 assert_eq!(
1142 Ok(()),
1143 security_server
1144 .load_policy(with_unlabeled_access_domain_policy_bytes.clone())
1145 .map_err(|e| format!("{:?}", e))
1146 );
1147 let allowed_type_sid =
1148 security_server.security_context_to_sid(allowed_type_context.into()).unwrap();
1149 assert!(security_server.security_context_to_sid(additional_type_context.into()).is_err());
1150
1151 assert_eq!(
1154 Ok(()),
1155 security_server
1156 .load_policy(with_additional_domain_policy_bytes.clone())
1157 .map_err(|e| format!("{:?}", e))
1158 );
1159 let additional_type_sid =
1160 security_server.security_context_to_sid(additional_type_context.into()).unwrap();
1161 assert_eq!(
1162 allowed_type_sid,
1163 security_server.security_context_to_sid(allowed_type_context.into()).unwrap()
1164 );
1165
1166 let permission_check = security_server.as_permission_check();
1167
1168 assert!(
1172 !permission_check
1173 .has_permission(additional_type_sid, allowed_type_sid, ProcessPermission::GetSched)
1174 .permit
1175 );
1176 assert!(
1177 !permission_check
1178 .has_permission(additional_type_sid, allowed_type_sid, ProcessPermission::SetSched)
1179 .permit
1180 );
1181 assert!(
1182 !permission_check
1183 .has_permission(allowed_type_sid, additional_type_sid, ProcessPermission::GetSched)
1184 .permit
1185 );
1186 assert!(
1187 !permission_check
1188 .has_permission(allowed_type_sid, additional_type_sid, ProcessPermission::SetSched)
1189 .permit
1190 );
1191
1192 assert_eq!(
1194 Ok(()),
1195 security_server
1196 .load_policy(with_unlabeled_access_domain_policy_bytes)
1197 .map_err(|e| format!("{:?}", e))
1198 );
1199
1200 assert!(
1204 permission_check
1205 .has_permission(allowed_type_sid, additional_type_sid, ProcessPermission::GetSched)
1206 .permit
1207 );
1208 assert!(
1209 !permission_check
1210 .has_permission(allowed_type_sid, additional_type_sid, ProcessPermission::SetSched)
1211 .permit
1212 );
1213
1214 assert!(
1219 !permission_check
1220 .has_permission(additional_type_sid, allowed_type_sid, ProcessPermission::GetSched)
1221 .permit
1222 );
1223 assert!(
1224 permission_check
1225 .has_permission(additional_type_sid, allowed_type_sid, ProcessPermission::SetSched)
1226 .permit
1227 );
1228
1229 assert!(security_server.sid_to_security_context(additional_type_sid).is_none());
1231
1232 assert_eq!(
1235 Ok(()),
1236 security_server
1237 .load_policy(with_additional_domain_policy_bytes)
1238 .map_err(|e| format!("{:?}", e))
1239 );
1240 assert_eq!(
1241 additional_type_context.to_vec(),
1242 security_server.sid_to_security_context(additional_type_sid).unwrap()
1243 );
1244 }
1245
1246 #[test]
1247 fn permission_check_permissive() {
1248 let security_server = security_server_with_tests_policy();
1249 security_server.set_enforcing(false);
1250 assert!(!security_server.is_enforcing());
1251
1252 let sid =
1253 security_server.security_context_to_sid("user0:object_r:type0:s0".into()).unwrap();
1254 let permission_check = security_server.as_permission_check();
1255
1256 assert_eq!(
1259 permission_check.has_permission(sid, sid, ProcessPermission::Fork),
1260 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1261 );
1262
1263 assert_eq!(
1267 permission_check.has_permission(sid, sid, ProcessPermission::GetRlimit),
1268 PermissionCheckResult { permit: true, audit: true, todo_bug: None }
1269 );
1270
1271 assert_eq!(
1275 permission_check.has_permission(
1276 sid,
1277 sid,
1278 CommonFsNodePermission::GetAttr.for_class(FileClass::Block)
1279 ),
1280 PermissionCheckResult { permit: true, audit: true, todo_bug: None }
1281 );
1282 }
1283
1284 #[test]
1285 fn permission_check_enforcing() {
1286 let security_server = security_server_with_tests_policy();
1287 security_server.set_enforcing(true);
1288 assert!(security_server.is_enforcing());
1289
1290 let sid =
1291 security_server.security_context_to_sid("user0:object_r:type0:s0".into()).unwrap();
1292 let permission_check = security_server.as_permission_check();
1293
1294 assert_eq!(
1296 permission_check.has_permission(sid, sid, ProcessPermission::Fork),
1297 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1298 );
1299
1300 assert_eq!(
1303 permission_check.has_permission(sid, sid, ProcessPermission::GetRlimit),
1304 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1305 );
1306
1307 assert_eq!(
1310 permission_check.has_permission(
1311 sid,
1312 sid,
1313 CommonFsNodePermission::GetAttr.for_class(FileClass::Block)
1314 ),
1315 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1316 );
1317 }
1318
1319 #[test]
1320 fn permissive_domain() {
1321 let security_server = security_server_with_tests_policy();
1322 security_server.set_enforcing(true);
1323 assert!(security_server.is_enforcing());
1324
1325 let permissive_sid = security_server
1326 .security_context_to_sid("user0:object_r:permissive_t:s0".into())
1327 .unwrap();
1328 let non_permissive_sid = security_server
1329 .security_context_to_sid("user0:object_r:non_permissive_t:s0".into())
1330 .unwrap();
1331
1332 let permission_check = security_server.as_permission_check();
1333
1334 assert_eq!(
1336 permission_check.has_permission(
1337 permissive_sid,
1338 permissive_sid,
1339 ProcessPermission::GetSched
1340 ),
1341 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1342 );
1343 assert_eq!(
1344 permission_check.has_permission(
1345 non_permissive_sid,
1346 non_permissive_sid,
1347 ProcessPermission::GetSched
1348 ),
1349 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1350 );
1351
1352 assert_eq!(
1355 permission_check.has_permission(
1356 permissive_sid,
1357 non_permissive_sid,
1358 ProcessPermission::GetSched
1359 ),
1360 PermissionCheckResult { permit: true, audit: true, todo_bug: None }
1361 );
1362 assert_eq!(
1363 permission_check.has_permission(
1364 non_permissive_sid,
1365 permissive_sid,
1366 ProcessPermission::GetSched
1367 ),
1368 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1369 );
1370
1371 assert_eq!(
1376 permission_check.has_permission(
1377 permissive_sid,
1378 non_permissive_sid,
1379 CommonFsNodePermission::GetAttr.for_class(FileClass::Block)
1380 ),
1381 PermissionCheckResult { permit: true, audit: true, todo_bug: None }
1382 );
1383 assert_eq!(
1384 permission_check.has_permission(
1385 non_permissive_sid,
1386 non_permissive_sid,
1387 CommonFsNodePermission::GetAttr.for_class(FileClass::Block)
1388 ),
1389 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1390 );
1391 }
1392
1393 #[test]
1394 fn auditallow_and_dontaudit() {
1395 let security_server = security_server_with_tests_policy();
1396 security_server.set_enforcing(true);
1397 assert!(security_server.is_enforcing());
1398
1399 let audit_sid = security_server
1400 .security_context_to_sid("user0:object_r:test_audit_t:s0".into())
1401 .unwrap();
1402
1403 let permission_check = security_server.as_permission_check();
1404
1405 assert_eq!(
1407 permission_check.has_permission(audit_sid, audit_sid, ProcessPermission::Fork),
1408 PermissionCheckResult { permit: true, audit: true, todo_bug: None }
1409 );
1410
1411 assert_eq!(
1413 permission_check.has_permission(audit_sid, audit_sid, ProcessPermission::SetSched),
1414 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1415 );
1416
1417 assert_eq!(
1419 permission_check.has_permission(audit_sid, audit_sid, ProcessPermission::GetSched),
1420 PermissionCheckResult { permit: false, audit: false, todo_bug: None }
1421 );
1422
1423 assert_eq!(
1425 permission_check.has_permission(audit_sid, audit_sid, ProcessPermission::GetPgid),
1426 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1427 );
1428 }
1429
1430 #[test]
1431 fn access_checks_with_exceptions_config() {
1432 const EXCEPTIONS_CONFIG: &str = "
1433 // These statement should all be resolved.
1434 todo_deny b/001 test_exception_source_t test_exception_target_t file
1435 todo_deny b/002 test_exception_other_t test_exception_target_t chr_file
1436 todo_deny b/003 test_exception_source_t test_exception_other_t anon_inode
1437 todo_deny b/004 test_exception_permissive_t test_exception_target_t file
1438 todo_permissive b/005 test_exception_todo_permissive_t
1439
1440 // These statements should not be resolved.
1441 todo_deny b/101 test_undefined_source_t test_exception_target_t file
1442 todo_deny b/102 test_exception_source_t test_undefined_target_t file
1443 todo_permissive b/103 test_undefined_source_t
1444 ";
1445 let security_server = SecurityServer::new_with_exceptions(EXCEPTIONS_CONFIG.into());
1446 security_server.set_enforcing(true);
1447
1448 const EXCEPTIONS_POLICY: &[u8] =
1449 include_bytes!("../testdata/composite_policies/compiled/exceptions_config_policy.pp");
1450 assert!(security_server.load_policy(EXCEPTIONS_POLICY.into()).is_ok());
1451
1452 let source_sid = security_server
1453 .security_context_to_sid("test_exception_u:object_r:test_exception_source_t:s0".into())
1454 .unwrap();
1455 let target_sid = security_server
1456 .security_context_to_sid("test_exception_u:object_r:test_exception_target_t:s0".into())
1457 .unwrap();
1458 let other_sid = security_server
1459 .security_context_to_sid("test_exception_u:object_r:test_exception_other_t:s0".into())
1460 .unwrap();
1461 let permissive_sid = security_server
1462 .security_context_to_sid(
1463 "test_exception_u:object_r:test_exception_permissive_t:s0".into(),
1464 )
1465 .unwrap();
1466 let unmatched_sid = security_server
1467 .security_context_to_sid(
1468 "test_exception_u:object_r:test_exception_unmatched_t:s0".into(),
1469 )
1470 .unwrap();
1471 let todo_permissive_sid = security_server
1472 .security_context_to_sid(
1473 "test_exception_u:object_r:test_exception_todo_permissive_t:s0".into(),
1474 )
1475 .unwrap();
1476
1477 let permission_check = security_server.as_permission_check();
1478
1479 assert_eq!(
1481 permission_check.has_permission(source_sid, target_sid, ProcessPermission::GetPgid),
1482 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1483 );
1484
1485 assert_eq!(
1487 permission_check.has_permission(source_sid, target_sid, FilePermission::Entrypoint),
1488 PermissionCheckResult {
1489 permit: true,
1490 audit: true,
1491 todo_bug: Some(NonZeroU64::new(1).unwrap())
1492 }
1493 );
1494
1495 assert_eq!(
1497 permission_check.has_permission(source_sid, target_sid, FilePermission::ExecuteNoTrans),
1498 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1499 );
1500
1501 assert_eq!(
1503 permission_check.has_permission(other_sid, target_sid, FilePermission::Entrypoint),
1504 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1505 );
1506
1507 assert_eq!(
1509 permission_check.has_permission(
1510 other_sid,
1511 target_sid,
1512 CommonFsNodePermission::Read.for_class(FileClass::Character)
1513 ),
1514 PermissionCheckResult {
1515 permit: true,
1516 audit: true,
1517 todo_bug: Some(NonZeroU64::new(2).unwrap())
1518 }
1519 );
1520
1521 assert_eq!(
1523 permission_check.has_permission(source_sid, unmatched_sid, FilePermission::Entrypoint),
1524 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1525 );
1526
1527 assert_eq!(
1529 permission_check.has_permission(unmatched_sid, target_sid, FilePermission::Entrypoint),
1530 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1531 );
1532
1533 assert_eq!(
1535 permission_check.has_permission(permissive_sid, target_sid, FilePermission::Entrypoint),
1536 PermissionCheckResult { permit: true, audit: true, todo_bug: None }
1537 );
1538
1539 assert_eq!(
1542 permission_check.has_permission(
1543 todo_permissive_sid,
1544 target_sid,
1545 FilePermission::Entrypoint
1546 ),
1547 PermissionCheckResult {
1548 permit: true,
1549 audit: true,
1550 todo_bug: Some(NonZeroU64::new(5).unwrap())
1551 }
1552 );
1553 assert_eq!(
1554 permission_check.has_permission(
1555 todo_permissive_sid,
1556 todo_permissive_sid,
1557 FilePermission::Entrypoint
1558 ),
1559 PermissionCheckResult {
1560 permit: true,
1561 audit: true,
1562 todo_bug: Some(NonZeroU64::new(5).unwrap())
1563 }
1564 );
1565 assert_eq!(
1566 permission_check.has_permission(
1567 todo_permissive_sid,
1568 target_sid,
1569 FilePermission::Entrypoint
1570 ),
1571 PermissionCheckResult {
1572 permit: true,
1573 audit: true,
1574 todo_bug: Some(NonZeroU64::new(5).unwrap())
1575 }
1576 );
1577 }
1578
1579 #[test]
1580 fn handle_unknown() {
1581 let security_server = security_server_with_tests_policy();
1582
1583 let sid = security_server
1584 .security_context_to_sid("user0:object_r:type0:s0".into())
1585 .expect("Resolve Context to SID");
1586
1587 const REJECT_POLICY: &[u8] = include_bytes!(
1591 "../testdata/composite_policies/compiled/handle_unknown_policy-reject.pp"
1592 );
1593 assert!(security_server.load_policy(REJECT_POLICY.to_vec()).is_err());
1594
1595 security_server.set_enforcing(true);
1596
1597 const DENY_POLICY: &[u8] =
1599 include_bytes!("../testdata/composite_policies/compiled/handle_unknown_policy-deny.pp");
1600 assert!(security_server.load_policy(DENY_POLICY.to_vec()).is_ok());
1601 let permission_check = security_server.as_permission_check();
1602
1603 assert_eq!(
1605 permission_check.has_permission(sid, sid, ProcessPermission::GetSched),
1606 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1607 );
1608 assert_eq!(
1609 permission_check.has_permission(sid, sid, DirPermission::AddName),
1610 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1611 );
1612
1613 assert_eq!(
1615 permission_check.has_permission(sid, sid, DirPermission::Search),
1616 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1617 );
1618 assert_eq!(
1619 permission_check.has_permission(sid, sid, DirPermission::Reparent),
1620 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1621 );
1622
1623 const ALLOW_POLICY: &[u8] = include_bytes!(
1625 "../testdata/composite_policies/compiled/handle_unknown_policy-allow.pp"
1626 );
1627 assert!(security_server.load_policy(ALLOW_POLICY.to_vec()).is_ok());
1628 let permission_check = security_server.as_permission_check();
1629
1630 assert_eq!(
1632 permission_check.has_permission(sid, sid, ProcessPermission::GetSched),
1633 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1634 );
1635 assert_eq!(
1636 permission_check.has_permission(sid, sid, DirPermission::AddName),
1637 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1638 );
1639
1640 assert_eq!(
1642 permission_check.has_permission(sid, sid, DirPermission::Search),
1643 PermissionCheckResult { permit: true, audit: false, todo_bug: None }
1644 );
1645 assert_eq!(
1646 permission_check.has_permission(sid, sid, DirPermission::Reparent),
1647 PermissionCheckResult { permit: false, audit: true, todo_bug: None }
1648 );
1649 }
1650}