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