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