1#![allow(non_upper_case_globals)]
7
8use super::selinux_hooks::audit::Auditable;
9use super::{
10 BinderConnectionState, BpfMapState, BpfProgState, FileObjectState, FileSystemState,
11 KernelState, PerfEventState, common_cap, selinux_hooks, yama,
12};
13use crate::mm::{Mapping, MappingOptions, ProtectionFlags};
14use crate::perf::PerfEventFile;
15use crate::security::selinux_hooks::current_task_state;
16use crate::task::loader::ResolvedElf;
17use crate::task::{CurrentTask, Kernel, Task};
18use crate::vfs::fs_args::MountParams;
19use crate::vfs::socket::{
20 Socket, SocketAddress, SocketDomain, SocketFile, SocketPeer, SocketProtocol,
21 SocketShutdownFlags, SocketType,
22};
23use crate::vfs::{
24 DirEntryHandle, DowncastedFile, FileHandle, FileObject, FileSystem, FileSystemHandle,
25 FileSystemOps, FsNode, FsStr, FsString, Mount, NamespaceNode, ValueOrSize, XattrOp,
26};
27use ebpf::MapFlags;
28use linux_uapi::{
29 perf_event_attr, perf_type_id, perf_type_id_PERF_TYPE_BREAKPOINT,
30 perf_type_id_PERF_TYPE_HARDWARE, perf_type_id_PERF_TYPE_HW_CACHE, perf_type_id_PERF_TYPE_RAW,
31 perf_type_id_PERF_TYPE_SOFTWARE, perf_type_id_PERF_TYPE_TRACEPOINT,
32};
33use selinux::{FileSystemMountOptions, InitialSid, SecurityPermission, SecurityServer, TaskAttrs};
34use starnix_logging::{CATEGORY_STARNIX_SECURITY, log_debug};
35use starnix_sync::{FileOpsCore, LockEqualOrBefore, Locked, Unlocked};
36use starnix_uapi::arc_key::WeakKey;
37use starnix_uapi::auth::{Credentials, PtraceAccessMode};
38use starnix_uapi::device_id::DeviceId;
39use starnix_uapi::errors::Errno;
40use starnix_uapi::file_mode::{Access, FileMode};
41use starnix_uapi::mount_flags::MountFlags;
42use starnix_uapi::open_flags::OpenFlags;
43use starnix_uapi::signals::Signal;
44use starnix_uapi::syslog::SyslogAction;
45use starnix_uapi::unmount_flags::UnmountFlags;
46use starnix_uapi::user_address::UserAddress;
47use starnix_uapi::{bpf_cmd, error, rlimit};
48use std::ops::Range;
49use std::sync::Arc;
50use syncio::zxio_node_attr_has_t;
51use zerocopy::FromBytes;
52
53macro_rules! track_hook_duration {
54 ($cname:literal) => {
55 fuchsia_trace::duration!(CATEGORY_STARNIX_SECURITY, $cname);
56 };
57}
58
59bitflags::bitflags! {
60 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
63 pub struct PermissionFlags: u32 {
64 const EXEC = 1 as u32;
65 const WRITE = 2 as u32;
66 const READ = 4 as u32;
67 const APPEND = 8 as u32;
68
69 const ACCESS = 16 as u32;
72
73 const FOR_OPEN = 32 as u32;
76 }
77}
78
79impl PermissionFlags {
80 pub fn as_access(&self) -> Access {
81 let mut access = Access::empty();
82 if self.contains(PermissionFlags::READ) {
83 access |= Access::READ;
84 }
85 if self.contains(PermissionFlags::WRITE) {
86 access |= Access::WRITE;
89 }
90 if self.contains(PermissionFlags::EXEC) {
91 access |= Access::EXEC;
92 }
93 access
94 }
95}
96
97impl From<Access> for PermissionFlags {
98 fn from(access: Access) -> Self {
99 let mut permissions = PermissionFlags::empty();
101 if access.contains(Access::READ) {
102 permissions |= PermissionFlags::READ;
103 }
104 if access.contains(Access::WRITE) {
105 permissions |= PermissionFlags::WRITE;
106 }
107 if access.contains(Access::EXEC) {
108 permissions |= PermissionFlags::EXEC;
109 }
110 permissions
111 }
112}
113
114impl From<ProtectionFlags> for PermissionFlags {
115 fn from(protection_flags: ProtectionFlags) -> Self {
116 let mut flags = PermissionFlags::empty();
117 if protection_flags.contains(ProtectionFlags::READ) {
118 flags |= PermissionFlags::READ;
119 }
120 if protection_flags.contains(ProtectionFlags::WRITE) {
121 flags |= PermissionFlags::WRITE;
122 }
123 if protection_flags.contains(ProtectionFlags::EXEC) {
124 flags |= PermissionFlags::EXEC;
125 }
126 flags
127 }
128}
129
130impl From<OpenFlags> for PermissionFlags {
131 fn from(flags: OpenFlags) -> Self {
132 let mut permissions = PermissionFlags::empty();
133 if flags.can_read() {
134 permissions |= PermissionFlags::READ;
135 }
136 if flags.can_write() {
137 permissions |= PermissionFlags::WRITE;
138 if flags.contains(OpenFlags::APPEND) {
139 permissions |= PermissionFlags::APPEND;
140 }
141 }
142 permissions
143 }
144}
145
146impl From<MapFlags> for PermissionFlags {
147 fn from(bpf_flags: MapFlags) -> Self {
148 if bpf_flags.contains(MapFlags::SyscallReadOnly) {
149 PermissionFlags::READ
150 } else if bpf_flags.contains(MapFlags::SyscallWriteOnly) {
151 PermissionFlags::WRITE
152 } else {
153 PermissionFlags::READ | PermissionFlags::WRITE
154 }
155 }
156}
157
158#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
160pub enum PerfEventType {
161 Hardware,
162 Software,
163 Tracepoint,
164 Raw,
165 HwCache,
166 Breakpoint,
167}
168
169#[allow(non_upper_case_globals)]
171impl TryFrom<perf_type_id> for PerfEventType {
172 type Error = Errno;
173
174 fn try_from(type_id: perf_type_id) -> Result<Self, Errno> {
175 match type_id {
176 perf_type_id_PERF_TYPE_HARDWARE => Ok(Self::Hardware),
177 perf_type_id_PERF_TYPE_SOFTWARE => Ok(Self::Software),
178 perf_type_id_PERF_TYPE_TRACEPOINT => Ok(Self::Tracepoint),
179 perf_type_id_PERF_TYPE_RAW => Ok(Self::Raw),
180 perf_type_id_PERF_TYPE_HW_CACHE => Ok(Self::HwCache),
181 perf_type_id_PERF_TYPE_BREAKPOINT => Ok(Self::Breakpoint),
182 _ => {
183 return error!(ENOTSUP);
184 }
185 }
186 }
187}
188
189#[derive(PartialEq, Eq)]
191pub enum TargetTaskType<'a> {
192 AllTasks,
194 CurrentTask,
196 Task(&'a Task),
198}
199
200fn if_selinux_else_with_context<F, R, D, C>(context: C, task: &Task, hook: F, default: D) -> R
204where
205 F: FnOnce(C, &Arc<SecurityServer>) -> R,
206 D: Fn(C) -> R,
207{
208 if let Some(state) = task.kernel().security_state.state.as_ref() {
209 if state.has_policy() { hook(context, &state.server) } else { default(context) }
210 } else {
211 default(context)
212 }
213}
214
215fn if_selinux_else<F, R, D>(task: &Task, hook: F, default: D) -> R
219where
220 F: FnOnce(&Arc<SecurityServer>) -> R,
221 D: Fn() -> R,
222{
223 if_selinux_else_with_context(
224 (),
225 task,
226 |_, security_server| hook(security_server),
227 |_| default(),
228 )
229}
230
231fn if_selinux_else_default_ok_with_context<R, F, C>(
235 context: C,
236 task: &Task,
237 hook: F,
238) -> Result<R, Errno>
239where
240 F: FnOnce(C, &Arc<SecurityServer>) -> Result<R, Errno>,
241 R: Default,
242{
243 if_selinux_else_with_context(context, task, hook, |_| Ok(R::default()))
244}
245
246fn if_selinux_else_default_ok<R, F>(task: &Task, hook: F) -> Result<R, Errno>
250where
251 F: FnOnce(&Arc<SecurityServer>) -> Result<R, Errno>,
252 R: Default,
253{
254 if_selinux_else(task, hook, || Ok(R::default()))
255}
256
257pub fn kernel_init_security(
260 enabled: bool,
261 options: String,
262 exceptions: Vec<String>,
263 inspect_node: &fuchsia_inspect::Node,
264) -> KernelState {
265 track_hook_duration!("security.hooks.kernel_init_security");
266 KernelState {
267 state: enabled
268 .then(|| selinux_hooks::kernel_init_security(options, exceptions, inspect_node)),
269 }
270}
271
272pub fn binder_set_context_mgr(current_task: &CurrentTask) -> Result<(), Errno> {
275 track_hook_duration!("security.hooks.binder_set_context_mgr");
276 if_selinux_else_default_ok(current_task, |security_server| {
277 selinux_hooks::binder::binder_set_context_mgr(security_server, current_task)
278 })
279}
280
281pub fn binder_transaction(
284 current_task: &CurrentTask,
285 target_task: &Task,
286 connection_state: &BinderConnectionState,
287) -> Result<(), Errno> {
288 track_hook_duration!("security.hooks.binder_transaction");
289 if_selinux_else_default_ok(current_task, |security_server| {
290 selinux_hooks::binder::binder_transaction(
291 security_server,
292 &connection_state.state,
293 current_task,
294 target_task,
295 )
296 })
297}
298
299pub fn binder_transfer_binder(current_task: &CurrentTask, target_task: &Task) -> Result<(), Errno> {
302 track_hook_duration!("security.hooks.binder_transfer_binder");
303 if_selinux_else_default_ok(current_task, |security_server| {
304 selinux_hooks::binder::binder_transfer_binder(security_server, current_task, target_task)
305 })
306}
307
308pub fn binder_transfer_file(
311 current_task: &CurrentTask,
312 receiving_task: &Task,
313 file: &FileObject,
314) -> Result<(), Errno> {
315 track_hook_duration!("security.hooks.binder_transfer_file");
316 if_selinux_else_default_ok(current_task, |security_server| {
317 selinux_hooks::binder::binder_transfer_file(
318 security_server,
319 current_task,
320 receiving_task,
321 file,
322 )
323 })
324}
325
326pub fn binder_get_context(
329 current_task: &CurrentTask,
330 connection_state: &BinderConnectionState,
331) -> Option<Vec<u8>> {
332 track_hook_duration!("security.hooks.binder_get_context");
333 if_selinux_else(
334 current_task,
335 |security_server| {
336 selinux_hooks::binder::binder_get_context(&security_server, &connection_state.state)
337 },
338 || None,
339 )
340}
341
342pub fn sb_eat_lsm_opts(
346 kernel: &Kernel,
347 mount_params: &mut MountParams,
348) -> Result<FileSystemMountOptions, Errno> {
349 track_hook_duration!("security.hooks.sb_eat_lsm_opts");
350 if kernel.security_state.state.is_some() {
351 return selinux_hooks::superblock::sb_eat_lsm_opts(mount_params);
352 }
353 Ok(FileSystemMountOptions::default())
354}
355
356pub fn file_system_init_security(
359 mount_options: &FileSystemMountOptions,
360 ops: &dyn FileSystemOps,
361) -> Result<FileSystemState, Errno> {
362 track_hook_duration!("security.hooks.file_system_init_security");
363 Ok(FileSystemState {
364 state: selinux_hooks::superblock::file_system_init_security(mount_options, ops)?,
365 })
366}
367
368pub fn file_system_post_init_security(kernel: &Kernel, file_system: &FileSystemHandle) {
373 track_hook_duration!("security.hooks.file_system_post_init_security");
374 if let Some(state) = &kernel.security_state.state {
375 if !state.has_policy() {
376 log_debug!("Queuing {} FileSystem for labeling", file_system.name());
379 state.pending_file_systems.lock().insert(WeakKey::from(&file_system));
380 }
381 }
382}
383
384pub fn file_system_resolve_security<L>(
389 locked: &mut Locked<L>,
390 current_task: &CurrentTask,
391 file_system: &FileSystemHandle,
392) -> Result<(), Errno>
393where
394 L: LockEqualOrBefore<FileOpsCore>,
395{
396 track_hook_duration!("security.hooks.file_system_resolve_security");
397 if_selinux_else_default_ok_with_context(locked, current_task, |locked, security_server| {
398 selinux_hooks::superblock::file_system_resolve_security(
399 locked,
400 security_server,
401 current_task,
402 file_system,
403 )
404 })
405}
406
407pub struct FsNodeSecurityXattr {
409 pub name: &'static FsStr,
410 pub value: FsString,
411}
412
413pub fn mmap_file(
417 current_task: &CurrentTask,
418 file: Option<&FileHandle>,
419 protection_flags: ProtectionFlags,
420 options: MappingOptions,
421) -> Result<(), Errno> {
422 track_hook_duration!("security.hooks.mmap_file");
423 if_selinux_else_default_ok(current_task, |security_server| {
424 selinux_hooks::file::mmap_file(
425 security_server,
426 current_task,
427 file,
428 protection_flags,
429 options,
430 )
431 })
432}
433
434pub fn file_mprotect(
438 current_task: &CurrentTask,
439 range: &Range<UserAddress>,
440 mapping: &Mapping,
441 prot: ProtectionFlags,
442) -> Result<(), Errno> {
443 track_hook_duration!("security.hooks.file_mprotect");
444 if_selinux_else_default_ok(current_task, |security_server| {
445 selinux_hooks::file::file_mprotect(security_server, current_task, range, mapping, prot)
446 })
447}
448
449pub fn file_permission(
452 current_task: &CurrentTask,
453 file: &FileObject,
454 permission_flags: PermissionFlags,
455) -> Result<(), Errno> {
456 track_hook_duration!("security.hooks.file_permission");
457 if_selinux_else_default_ok(current_task, |security_server| {
458 selinux_hooks::file::file_permission(security_server, current_task, file, permission_flags)
459 })
460}
461
462pub fn file_open(current_task: &CurrentTask, file: &FileObject) -> Result<(), Errno> {
465 track_hook_duration!("security.hooks.file_open");
466 if_selinux_else_default_ok(current_task, |security_server| {
467 selinux_hooks::file::file_open(security_server, current_task, file)
468 })
469}
470
471pub fn fs_node_init_with_dentry<L>(
477 locked: &mut Locked<L>,
478 current_task: &CurrentTask,
479 dir_entry: &DirEntryHandle,
480) -> Result<(), Errno>
481where
482 L: LockEqualOrBefore<FileOpsCore>,
483{
484 track_hook_duration!("security.hooks.fs_node_init_with_dentry");
485 if let Some(state) = ¤t_task.kernel().security_state.state {
490 selinux_hooks::fs_node::fs_node_init_with_dentry(
491 Some(locked.cast_locked()),
492 &state.server,
493 current_task,
494 dir_entry,
495 )
496 } else {
497 Ok(())
498 }
499}
500
501pub fn fs_node_init_with_dentry_no_xattr(
502 current_task: &CurrentTask,
503 dir_entry: &DirEntryHandle,
504) -> Result<(), Errno> {
505 track_hook_duration!("security.hooks.fs_node_init_with_dentry_no_xattr");
506 if let Some(state) = ¤t_task.kernel().security_state.state {
511 if dir_entry.node.is_private() {
514 return selinux_hooks::fs_node::fs_node_init_anon(
515 &state.server,
516 current_task,
517 &dir_entry.node,
518 "",
519 );
520 }
521
522 selinux_hooks::fs_node::fs_node_init_with_dentry(
523 None,
524 &state.server,
525 current_task,
526 dir_entry,
527 )
528 } else {
529 Ok(())
530 }
531}
532
533pub fn fs_node_init_with_dentry_deferred(kernel: &Kernel, dir_entry: &DirEntryHandle) {
537 track_hook_duration!("security.hooks.fs_node_init_with_dentry_no_xattr");
538 if kernel.security_state.state.is_some() {
539 selinux_hooks::fs_node::fs_node_init_with_dentry_deferred(dir_entry);
540 }
541}
542
543pub fn fs_node_notify_security_context(
550 current_task: &CurrentTask,
551 fs_node: &FsNode,
552 context: &FsStr,
553) -> Result<(), Errno> {
554 track_hook_duration!("security.hooks.fs_node_notify_security_context");
555 if_selinux_else(
556 current_task,
557 |security_server| {
558 selinux_hooks::fs_node::fs_node_notify_security_context(
559 security_server,
560 fs_node,
561 context,
562 )
563 },
564 || error!(ENOTSUP),
565 )
566}
567
568pub fn fs_node_init_on_create(
580 current_task: &CurrentTask,
581 new_node: &FsNode,
582 parent: &FsNode,
583 name: &FsStr,
584) -> Result<Option<FsNodeSecurityXattr>, Errno> {
585 track_hook_duration!("security.hooks.fs_node_init_on_create");
586 if_selinux_else_default_ok(current_task, |security_server| {
587 selinux_hooks::fs_node::fs_node_init_on_create(
588 security_server,
589 current_task,
590 new_node,
591 Some(parent),
592 name,
593 )
594 })
595}
596
597pub fn dentry_create_files_as(
605 current_task: &CurrentTask,
606 parent: &FsNode,
607 new_node_mode: FileMode,
608 new_node_name: &FsStr,
609 new_creds: &mut Credentials,
610) -> Result<(), Errno> {
611 track_hook_duration!("security.hooks.dentry_create_files_as");
612 if_selinux_else_default_ok(current_task, |security_server| {
613 selinux_hooks::fs_node::dentry_create_files_as(
614 security_server,
615 current_task,
616 parent,
617 new_node_mode,
618 new_node_name,
619 new_creds,
620 )
621 })
622}
623
624pub fn fs_node_init_anon(
629 current_task: &CurrentTask,
630 new_node: &FsNode,
631 node_type: &str,
632) -> Result<(), Errno> {
633 track_hook_duration!("security.hooks.fs_node_init_anon");
634 if let Some(state) = current_task.kernel().security_state.state.as_ref() {
635 selinux_hooks::fs_node::fs_node_init_anon(&state.server, current_task, new_node, node_type)
636 } else {
637 Ok(())
638 }
639}
640
641pub fn check_fs_node_create_access(
645 current_task: &CurrentTask,
646 parent: &FsNode,
647 mode: FileMode,
648 name: &FsStr,
649) -> Result<(), Errno> {
650 track_hook_duration!("security.hooks.check_fs_node_create_access");
651 if_selinux_else_default_ok(current_task, |security_server| {
652 selinux_hooks::fs_node::check_fs_node_create_access(
653 security_server,
654 current_task,
655 parent,
656 mode,
657 name,
658 )
659 })
660}
661
662pub fn check_fs_node_symlink_access(
666 current_task: &CurrentTask,
667 parent: &FsNode,
668 name: &FsStr,
669 old_path: &FsStr,
670) -> Result<(), Errno> {
671 track_hook_duration!("security.hooks.check_fs_node_symlink_access");
672 if_selinux_else_default_ok(current_task, |security_server| {
673 selinux_hooks::fs_node::check_fs_node_symlink_access(
674 security_server,
675 current_task,
676 parent,
677 name,
678 old_path,
679 )
680 })
681}
682
683pub fn check_fs_node_mkdir_access(
687 current_task: &CurrentTask,
688 parent: &FsNode,
689 mode: FileMode,
690 name: &FsStr,
691) -> Result<(), Errno> {
692 track_hook_duration!("security.hooks.check_fs_node_mkdir_access");
693 if_selinux_else_default_ok(current_task, |security_server| {
694 selinux_hooks::fs_node::check_fs_node_mkdir_access(
695 security_server,
696 current_task,
697 parent,
698 mode,
699 name,
700 )
701 })
702}
703
704pub fn check_fs_node_mknod_access(
710 current_task: &CurrentTask,
711 parent: &FsNode,
712 mode: FileMode,
713 name: &FsStr,
714 device_id: DeviceId,
715) -> Result<(), Errno> {
716 track_hook_duration!("security.hooks.check_fs_node_mknod_access");
717 assert!(!mode.is_reg());
718
719 if_selinux_else_default_ok(current_task, |security_server| {
720 selinux_hooks::fs_node::check_fs_node_mknod_access(
721 security_server,
722 current_task,
723 parent,
724 mode,
725 name,
726 device_id,
727 )
728 })
729}
730
731pub fn check_fs_node_link_access(
734 current_task: &CurrentTask,
735 parent: &FsNode,
736 child: &FsNode,
737) -> Result<(), Errno> {
738 track_hook_duration!("security.hooks.check_fs_node_link_access");
739 if_selinux_else_default_ok(current_task, |security_server| {
740 selinux_hooks::fs_node::check_fs_node_link_access(
741 security_server,
742 current_task,
743 parent,
744 child,
745 )
746 })
747}
748
749pub fn check_fs_node_unlink_access(
752 current_task: &CurrentTask,
753 parent: &FsNode,
754 child: &FsNode,
755 name: &FsStr,
756) -> Result<(), Errno> {
757 track_hook_duration!("security.hooks.check_fs_node_unlink_access");
758 if_selinux_else_default_ok(current_task, |security_server| {
759 selinux_hooks::fs_node::check_fs_node_unlink_access(
760 security_server,
761 current_task,
762 parent,
763 child,
764 name,
765 )
766 })
767}
768
769pub fn check_fs_node_rmdir_access(
772 current_task: &CurrentTask,
773 parent: &FsNode,
774 child: &FsNode,
775 name: &FsStr,
776) -> Result<(), Errno> {
777 track_hook_duration!("security.hooks.check_fs_node_rmdir_access");
778 if_selinux_else_default_ok(current_task, |security_server| {
779 selinux_hooks::fs_node::check_fs_node_rmdir_access(
780 security_server,
781 current_task,
782 parent,
783 child,
784 name,
785 )
786 })
787}
788
789pub fn check_fs_node_rename_access(
794 current_task: &CurrentTask,
795 old_parent: &FsNode,
796 moving_node: &FsNode,
797 new_parent: &FsNode,
798 replaced_node: Option<&FsNode>,
799 old_basename: &FsStr,
800 new_basename: &FsStr,
801) -> Result<(), Errno> {
802 track_hook_duration!("security.hooks.check_fs_node_rename_access");
803 if_selinux_else_default_ok(current_task, |security_server| {
804 selinux_hooks::fs_node::check_fs_node_rename_access(
805 security_server,
806 current_task,
807 old_parent,
808 moving_node,
809 new_parent,
810 replaced_node,
811 old_basename,
812 new_basename,
813 )
814 })
815}
816
817pub fn check_fs_node_read_link_access(
820 current_task: &CurrentTask,
821 fs_node: &FsNode,
822) -> Result<(), Errno> {
823 track_hook_duration!("security.hooks.check_fs_node_read_link_access");
824 if_selinux_else_default_ok(current_task, |security_server| {
825 selinux_hooks::fs_node::check_fs_node_read_link_access(
826 security_server,
827 current_task,
828 fs_node,
829 )
830 })
831}
832
833pub fn fs_node_permission(
836 current_task: &CurrentTask,
837 fs_node: &FsNode,
838 permission_flags: PermissionFlags,
839 audit_context: Auditable<'_>,
840) -> Result<(), Errno> {
841 track_hook_duration!("security.hooks.fs_node_permission");
842 if_selinux_else_default_ok(current_task, |security_server| {
843 selinux_hooks::fs_node::fs_node_permission(
844 security_server,
845 current_task,
846 fs_node,
847 permission_flags,
848 audit_context,
849 )
850 })
851}
852
853pub fn file_receive(current_task: &CurrentTask, file: &FileObject) -> Result<(), Errno> {
856 track_hook_duration!("security.hooks.file_receive");
857 if_selinux_else_default_ok(current_task, |security_server| {
858 let receiving_sid = current_task_state(current_task).current_sid;
859 selinux_hooks::file::file_receive(security_server, current_task, receiving_sid, file)
860 })
861}
862
863pub fn file_alloc_security(current_task: &CurrentTask) -> FileObjectState {
866 track_hook_duration!("security.hooks.file_alloc_security");
867 FileObjectState { state: selinux_hooks::file::file_alloc_security(current_task) }
868}
869
870pub fn binder_connection_alloc(current_task: &CurrentTask) -> BinderConnectionState {
873 track_hook_duration!("security.hooks.binder_connection_alloc");
874 BinderConnectionState { state: selinux_hooks::binder::binder_connection_alloc(current_task) }
875}
876
877pub fn bpf_map_alloc(current_task: &CurrentTask) -> BpfMapState {
881 track_hook_duration!("security.hooks.bpf_map_alloc");
882 BpfMapState { state: selinux_hooks::bpf::bpf_map_alloc(current_task) }
883}
884
885pub fn bpf_prog_alloc(current_task: &CurrentTask) -> BpfProgState {
889 track_hook_duration!("security.hooks.bpf_prog_alloc");
890 BpfProgState { state: selinux_hooks::bpf::bpf_prog_alloc(current_task) }
891}
892
893pub fn check_file_ioctl_access(
896 current_task: &CurrentTask,
897 file: &FileObject,
898 request: u32,
899) -> Result<(), Errno> {
900 track_hook_duration!("security.hooks.check_file_ioctl_access");
901 if_selinux_else_default_ok(current_task, |security_server| {
902 selinux_hooks::file::check_file_ioctl_access(security_server, current_task, file, request)
903 })
904}
905
906pub fn fs_node_copy_up(
916 current_task: &CurrentTask,
917 fs_node: &FsNode,
918 fs: &FileSystem,
919 new_creds: &mut Credentials,
920) {
921 if_selinux_else(
922 current_task,
923 |_security_server| {
924 selinux_hooks::fs_node::fs_node_copy_up(current_task, fs_node, fs, new_creds)
925 },
926 || {},
927 )
928}
929
930pub fn check_file_lock_access(current_task: &CurrentTask, file: &FileObject) -> Result<(), Errno> {
938 track_hook_duration!("security.hooks.check_file_lock_access");
939 if_selinux_else_default_ok(current_task, |security_server| {
940 selinux_hooks::file::check_file_lock_access(security_server, current_task, file)
941 })
942}
943
944pub fn check_file_fcntl_access(
947 current_task: &CurrentTask,
948 file: &FileObject,
949 fcntl_cmd: u32,
950 fcntl_arg: u64,
951) -> Result<(), Errno> {
952 track_hook_duration!("security.hooks.check_file_fcntl_access");
953 if_selinux_else_default_ok(current_task, |security_server| {
954 selinux_hooks::file::check_file_fcntl_access(
955 security_server,
956 current_task,
957 file,
958 fcntl_cmd,
959 fcntl_arg,
960 )
961 })
962}
963
964pub fn check_fs_node_setattr_access(
967 current_task: &CurrentTask,
968 node: &FsNode,
969 attributes: &zxio_node_attr_has_t,
970) -> Result<(), Errno> {
971 track_hook_duration!("security.hooks.check_fs_node_setattr_access");
972 if_selinux_else_default_ok(current_task, |security_server| {
973 selinux_hooks::fs_node::check_fs_node_setattr_access(
974 security_server,
975 current_task,
976 node,
977 attributes,
978 )
979 })
980}
981
982pub fn task_alloc_for_kernel() -> TaskAttrs {
985 track_hook_duration!("security.hooks.task_alloc_for_kernel");
986 TaskAttrs::for_kernel()
987}
988
989pub fn task_to_fs_node(current_task: &CurrentTask, task: &Task, fs_node: &FsNode) {
995 track_hook_duration!("security.hooks.task_to_fs_node");
996 if current_task.kernel().security_state.state.is_some() {
999 selinux_hooks::task::fs_node_init_with_task(task, &fs_node);
1000 }
1001}
1002
1003pub fn task_for_context(task: &Task, context: &FsStr) -> Result<TaskAttrs, Errno> {
1009 track_hook_duration!("security.hooks.task_for_context");
1010 Ok(if let Some(kernel_state) = task.kernel().security_state.state.as_ref() {
1011 selinux_hooks::task::task_alloc_from_context(&kernel_state.server, context)
1012 } else {
1013 Ok(TaskAttrs::for_selinux_disabled())
1014 }?)
1015}
1016
1017pub fn has_dontaudit_access(current_task: &CurrentTask, fs_node: &FsNode) -> bool {
1021 track_hook_duration!("security.hooks.has_dontaudit_access");
1022 if_selinux_else(
1023 current_task,
1024 |security_server| {
1025 selinux_hooks::fs_node::has_dontaudit_access(security_server, current_task, fs_node)
1026 },
1027 || false,
1028 )
1029}
1030
1031pub fn is_task_capable_noaudit(
1034 current_task: &CurrentTask,
1035 capability: starnix_uapi::auth::Capabilities,
1036) -> bool {
1037 track_hook_duration!("security.hooks.is_task_capable_noaudit");
1038 return common_cap::capable(current_task, capability).is_ok()
1039 && if_selinux_else(
1040 current_task,
1041 |security_server| {
1042 selinux_hooks::task::is_task_capable_noaudit(
1043 &selinux_hooks::build_permission_check(current_task, security_server),
1044 ¤t_task,
1045 capability,
1046 )
1047 },
1048 || true,
1049 );
1050}
1051
1052pub fn check_creds_capable(
1055 current_task: &CurrentTask,
1056 creds: &Credentials,
1057 capability: starnix_uapi::auth::Capabilities,
1058) -> Result<(), Errno> {
1059 track_hook_duration!("security.hooks.check_creds_capable");
1060 common_cap::creds_capable(creds, capability)?;
1061 if_selinux_else_default_ok(current_task, |security_server| {
1062 selinux_hooks::task::check_creds_capable(
1063 &selinux_hooks::build_permission_check(current_task, security_server),
1064 ¤t_task,
1065 creds,
1066 capability,
1067 )
1068 })
1069}
1070
1071pub fn check_task_capable(
1074 current_task: &CurrentTask,
1075 capability: starnix_uapi::auth::Capabilities,
1076) -> Result<(), Errno> {
1077 check_creds_capable(current_task, &**current_task.current_creds(), capability)
1078}
1079
1080pub fn check_task_create_access(current_task: &CurrentTask) -> Result<(), Errno> {
1083 track_hook_duration!("security.hooks.check_task_create_access");
1084 if_selinux_else_default_ok(current_task, |security_server| {
1085 selinux_hooks::task::check_task_create_access(
1086 &selinux_hooks::build_permission_check(current_task, security_server),
1087 current_task,
1088 )
1089 })
1090}
1091
1092pub fn check_socket_create_access<L>(
1095 locked: &mut Locked<L>,
1096 current_task: &CurrentTask,
1097 domain: SocketDomain,
1098 socket_type: SocketType,
1099 protocol: SocketProtocol,
1100 kernel_private: bool,
1101) -> Result<(), Errno>
1102where
1103 L: LockEqualOrBefore<FileOpsCore>,
1104{
1105 track_hook_duration!("security.hooks.socket_create");
1106 if_selinux_else_default_ok(current_task, |security_server| {
1107 selinux_hooks::socket::check_socket_create_access(
1108 locked,
1109 &security_server,
1110 current_task,
1111 domain,
1112 socket_type,
1113 protocol,
1114 kernel_private,
1115 )
1116 })
1117}
1118
1119pub fn socket_socketpair(
1122 current_task: &CurrentTask,
1123 left: DowncastedFile<'_, SocketFile>,
1124 right: DowncastedFile<'_, SocketFile>,
1125) -> Result<(), Errno> {
1126 track_hook_duration!("security.hooks.socket_socketpair");
1127 if_selinux_else_default_ok(current_task, |_| {
1128 selinux_hooks::socket::socket_socketpair(left, right)
1129 })
1130}
1131
1132pub fn socket_post_create(current_task: &CurrentTask, socket: &Socket) {
1135 track_hook_duration!("security.hooks.socket_post_create");
1136 if let Some(state) = ¤t_task.kernel().security_state.state {
1137 selinux_hooks::socket::socket_post_create(&state.server, socket);
1138 }
1139}
1140
1141pub fn check_socket_bind_access(
1144 current_task: &CurrentTask,
1145 socket: &Socket,
1146 socket_address: &SocketAddress,
1147) -> Result<(), Errno> {
1148 track_hook_duration!("security.hooks.check_socket_bind_access");
1149 if_selinux_else_default_ok(current_task, |security_server| {
1150 selinux_hooks::socket::check_socket_bind_access(
1151 &security_server,
1152 current_task,
1153 socket,
1154 socket_address,
1155 )
1156 })
1157}
1158
1159pub fn check_socket_connect_access(
1162 current_task: &CurrentTask,
1163 socket: DowncastedFile<'_, SocketFile>,
1164 socket_peer: &SocketPeer,
1165) -> Result<(), Errno> {
1166 track_hook_duration!("security.hooks.check_socket_connect_access");
1167 if_selinux_else_default_ok(current_task, |security_server| {
1168 selinux_hooks::socket::check_socket_connect_access(
1169 &security_server,
1170 current_task,
1171 socket,
1172 socket_peer,
1173 )
1174 })
1175}
1176
1177pub fn check_socket_listen_access(
1180 current_task: &CurrentTask,
1181 socket: &Socket,
1182 backlog: i32,
1183) -> Result<(), Errno> {
1184 track_hook_duration!("security.hooks.check_socket_listen_access");
1185 if_selinux_else_default_ok(current_task, |security_server| {
1186 selinux_hooks::socket::check_socket_listen_access(
1187 &security_server,
1188 current_task,
1189 socket,
1190 backlog,
1191 )
1192 })
1193}
1194
1195pub fn socket_accept(
1199 current_task: &CurrentTask,
1200 listening_socket: DowncastedFile<'_, SocketFile>,
1201 accepted_socket: DowncastedFile<'_, SocketFile>,
1202) -> Result<(), Errno> {
1203 track_hook_duration!("security.hooks.check_socket_getname_access");
1204 if_selinux_else_default_ok(current_task, |security_server| {
1205 selinux_hooks::socket::socket_accept(
1206 &security_server,
1207 current_task,
1208 listening_socket,
1209 accepted_socket,
1210 )
1211 })
1212}
1213
1214pub fn check_socket_getsockopt_access(
1217 current_task: &CurrentTask,
1218 socket: &Socket,
1219 level: u32,
1220 optname: u32,
1221) -> Result<(), Errno> {
1222 track_hook_duration!("security.hooks.check_socket_getsockopt_access");
1223 if_selinux_else_default_ok(current_task, |security_server| {
1224 selinux_hooks::socket::check_socket_getsockopt_access(
1225 &security_server,
1226 current_task,
1227 socket,
1228 level,
1229 optname,
1230 )
1231 })
1232}
1233
1234pub fn check_socket_setsockopt_access(
1237 current_task: &CurrentTask,
1238 socket: &Socket,
1239 level: u32,
1240 optname: u32,
1241) -> Result<(), Errno> {
1242 track_hook_duration!("security.hooks.check_socket_setsockopt_access");
1243 if_selinux_else_default_ok(current_task, |security_server| {
1244 selinux_hooks::socket::check_socket_setsockopt_access(
1245 &security_server,
1246 current_task,
1247 socket,
1248 level,
1249 optname,
1250 )
1251 })
1252}
1253
1254pub fn check_socket_sendmsg_access(
1257 current_task: &CurrentTask,
1258 socket: &Socket,
1259) -> Result<(), Errno> {
1260 track_hook_duration!("security.hooks.check_socket_sendmsg_access");
1261 if_selinux_else_default_ok(current_task, |security_server| {
1262 selinux_hooks::socket::check_socket_sendmsg_access(&security_server, current_task, socket)
1263 })
1264}
1265
1266pub fn check_socket_recvmsg_access(
1269 current_task: &CurrentTask,
1270 socket: &Socket,
1271) -> Result<(), Errno> {
1272 track_hook_duration!("security.hooks.check_socket_recvmsg_access");
1273 if_selinux_else_default_ok(current_task, |security_server| {
1274 selinux_hooks::socket::check_socket_recvmsg_access(&security_server, current_task, socket)
1275 })
1276}
1277
1278pub fn check_socket_getsockname_access(
1281 current_task: &CurrentTask,
1282 socket: &Socket,
1283) -> Result<(), Errno> {
1284 track_hook_duration!("security.hooks.check_socket_getname_access");
1285 if_selinux_else_default_ok(current_task, |security_server| {
1286 selinux_hooks::socket::check_socket_getname_access(&security_server, current_task, socket)
1287 })
1288}
1289
1290pub fn check_socket_getpeername_access(
1293 current_task: &CurrentTask,
1294 socket: &Socket,
1295) -> Result<(), Errno> {
1296 track_hook_duration!("security.hooks.check_socket_getname_access");
1297 if_selinux_else_default_ok(current_task, |security_server| {
1298 selinux_hooks::socket::check_socket_getname_access(&security_server, current_task, socket)
1299 })
1300}
1301
1302pub fn check_socket_shutdown_access(
1305 current_task: &CurrentTask,
1306 socket: &Socket,
1307 how: SocketShutdownFlags,
1308) -> Result<(), Errno> {
1309 track_hook_duration!("security.hooks.check_socket_shutdown_access");
1310 if_selinux_else_default_ok(current_task, |security_server| {
1311 selinux_hooks::socket::check_socket_shutdown_access(
1312 &security_server,
1313 current_task,
1314 socket,
1315 how,
1316 )
1317 })
1318}
1319
1320pub fn socket_getpeersec_stream(
1323 current_task: &CurrentTask,
1324 socket: &Socket,
1325) -> Result<Vec<u8>, Errno> {
1326 track_hook_duration!("security.hooks.socket_getpeersec_stream");
1327 if_selinux_else_default_ok(current_task, |security_server| {
1328 selinux_hooks::socket::socket_getpeersec_stream(&security_server, current_task, socket)
1329 })
1330}
1331
1332pub fn socket_getpeersec_dgram(current_task: &CurrentTask, socket: &Socket) -> Vec<u8> {
1336 track_hook_duration!("security.hooks.socket_getpeersec_dgram");
1337 if_selinux_else(
1338 current_task,
1339 |security_server| {
1340 selinux_hooks::socket::socket_getpeersec_dgram(&security_server, current_task, socket)
1341 },
1342 Vec::default,
1343 )
1344}
1345
1346pub fn unix_may_send(
1350 current_task: &CurrentTask,
1351 sending_socket: &Socket,
1352 receiving_socket: &Socket,
1353) -> Result<(), Errno> {
1354 track_hook_duration!("security.hooks.unix_may_send");
1355 if_selinux_else_default_ok(current_task, |security_server| {
1356 selinux_hooks::socket::unix_may_send(
1357 &security_server,
1358 current_task,
1359 sending_socket,
1360 receiving_socket,
1361 )
1362 })
1363}
1364
1365pub fn unix_stream_connect(
1369 current_task: &CurrentTask,
1370 client_socket: &Socket,
1371 listening_socket: &Socket,
1372 server_socket: &Socket,
1373) -> Result<(), Errno> {
1374 track_hook_duration!("security.hooks.unix_stream_connect");
1375 if_selinux_else_default_ok(current_task, |security_server| {
1376 selinux_hooks::socket::unix_stream_connect(
1377 &security_server,
1378 current_task,
1379 client_socket,
1380 listening_socket,
1381 server_socket,
1382 )
1383 })
1384}
1385
1386pub fn check_netlink_send_access(
1390 current_task: &CurrentTask,
1391 socket: &Socket,
1392 message_type: u16,
1393) -> Result<(), Errno> {
1394 track_hook_duration!("security.hooks.check_netlink_send_access");
1395 if_selinux_else_default_ok(current_task, |security_server| {
1396 selinux_hooks::netlink_socket::check_netlink_send_access(
1397 &security_server,
1398 current_task,
1399 socket,
1400 message_type,
1401 )
1402 })
1403}
1404
1405pub fn check_tun_dev_create_access(current_task: &CurrentTask) -> Result<(), Errno> {
1408 track_hook_duration!("security.hooks.check_tun_dev_create_access");
1409 if_selinux_else_default_ok(current_task, |security_server| {
1410 selinux_hooks::socket::check_tun_dev_create_access(&security_server, current_task)
1411 })
1412}
1413
1414pub fn bprm_creds_for_exec(
1420 current_task: &CurrentTask,
1421 executable: &NamespaceNode,
1422 elf_state: &mut ResolvedElf,
1423) -> Result<(), Errno> {
1424 track_hook_duration!("security.hooks.bprm_creds_for_exec");
1425 if let Some(state) = ¤t_task.kernel().security_state.state {
1426 if state.has_policy() {
1427 return selinux_hooks::task::bprm_creds_for_exec(
1428 &state.server,
1429 current_task,
1430 executable,
1431 elf_state,
1432 );
1433 } else {
1434 let previous_sid = current_task.current_creds().security_state.current_sid;
1436 elf_state.creds.security_state =
1437 TaskAttrs::for_transition(InitialSid::Init.into(), previous_sid);
1438 }
1439 }
1440 Ok(())
1441}
1442
1443pub fn bprm_committing_creds(
1449 locked: &mut Locked<Unlocked>,
1450 current_task: &CurrentTask,
1451 elf_state: &ResolvedElf,
1452) -> Result<(), Errno> {
1453 track_hook_duration!("security.hooks.bprm_committing_creds");
1454 if_selinux_else_default_ok(current_task, |security_server| {
1455 selinux_hooks::task::bprm_committing_creds(
1456 locked,
1457 security_server,
1458 current_task,
1459 elf_state,
1460 );
1461 Ok(())
1462 })
1463}
1464
1465pub fn bprm_committed_creds(
1469 _locked: &mut Locked<Unlocked>,
1470 current_task: &CurrentTask,
1471) -> Result<(), Errno> {
1472 track_hook_duration!("security.hooks.bprm_committed_creds");
1473 if_selinux_else_default_ok(current_task, |security_server| {
1474 selinux_hooks::task::bprm_committed_creds(security_server, current_task);
1475 Ok(())
1476 })
1477}
1478
1479pub fn check_task_getscheduler_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1482 track_hook_duration!("security.hooks.task_getscheduler");
1483 if_selinux_else_default_ok(source, |security_server| {
1484 selinux_hooks::task::check_getsched_access(
1485 &selinux_hooks::build_permission_check(source, security_server),
1486 &source,
1487 &target,
1488 )
1489 })
1490}
1491
1492pub fn check_task_setscheduler_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1495 track_hook_duration!("security.hooks.task_setscheduler");
1496 if_selinux_else_default_ok(source, |security_server| {
1497 selinux_hooks::task::check_setsched_access(
1498 &selinux_hooks::build_permission_check(source, security_server),
1499 &source,
1500 &target,
1501 )
1502 })
1503}
1504
1505pub fn check_task_setnice_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1508 track_hook_duration!("security.hooks.task_setnice");
1509 if_selinux_else_default_ok(source, |security_server| {
1510 selinux_hooks::task::check_setsched_access(
1511 &selinux_hooks::build_permission_check(source, security_server),
1512 &source,
1513 &target,
1514 )
1515 })
1516}
1517
1518pub fn check_getpgid_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1521 track_hook_duration!("security.hooks.check_getpgid_access");
1522 if_selinux_else_default_ok(source, |security_server| {
1523 selinux_hooks::task::check_getpgid_access(
1524 &selinux_hooks::build_permission_check(source, security_server),
1525 &source,
1526 &target,
1527 )
1528 })
1529}
1530
1531pub fn check_setpgid_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1534 track_hook_duration!("security.hooks.check_setpgid_access");
1535 if_selinux_else_default_ok(source, |security_server| {
1536 selinux_hooks::task::check_setpgid_access(
1537 &selinux_hooks::build_permission_check(source, security_server),
1538 &source,
1539 &target,
1540 )
1541 })
1542}
1543
1544pub fn check_task_getsid(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1547 track_hook_duration!("security.hooks.check_task_getsid");
1548 if_selinux_else_default_ok(source, |security_server| {
1549 selinux_hooks::task::check_task_getsid(
1550 &selinux_hooks::build_permission_check(source, security_server),
1551 &source,
1552 &target,
1553 )
1554 })
1555}
1556
1557pub fn check_getcap_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1560 track_hook_duration!("security.hooks.check_getcap_access");
1561 if_selinux_else_default_ok(source, |security_server| {
1562 selinux_hooks::task::check_getcap_access(
1563 &selinux_hooks::build_permission_check(source, security_server),
1564 &source,
1565 &target,
1566 )
1567 })
1568}
1569
1570pub fn check_setcap_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1574 track_hook_duration!("security.hooks.check_setcap_access");
1575 if_selinux_else_default_ok(source, |security_server| {
1576 selinux_hooks::task::check_setcap_access(
1577 &selinux_hooks::build_permission_check(source, security_server),
1578 &source,
1579 &target,
1580 )
1581 })
1582}
1583
1584pub fn check_signal_access(
1587 source: &CurrentTask,
1588 target: &Task,
1589 signal: Signal,
1590) -> Result<(), Errno> {
1591 track_hook_duration!("security.hooks.check_signal_access");
1592 if_selinux_else_default_ok(source, |security_server| {
1593 selinux_hooks::task::check_signal_access(
1594 &selinux_hooks::build_permission_check(source, security_server),
1595 &source,
1596 &target,
1597 signal,
1598 )
1599 })
1600}
1601
1602pub fn check_syslog_access(source: &CurrentTask, action: SyslogAction) -> Result<(), Errno> {
1605 track_hook_duration!("security.hooks.check_syslog_access");
1606 if_selinux_else_default_ok(source, |security_server| {
1607 selinux_hooks::task::check_syslog_access(
1608 &selinux_hooks::build_permission_check(source, security_server),
1609 &source,
1610 action,
1611 )
1612 })
1613}
1614
1615pub fn ptrace_traceme(current_task: &CurrentTask, parent_tracer_task: &Task) -> Result<(), Errno> {
1618 track_hook_duration!("security.hooks.ptrace_traceme");
1619 yama::ptrace_traceme(current_task, parent_tracer_task)?;
1620 common_cap::ptrace_traceme(current_task, parent_tracer_task)?;
1621 if_selinux_else_default_ok(current_task, |security_server| {
1622 selinux_hooks::task::ptrace_traceme(
1623 &selinux_hooks::build_permission_check(current_task, security_server),
1624 current_task,
1625 parent_tracer_task,
1626 )
1627 })
1628}
1629
1630pub fn ptrace_access_check(
1633 current_task: &CurrentTask,
1634 tracee_task: &Task,
1635 mode: PtraceAccessMode,
1636) -> Result<(), Errno> {
1637 track_hook_duration!("security.hooks.ptrace_access_check");
1638 yama::ptrace_access_check(current_task, tracee_task, mode)?;
1639 common_cap::ptrace_access_check(current_task, tracee_task, mode)?;
1640 if_selinux_else_default_ok(current_task, |security_server| {
1641 selinux_hooks::task::ptrace_access_check(
1642 &selinux_hooks::build_permission_check(current_task, security_server),
1643 current_task,
1644 tracee_task,
1645 mode,
1646 )
1647 })
1648}
1649
1650pub fn task_prlimit(
1653 source: &CurrentTask,
1654 target: &Task,
1655 check_get_rlimit: bool,
1656 check_set_rlimit: bool,
1657) -> Result<(), Errno> {
1658 track_hook_duration!("security.hooks.task_prlimit");
1659 if_selinux_else_default_ok(source, |security_server| {
1660 selinux_hooks::task::task_prlimit(
1661 &selinux_hooks::build_permission_check(source, security_server),
1662 &source,
1663 &target,
1664 check_get_rlimit,
1665 check_set_rlimit,
1666 )
1667 })
1668}
1669
1670pub fn task_setrlimit(
1673 source: &CurrentTask,
1674 target: &Task,
1675 old_limit: rlimit,
1676 new_limit: rlimit,
1677) -> Result<(), Errno> {
1678 track_hook_duration!("security.hooks.task_setrlimit");
1679 if_selinux_else_default_ok(source, |security_server| {
1680 selinux_hooks::task::task_setrlimit(
1681 &selinux_hooks::build_permission_check(source, security_server),
1682 &source,
1683 &target,
1684 old_limit,
1685 new_limit,
1686 )
1687 })
1688}
1689
1690pub fn sb_kern_mount(current_task: &CurrentTask, fs: &FileSystem) -> Result<(), Errno> {
1693 track_hook_duration!("security.hooks.sb_kern_mount");
1694 if_selinux_else_default_ok(current_task, |security_server| {
1695 selinux_hooks::superblock::sb_kern_mount(
1696 &selinux_hooks::build_permission_check(current_task, security_server),
1697 current_task,
1698 fs,
1699 )
1700 })
1701}
1702
1703pub fn sb_mount(
1707 current_task: &CurrentTask,
1708 path: &NamespaceNode,
1709 flags: MountFlags,
1710) -> Result<(), Errno> {
1711 track_hook_duration!("security.hooks.sb_mount");
1712 if_selinux_else_default_ok(current_task, |security_server| {
1713 selinux_hooks::superblock::sb_mount(
1714 &selinux_hooks::build_permission_check(current_task, security_server),
1715 current_task,
1716 path,
1717 flags,
1718 )
1719 })
1720}
1721
1722pub fn sb_remount(
1725 current_task: &CurrentTask,
1726 mount: &Mount,
1727 new_mount_options: FileSystemMountOptions,
1728) -> Result<(), Errno> {
1729 track_hook_duration!("security.hooks.sb_remount");
1730 if_selinux_else_default_ok(current_task, |security_server| {
1731 selinux_hooks::superblock::sb_remount(security_server, mount, new_mount_options)
1732 })
1733}
1734
1735pub fn sb_show_options<'a>(
1738 _kernel: &Kernel,
1739 fs: &'a FileSystem,
1740) -> Result<impl std::fmt::Display + 'a, Errno> {
1741 track_hook_duration!("security.hooks.sb_show_options");
1742 selinux_hooks::superblock::sb_show_options(fs)
1743}
1744
1745pub fn sb_statfs(current_task: &CurrentTask, fs: &FileSystem) -> Result<(), Errno> {
1748 track_hook_duration!("security.hooks.sb_statfs");
1749 if_selinux_else_default_ok(current_task, |security_server| {
1750 selinux_hooks::superblock::sb_statfs(
1751 &selinux_hooks::build_permission_check(current_task, security_server),
1752 current_task,
1753 fs,
1754 )
1755 })
1756}
1757
1758pub fn sb_umount(
1762 current_task: &CurrentTask,
1763 node: &NamespaceNode,
1764 flags: UnmountFlags,
1765) -> Result<(), Errno> {
1766 track_hook_duration!("security.hooks.sb_umount");
1767 if_selinux_else_default_ok(current_task, |security_server| {
1768 selinux_hooks::superblock::sb_umount(
1769 &selinux_hooks::build_permission_check(current_task, security_server),
1770 current_task,
1771 node,
1772 flags,
1773 )
1774 })
1775}
1776
1777pub fn check_fs_node_getattr_access(
1780 current_task: &CurrentTask,
1781 fs_node: &FsNode,
1782) -> Result<(), Errno> {
1783 track_hook_duration!("security.hooks.check_fs_node_getattr_access");
1784 if_selinux_else_default_ok(current_task, |security_server| {
1785 selinux_hooks::fs_node::check_fs_node_getattr_access(security_server, current_task, fs_node)
1786 })
1787}
1788
1789pub fn fs_node_xattr_skipcap(_current_task: &CurrentTask, name: &FsStr) -> bool {
1792 selinux_hooks::fs_node::fs_node_xattr_skipcap(name)
1793}
1794
1795pub fn check_fs_node_setxattr_access(
1801 current_task: &CurrentTask,
1802 fs_node: &FsNode,
1803 name: &FsStr,
1804 value: &FsStr,
1805 op: XattrOp,
1806) -> Result<(), Errno> {
1807 track_hook_duration!("security.hooks.check_fs_node_setxattr_access");
1808 common_cap::fs_node_setxattr(current_task, fs_node, name, value, op)?;
1809 if_selinux_else_default_ok(current_task, |security_server| {
1810 selinux_hooks::fs_node::check_fs_node_setxattr_access(
1811 security_server,
1812 current_task,
1813 fs_node,
1814 name,
1815 value,
1816 op,
1817 )
1818 })
1819}
1820
1821pub fn check_fs_node_getxattr_access(
1823 current_task: &CurrentTask,
1824 fs_node: &FsNode,
1825 name: &FsStr,
1826) -> Result<(), Errno> {
1827 track_hook_duration!("security.hooks.check_fs_node_getxattr_access");
1828 if_selinux_else_default_ok(current_task, |security_server| {
1829 selinux_hooks::fs_node::check_fs_node_getxattr_access(
1830 security_server,
1831 current_task,
1832 fs_node,
1833 name,
1834 )
1835 })
1836}
1837
1838pub fn check_fs_node_listxattr_access(
1840 current_task: &CurrentTask,
1841 fs_node: &FsNode,
1842) -> Result<(), Errno> {
1843 track_hook_duration!("security.hooks.check_fs_node_listxattr_access");
1844 if_selinux_else_default_ok(current_task, |security_server| {
1845 selinux_hooks::fs_node::check_fs_node_listxattr_access(
1846 security_server,
1847 current_task,
1848 fs_node,
1849 )
1850 })
1851}
1852
1853pub fn check_fs_node_removexattr_access(
1855 current_task: &CurrentTask,
1856 fs_node: &FsNode,
1857 name: &FsStr,
1858) -> Result<(), Errno> {
1859 track_hook_duration!("security.hooks.check_fs_node_removexattr_access");
1860 common_cap::fs_node_removexattr(current_task, fs_node, name)?;
1861 if_selinux_else_default_ok(current_task, |security_server| {
1862 selinux_hooks::fs_node::check_fs_node_removexattr_access(
1863 security_server,
1864 current_task,
1865 fs_node,
1866 name,
1867 )
1868 })
1869}
1870
1871pub fn fs_node_listsecurity(current_task: &CurrentTask, fs_node: &FsNode) -> Option<FsString> {
1878 track_hook_duration!("security.hooks.fs_node_listsecurity");
1879 if_selinux_else(
1880 current_task,
1881 |_| selinux_hooks::fs_node::fs_node_listsecurity(fs_node),
1882 || None,
1883 )
1884}
1885
1886pub fn fs_node_getsecurity<L>(
1894 locked: &mut Locked<L>,
1895 current_task: &CurrentTask,
1896 fs_node: &FsNode,
1897 name: &FsStr,
1898 max_size: usize,
1899) -> Result<ValueOrSize<FsString>, Errno>
1900where
1901 L: LockEqualOrBefore<FileOpsCore>,
1902{
1903 track_hook_duration!("security.hooks.fs_node_getsecurity");
1904 if_selinux_else_with_context(
1905 locked,
1906 current_task,
1907 |locked, security_server| {
1908 selinux_hooks::fs_node::fs_node_getsecurity(
1909 locked,
1910 security_server,
1911 current_task,
1912 fs_node,
1913 name,
1914 max_size,
1915 )
1916 },
1917 |locked| {
1918 fs_node.ops().get_xattr(
1919 locked.cast_locked::<FileOpsCore>(),
1920 fs_node,
1921 current_task,
1922 name,
1923 max_size,
1924 )
1925 },
1926 )
1927}
1928
1929pub fn fs_node_setsecurity<L>(
1935 locked: &mut Locked<L>,
1936 current_task: &CurrentTask,
1937 fs_node: &FsNode,
1938 name: &FsStr,
1939 value: &FsStr,
1940 op: XattrOp,
1941) -> Result<(), Errno>
1942where
1943 L: LockEqualOrBefore<FileOpsCore>,
1944{
1945 track_hook_duration!("security.hooks.fs_node_setsecurity");
1946 if_selinux_else_with_context(
1947 locked,
1948 current_task,
1949 |locked, security_server| {
1950 selinux_hooks::fs_node::fs_node_setsecurity(
1951 locked,
1952 security_server,
1953 current_task,
1954 fs_node,
1955 name,
1956 value,
1957 op,
1958 )
1959 },
1960 |locked| {
1961 fs_node.ops().set_xattr(
1962 locked.cast_locked::<FileOpsCore>(),
1963 fs_node,
1964 current_task,
1965 name,
1966 value,
1967 op,
1968 )
1969 },
1970 )
1971}
1972
1973pub fn check_bpf_access<Attr: FromBytes>(
1977 current_task: &CurrentTask,
1978 cmd: bpf_cmd,
1979 attr: &Attr,
1980 attr_size: u32,
1981) -> Result<(), Errno> {
1982 track_hook_duration!("security.hooks.check_bpf_access");
1983 if_selinux_else_default_ok(current_task, |security_server| {
1984 selinux_hooks::bpf::check_bpf_access(security_server, current_task, cmd, attr, attr_size)
1985 })
1986}
1987
1988pub fn check_bpf_map_access(
1992 current_task: &CurrentTask,
1993 bpf_map_state: &BpfMapState,
1994 flags: PermissionFlags,
1995) -> Result<(), Errno> {
1996 track_hook_duration!("security.hooks.check_bpf_map_access");
1997 if_selinux_else_default_ok(current_task, |security_server| {
1998 let subject_sid = current_task_state(current_task).current_sid;
1999 selinux_hooks::bpf::check_bpf_map_access(
2000 security_server,
2001 current_task,
2002 subject_sid,
2003 bpf_map_state,
2004 flags,
2005 )
2006 })
2007}
2008
2009pub fn check_bpf_prog_access(
2014 current_task: &CurrentTask,
2015 bpf_program_state: &BpfProgState,
2016) -> Result<(), Errno> {
2017 track_hook_duration!("security.hooks.check_bpf_prog_access");
2018 if_selinux_else_default_ok(current_task, |security_server| {
2019 let subject_sid = current_task_state(current_task).current_sid;
2020 selinux_hooks::bpf::check_bpf_prog_access(
2021 security_server,
2022 current_task,
2023 subject_sid,
2024 bpf_program_state,
2025 )
2026 })
2027}
2028
2029pub fn check_perf_event_open_access(
2033 current_task: &CurrentTask,
2034 target_task_type: TargetTaskType<'_>,
2035 attr: &perf_event_attr,
2036 event_type: PerfEventType,
2037) -> Result<(), Errno> {
2038 track_hook_duration!("security.hooks.check_perf_event_open_access");
2039 if_selinux_else_default_ok(current_task, |security_server| {
2040 selinux_hooks::perf_event::check_perf_event_open_access(
2041 security_server,
2042 current_task,
2043 target_task_type,
2044 attr,
2045 event_type,
2046 )
2047 })
2048}
2049
2050pub fn perf_event_alloc(current_task: &CurrentTask) -> PerfEventState {
2054 track_hook_duration!("security.hooks.perf_event_alloc");
2055 PerfEventState { state: selinux_hooks::perf_event::perf_event_alloc(current_task) }
2056}
2057
2058pub fn check_perf_event_read_access(
2061 current_task: &CurrentTask,
2062 perf_event_file: &PerfEventFile,
2063) -> Result<(), Errno> {
2064 track_hook_duration!("security.hooks.check_perf_event_read_access");
2065 if_selinux_else_default_ok(current_task, |security_server| {
2066 selinux_hooks::perf_event::check_perf_event_read_access(
2067 security_server,
2068 current_task,
2069 perf_event_file,
2070 )
2071 })
2072}
2073
2074pub fn check_perf_event_write_access(
2077 current_task: &CurrentTask,
2078 perf_event_file: &PerfEventFile,
2079) -> Result<(), Errno> {
2080 track_hook_duration!("security.hooks.check_perf_event_write_access");
2081 if_selinux_else_default_ok(current_task, |security_server| {
2082 selinux_hooks::perf_event::check_perf_event_write_access(
2083 security_server,
2084 current_task,
2085 perf_event_file,
2086 )
2087 })
2088}
2089
2090#[derive(Debug, Clone, Copy, PartialEq)]
2092pub enum ProcAttr {
2093 Current,
2094 Exec,
2095 FsCreate,
2096 KeyCreate,
2097 Previous,
2098 SockCreate,
2099}
2100
2101pub fn get_procattr(
2104 current_task: &CurrentTask,
2105 target: &Task,
2106 attr: ProcAttr,
2107) -> Result<Vec<u8>, Errno> {
2108 track_hook_duration!("security.hooks.get_procattr");
2109 if_selinux_else(
2110 current_task,
2111 |security_server| {
2112 selinux_hooks::task::get_procattr(security_server, current_task, target, attr)
2113 },
2114 || error!(EINVAL),
2116 )
2117}
2118
2119pub fn set_procattr(
2122 current_task: &CurrentTask,
2123 attr: ProcAttr,
2124 context: &[u8],
2125) -> Result<(), Errno> {
2126 track_hook_duration!("security.hooks.set_procattr");
2127 if_selinux_else(
2128 current_task,
2129 |security_server| {
2130 selinux_hooks::task::set_procattr(security_server, current_task, attr, context)
2131 },
2132 || error!(EINVAL),
2134 )
2135}
2136
2137pub fn fs_is_xattr_labeled(fs: FileSystemHandle) -> bool {
2139 fs.security_state.state.supports_xattr()
2140}
2141
2142pub fn selinuxfs_init_null(current_task: &CurrentTask, null_fs_node: &FileHandle) {
2145 selinux_hooks::selinuxfs::selinuxfs_init_null(current_task, null_fs_node)
2148}
2149
2150pub fn selinuxfs_policy_loaded<L>(locked: &mut Locked<L>, current_task: &CurrentTask)
2156where
2157 L: LockEqualOrBefore<FileOpsCore>,
2158{
2159 track_hook_duration!("security.hooks.selinuxfs_policy_loaded");
2160 selinux_hooks::selinuxfs::selinuxfs_policy_loaded(locked, current_task)
2161}
2162
2163pub fn selinuxfs_get_admin_api(current_task: &CurrentTask) -> Option<Arc<SecurityServer>> {
2167 current_task.kernel().security_state.state.as_ref().map(|state| state.server.clone())
2168}
2169
2170pub fn selinuxfs_check_access(
2173 current_task: &CurrentTask,
2174 permission: SecurityPermission,
2175) -> Result<(), Errno> {
2176 track_hook_duration!("security.hooks.selinuxfs_check_access");
2177 if_selinux_else_default_ok(current_task, |security_server| {
2178 selinux_hooks::selinuxfs::selinuxfs_check_access(security_server, current_task, permission)
2179 })
2180}
2181
2182pub fn creds_start_internal_operation(current_task: &CurrentTask) -> Arc<Credentials> {
2185 track_hook_duration!("security.hooks.creds_start_internal_operation");
2186 let mut creds = Credentials::clone(¤t_task.current_creds());
2187 creds.security_state.internal_operation = true;
2188 creds.into()
2189}
2190
2191pub mod testing {
2192 use super::{Arc, KernelState, SecurityServer, selinux_hooks};
2193 use starnix_sync::LockDepMutex;
2194 use std::sync::OnceLock;
2195 use std::sync::atomic::AtomicU64;
2196
2197 pub fn kernel_state(security_server: Option<Arc<SecurityServer>>) -> KernelState {
2200 let state = security_server.map(|server| selinux_hooks::KernelState {
2201 server,
2202 pending_file_systems: LockDepMutex::default(),
2203 selinuxfs_null: OnceLock::default(),
2204 access_denial_count: AtomicU64::new(0u64),
2205 has_policy: false.into(),
2206 _inspect_node: fuchsia_inspect::Node::default(),
2207 });
2208 KernelState { state }
2209 }
2210}
2211
2212#[cfg(test)]
2213mod tests {
2214 use super::*;
2215 use crate::security;
2216 use crate::security::selinux_hooks::get_cached_sid;
2217 use crate::security::selinux_hooks::testing::{
2218 self, spawn_kernel_with_selinux_hooks_test_policy_and_run,
2219 };
2220 use crate::testing::{create_task, spawn_kernel_and_run, spawn_kernel_with_selinux_and_run};
2221 use linux_uapi::XATTR_NAME_SELINUX;
2222 use selinux::InitialSid;
2223 use starnix_uapi::auth::PTRACE_MODE_ATTACH;
2224 use starnix_uapi::signals::SIGTERM;
2225
2226 const VALID_SECURITY_CONTEXT: &[u8] = b"u:object_r:test_valid_t:s0";
2227 const VALID_SECURITY_CONTEXT_WITH_NUL: &[u8] = b"u:object_r:test_valid_t:s0\0";
2228
2229 const DIFFERENT_VALID_SECURITY_CONTEXT: &[u8] = b"u:object_r:test_different_valid_t:s0";
2230 const DIFFERENT_VALID_SECURITY_CONTEXT_WITH_NUL: &[u8] =
2231 b"u:object_r:test_different_valid_t:s0\0";
2232
2233 const INVALID_SECURITY_CONTEXT_INTERNAL_NUL: &[u8] = b"u:object_r:test_valid_\0t:s0";
2234
2235 const INVALID_SECURITY_CONTEXT: &[u8] = b"not_a_u:object_r:test_valid_t:s0";
2236
2237 #[derive(Default, Debug, PartialEq)]
2238 enum TestHookResult {
2239 WasRun,
2240 WasNotRun,
2241 #[default]
2242 WasNotRunDefault,
2243 }
2244
2245 #[fuchsia::test]
2246 async fn if_selinux_else_disabled() {
2247 spawn_kernel_and_run(async |_, current_task| {
2248 assert!(current_task.kernel().security_state.state.is_none());
2249
2250 let check_result =
2251 if_selinux_else_default_ok(current_task, |_| Ok(TestHookResult::WasRun));
2252 assert_eq!(check_result, Ok(TestHookResult::WasNotRunDefault));
2253
2254 let run_else_result = if_selinux_else(
2255 current_task,
2256 |_| TestHookResult::WasRun,
2257 || TestHookResult::WasNotRun,
2258 );
2259 assert_eq!(run_else_result, TestHookResult::WasNotRun);
2260 })
2261 .await;
2262 }
2263
2264 #[fuchsia::test]
2265 async fn if_selinux_else_without_policy() {
2266 spawn_kernel_with_selinux_and_run(async |_locked, current_task, _security_server| {
2267 let check_result =
2268 if_selinux_else_default_ok(current_task, |_| Ok(TestHookResult::WasRun));
2269 assert_eq!(check_result, Ok(TestHookResult::WasNotRunDefault));
2270
2271 let run_else_result = if_selinux_else(
2272 current_task,
2273 |_| TestHookResult::WasRun,
2274 || TestHookResult::WasNotRun,
2275 );
2276 assert_eq!(run_else_result, TestHookResult::WasNotRun);
2277 })
2278 .await;
2279 }
2280
2281 #[fuchsia::test]
2282 async fn if_selinux_else_with_policy() {
2283 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2284 |_locked, current_task, _security_server| {
2285 let check_result =
2286 if_selinux_else_default_ok(current_task, |_| Ok(TestHookResult::WasRun));
2287 assert_eq!(check_result, Ok(TestHookResult::WasRun));
2288
2289 let run_else_result = if_selinux_else(
2290 current_task,
2291 |_| TestHookResult::WasRun,
2292 || TestHookResult::WasNotRun,
2293 );
2294 assert_eq!(run_else_result, TestHookResult::WasRun);
2295 },
2296 )
2297 .await;
2298 }
2299
2300 #[fuchsia::test]
2301 async fn task_create_access_allowed_for_selinux_disabled() {
2302 spawn_kernel_and_run(async |_, current_task| {
2303 assert!(current_task.kernel().security_state.state.is_none());
2304 assert_eq!(check_task_create_access(current_task), Ok(()));
2305 })
2306 .await;
2307 }
2308
2309 #[fuchsia::test]
2310 async fn task_create_access_allowed_for_permissive_mode() {
2311 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2312 |_locked, current_task, security_server| {
2313 security_server.set_enforcing(false);
2314 assert_eq!(check_task_create_access(current_task), Ok(()));
2315 },
2316 )
2317 .await;
2318 }
2319
2320 #[fuchsia::test]
2321 async fn exec_access_allowed_for_selinux_disabled() {
2322 spawn_kernel_and_run(async |locked, current_task| {
2323 assert!(current_task.kernel().security_state.state.is_none());
2324 let executable = testing::create_test_file(locked, current_task);
2325 let mut resolved_elf =
2326 testing::make_resolved_elf(locked, current_task, executable.clone());
2327 assert_eq!(bprm_creds_for_exec(current_task, &executable, &mut resolved_elf), Ok(()));
2328 })
2329 .await;
2330 }
2331
2332 #[fuchsia::test]
2333 async fn exec_access_allowed_for_permissive_mode() {
2334 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2335 |locked, current_task, security_server| {
2336 security_server.set_enforcing(false);
2337 let executable = testing::create_test_file(locked, current_task);
2338 let mut resolved_elf =
2339 testing::make_resolved_elf(locked, current_task, executable.clone());
2340 let result = bprm_creds_for_exec(current_task, &executable, &mut resolved_elf);
2342 assert!(result.is_ok());
2343 },
2344 )
2345 .await;
2346 }
2347
2348 #[fuchsia::test]
2349 async fn exec_no_state_update_for_selinux_disabled() {
2350 spawn_kernel_and_run(async |locked, current_task| {
2351 let target_sid = InitialSid::Unlabeled.into();
2352
2353 assert!(selinux_hooks::current_task_state(current_task).current_sid != target_sid);
2354
2355 testing::mutate_attrs_for_test(current_task, |attrs| {
2357 attrs.exec_sid = Some(target_sid);
2358 });
2359
2360 let executable = testing::create_test_file(locked, current_task);
2361 let mut resolved_elf =
2362 testing::make_resolved_elf(locked, current_task, executable.clone());
2363
2364 let before_hook_sid = selinux_hooks::current_task_state(current_task).current_sid;
2365
2366 bprm_creds_for_exec(current_task, &executable, &mut resolved_elf).unwrap();
2367 assert_eq!(resolved_elf.creds.security_state.current_sid, before_hook_sid);
2368 })
2369 .await;
2370 }
2371
2372 #[fuchsia::test]
2373 async fn exec_initial_context_for_selinux_without_policy() {
2374 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2375 let elf_sid = InitialSid::Unlabeled.into();
2376 assert_ne!(selinux_hooks::current_task_state(current_task).current_sid, elf_sid);
2377 assert_ne!(
2378 selinux_hooks::current_task_state(current_task).current_sid,
2379 InitialSid::Init.into()
2380 );
2381
2382 testing::mutate_attrs_for_test(current_task, |attrs| {
2384 attrs.exec_sid = Some(elf_sid);
2385 });
2386
2387 let executable = testing::create_test_file(locked, current_task);
2388 let mut resolved_elf =
2389 testing::make_resolved_elf(locked, current_task, executable.clone());
2390
2391 bprm_creds_for_exec(current_task, &executable, &mut resolved_elf).unwrap();
2392
2393 assert_eq!(resolved_elf.creds.security_state.current_sid, InitialSid::Init.into());
2394 })
2395 .await;
2396 }
2397
2398 #[fuchsia::test]
2399 async fn exec_state_update_for_permissive_mode() {
2400 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2401 |locked, current_task, security_server| {
2402 security_server.set_enforcing(false);
2403 let elf_sid = security_server
2404 .security_context_to_sid(b"u:object_r:fork_no_t:s0".into())
2405 .expect("invalid security context");
2406
2407 assert_ne!(elf_sid, selinux_hooks::current_task_state(current_task).current_sid);
2408
2409 testing::mutate_attrs_for_test(current_task, |attrs| {
2411 attrs.exec_sid = Some(elf_sid);
2412 });
2413
2414 let executable = testing::create_test_file(locked, current_task);
2415 let mut resolved_elf =
2416 testing::make_resolved_elf(locked, current_task, executable.clone());
2417
2418 bprm_creds_for_exec(current_task, &executable, &mut resolved_elf).unwrap();
2419 assert_eq!(resolved_elf.creds.security_state.current_sid, elf_sid);
2420 },
2421 )
2422 .await;
2423 }
2424
2425 #[fuchsia::test]
2426 async fn getsched_access_allowed_for_selinux_disabled() {
2427 spawn_kernel_and_run(async |locked, current_task| {
2428 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2429 assert_eq!(check_task_getscheduler_access(current_task, &another_task), Ok(()));
2430 })
2431 .await;
2432 }
2433
2434 #[fuchsia::test]
2435 async fn getsched_access_allowed_for_permissive_mode() {
2436 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2437 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2438 assert_eq!(check_task_getscheduler_access(current_task, &another_task), Ok(()));
2439 })
2440 .await;
2441 }
2442
2443 #[fuchsia::test]
2444 async fn setsched_access_allowed_for_selinux_disabled() {
2445 spawn_kernel_and_run(async |locked, current_task| {
2446 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2447 assert_eq!(check_task_setscheduler_access(current_task, &another_task), Ok(()));
2448 })
2449 .await;
2450 }
2451
2452 #[fuchsia::test]
2453 async fn setsched_access_allowed_for_permissive_mode() {
2454 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2455 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2456 assert_eq!(check_task_setscheduler_access(current_task, &another_task), Ok(()));
2457 })
2458 .await;
2459 }
2460
2461 #[fuchsia::test]
2462 async fn getpgid_access_allowed_for_selinux_disabled() {
2463 spawn_kernel_and_run(async |locked, current_task| {
2464 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2465 assert_eq!(check_getpgid_access(current_task, &another_task), Ok(()));
2466 })
2467 .await;
2468 }
2469
2470 #[fuchsia::test]
2471 async fn getpgid_access_allowed_for_permissive_mode() {
2472 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2473 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2474 assert_eq!(check_getpgid_access(current_task, &another_task), Ok(()));
2475 })
2476 .await;
2477 }
2478
2479 #[fuchsia::test]
2480 async fn setpgid_access_allowed_for_selinux_disabled() {
2481 spawn_kernel_and_run(async |locked, current_task| {
2482 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2483 assert_eq!(check_setpgid_access(current_task, &another_task), Ok(()));
2484 })
2485 .await;
2486 }
2487
2488 #[fuchsia::test]
2489 async fn setpgid_access_allowed_for_permissive_mode() {
2490 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2491 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2492 assert_eq!(check_setpgid_access(current_task, &another_task), Ok(()));
2493 })
2494 .await;
2495 }
2496
2497 #[fuchsia::test]
2498 async fn task_getsid_allowed_for_selinux_disabled() {
2499 spawn_kernel_and_run(async |locked, current_task| {
2500 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2501 assert_eq!(check_task_getsid(current_task, &another_task), Ok(()));
2502 })
2503 .await;
2504 }
2505
2506 #[fuchsia::test]
2507 async fn task_getsid_allowed_for_permissive_mode() {
2508 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2509 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2510 assert_eq!(check_task_getsid(current_task, &another_task), Ok(()));
2511 })
2512 .await;
2513 }
2514
2515 #[fuchsia::test]
2516 async fn signal_access_allowed_for_selinux_disabled() {
2517 spawn_kernel_and_run(async |locked, current_task| {
2518 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2519 assert_eq!(check_signal_access(current_task, &another_task, SIGTERM), Ok(()));
2520 })
2521 .await;
2522 }
2523
2524 #[fuchsia::test]
2525 async fn signal_access_allowed_for_permissive_mode() {
2526 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2527 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2528 assert_eq!(check_signal_access(current_task, &another_task, SIGTERM), Ok(()));
2529 })
2530 .await;
2531 }
2532
2533 #[fuchsia::test]
2534 async fn ptrace_traceme_access_allowed_for_selinux_disabled() {
2535 spawn_kernel_and_run(async |locked, current_task| {
2536 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2537 assert_eq!(ptrace_traceme(current_task, &another_task), Ok(()));
2538 })
2539 .await;
2540 }
2541
2542 #[fuchsia::test]
2543 async fn ptrace_traceme_access_allowed_for_permissive_mode() {
2544 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2545 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2546 assert_eq!(ptrace_traceme(current_task, &another_task), Ok(()));
2547 })
2548 .await;
2549 }
2550
2551 #[fuchsia::test]
2552 async fn ptrace_attach_access_allowed_for_selinux_disabled() {
2553 spawn_kernel_and_run(async |locked, current_task| {
2554 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2555 assert_eq!(
2556 ptrace_access_check(current_task, &another_task, PTRACE_MODE_ATTACH),
2557 Ok(())
2558 );
2559 })
2560 .await;
2561 }
2562
2563 #[fuchsia::test]
2564 async fn ptrace_attach_access_allowed_for_permissive_mode() {
2565 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2566 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2567 assert_eq!(
2568 ptrace_access_check(current_task, &another_task, PTRACE_MODE_ATTACH),
2569 Ok(())
2570 );
2571 })
2572 .await;
2573 }
2574
2575 #[fuchsia::test]
2576 async fn task_prlimit_access_allowed_for_selinux_disabled() {
2577 spawn_kernel_and_run(async |locked, current_task| {
2578 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2579 assert_eq!(task_prlimit(current_task, &another_task, true, true), Ok(()));
2580 })
2581 .await;
2582 }
2583
2584 #[fuchsia::test]
2585 async fn task_prlimit_access_allowed_for_permissive_mode() {
2586 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2587 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2588 assert_eq!(task_prlimit(current_task, &another_task, true, true), Ok(()));
2589 })
2590 .await;
2591 }
2592
2593 #[fuchsia::test]
2594 async fn fs_node_task_to_fs_node_noop_selinux_disabled() {
2595 spawn_kernel_and_run(async |locked, current_task| {
2596 let node = &testing::create_test_file(locked, current_task).entry.node;
2597 task_to_fs_node(current_task, ¤t_task.task, &node);
2598 assert_eq!(None, selinux_hooks::get_cached_sid(node));
2599 })
2600 .await;
2601 }
2602
2603 #[fuchsia::test]
2604 async fn fs_node_setsecurity_selinux_disabled_only_sets_xattr() {
2605 spawn_kernel_and_run(async |locked, current_task| {
2606 let node = &testing::create_test_file(locked, current_task).entry.node;
2607
2608 fs_node_setsecurity(
2609 locked,
2610 current_task,
2611 &node,
2612 XATTR_NAME_SELINUX.to_bytes().into(),
2613 VALID_SECURITY_CONTEXT.into(),
2614 XattrOp::Set,
2615 )
2616 .expect("set_xattr(security.selinux) failed");
2617
2618 assert_eq!(None, selinux_hooks::get_cached_sid(node));
2619 })
2620 .await;
2621 }
2622
2623 #[fuchsia::test]
2624 async fn fs_node_setsecurity_selinux_without_policy_only_sets_xattr() {
2625 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2626 let node = &testing::create_test_file(locked, current_task).entry.node;
2627 fs_node_setsecurity(
2628 locked,
2629 current_task,
2630 &node,
2631 XATTR_NAME_SELINUX.to_bytes().into(),
2632 VALID_SECURITY_CONTEXT.into(),
2633 XattrOp::Set,
2634 )
2635 .expect("set_xattr(security.selinux) failed");
2636
2637 assert_eq!(None, selinux_hooks::get_cached_sid(node));
2638 })
2639 .await;
2640 }
2641
2642 #[fuchsia::test]
2643 async fn fs_node_setsecurity_selinux_permissive_sets_xattr_and_label() {
2644 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2645 |locked, current_task, security_server| {
2646 security_server.set_enforcing(false);
2647 let expected_sid = security_server
2648 .security_context_to_sid(VALID_SECURITY_CONTEXT.into())
2649 .expect("no SID for VALID_SECURITY_CONTEXT");
2650 let node = &testing::create_test_file(locked, ¤t_task).entry.node;
2651
2652 assert_ne!(Some(expected_sid), selinux_hooks::get_cached_sid(node));
2654
2655 fs_node_setsecurity(
2656 locked,
2657 current_task,
2658 &node,
2659 XATTR_NAME_SELINUX.to_bytes().into(),
2660 VALID_SECURITY_CONTEXT.into(),
2661 XattrOp::Set,
2662 )
2663 .expect("set_xattr(security.selinux) failed");
2664
2665 assert_eq!(Some(expected_sid), selinux_hooks::get_cached_sid(node));
2668 },
2669 )
2670 .await;
2671 }
2672
2673 #[fuchsia::test]
2674 async fn fs_node_setsecurity_not_selinux_only_sets_xattr() {
2675 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2676 |locked, current_task, security_server| {
2677 let valid_security_context_sid = security_server
2678 .security_context_to_sid(VALID_SECURITY_CONTEXT.into())
2679 .expect("no SID for VALID_SECURITY_CONTEXT");
2680 let node = &testing::create_test_file(locked, current_task).entry.node;
2681 let whatever_sid = selinux_hooks::get_cached_sid(node);
2685 assert_ne!(Some(valid_security_context_sid), whatever_sid);
2686
2687 fs_node_setsecurity(
2688 locked,
2689 current_task,
2690 &node,
2691 "security.selinu!".into(), VALID_SECURITY_CONTEXT.into(),
2693 XattrOp::Set,
2694 )
2695 .expect("set_xattr(security.selinux) failed");
2696
2697 assert_eq!(whatever_sid, selinux_hooks::get_cached_sid(node));
2699 },
2700 )
2701 .await;
2702 }
2703
2704 #[fuchsia::test]
2705 async fn fs_node_setsecurity_selinux_enforcing_invalid_context_fails() {
2706 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2707 |locked, current_task, _security_server| {
2708 let node = &testing::create_test_file(locked, current_task).entry.node;
2709
2710 let before_sid = selinux_hooks::get_cached_sid(node);
2711 assert_ne!(Some(InitialSid::Unlabeled.into()), before_sid);
2712
2713 assert!(
2714 check_fs_node_setxattr_access(
2715 ¤t_task,
2716 &node,
2717 XATTR_NAME_SELINUX.to_bytes().into(),
2718 "!".into(), XattrOp::Set,
2720 )
2721 .is_err()
2722 );
2723
2724 assert_eq!(before_sid, selinux_hooks::get_cached_sid(node));
2725 },
2726 )
2727 .await;
2728 }
2729
2730 #[fuchsia::test]
2731 async fn fs_node_setsecurity_selinux_permissive_invalid_context_sets_xattr_and_label() {
2732 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2733 |locked, current_task, security_server| {
2734 security_server.set_enforcing(false);
2735 let node = &testing::create_test_file(locked, current_task).entry.node;
2736
2737 assert_ne!(Some(InitialSid::Unlabeled.into()), selinux_hooks::get_cached_sid(node));
2738
2739 fs_node_setsecurity(
2740 locked,
2741 current_task,
2742 &node,
2743 XATTR_NAME_SELINUX.to_bytes().into(),
2744 "!".into(), XattrOp::Set,
2746 )
2747 .expect("set_xattr(security.selinux) failed");
2748
2749 assert_eq!(Some(InitialSid::Unlabeled.into()), selinux_hooks::get_cached_sid(node));
2750 },
2751 )
2752 .await;
2753 }
2754
2755 #[fuchsia::test]
2756 async fn fs_node_setsecurity_different_sid_for_different_context() {
2757 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2758 |locked, current_task, _security_server| {
2759 let node = &testing::create_test_file(locked, current_task).entry.node;
2760
2761 fs_node_setsecurity(
2762 locked,
2763 current_task,
2764 &node,
2765 XATTR_NAME_SELINUX.to_bytes().into(),
2766 VALID_SECURITY_CONTEXT.into(),
2767 XattrOp::Set,
2768 )
2769 .expect("set_xattr(security.selinux) failed");
2770
2771 assert!(selinux_hooks::get_cached_sid(node).is_some());
2772
2773 let first_sid = selinux_hooks::get_cached_sid(node).unwrap();
2774 fs_node_setsecurity(
2775 locked,
2776 current_task,
2777 &node,
2778 XATTR_NAME_SELINUX.to_bytes().into(),
2779 DIFFERENT_VALID_SECURITY_CONTEXT.into(),
2780 XattrOp::Set,
2781 )
2782 .expect("set_xattr(security.selinux) failed");
2783
2784 assert!(selinux_hooks::get_cached_sid(node).is_some());
2785
2786 let second_sid = selinux_hooks::get_cached_sid(node).unwrap();
2787
2788 assert_ne!(first_sid, second_sid);
2789 },
2790 )
2791 .await;
2792 }
2793
2794 #[fuchsia::test]
2795 async fn fs_node_getsecurity_returns_cached_context() {
2796 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2797 |locked, current_task, security_server| {
2798 let node = &testing::create_test_file(locked, current_task).entry.node;
2799
2800 const TEST_VALUE: &str = "Something Random";
2802 node.ops()
2803 .set_xattr(
2804 locked.cast_locked::<FileOpsCore>(),
2805 node,
2806 current_task,
2807 XATTR_NAME_SELINUX.to_bytes().into(),
2808 TEST_VALUE.into(),
2809 XattrOp::Set,
2810 )
2811 .expect("set_xattr(security.selinux) failed");
2812
2813 let sid = security_server
2815 .security_context_to_sid(VALID_SECURITY_CONTEXT.into())
2816 .expect("security context to SID");
2817 selinux_hooks::set_cached_sid(&node, sid);
2818
2819 let result = fs_node_getsecurity(
2821 locked,
2822 current_task,
2823 node,
2824 XATTR_NAME_SELINUX.to_bytes().into(),
2825 4096,
2826 );
2827 assert_eq!(
2828 result,
2829 Ok(ValueOrSize::Value(FsString::new(VALID_SECURITY_CONTEXT_WITH_NUL.into())))
2830 );
2831 },
2832 )
2833 .await;
2834 }
2835
2836 #[fuchsia::test]
2837 async fn fs_node_getsecurity_delegates_to_get_xattr() {
2838 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2839 |locked, current_task, security_server| {
2840 let node = &testing::create_test_file(locked, current_task).entry.node;
2841
2842 security_server.set_enforcing(false);
2845 const TEST_VALUE: &str = "Something Random";
2846 fs_node_setsecurity(
2847 locked,
2848 current_task,
2849 node,
2850 XATTR_NAME_SELINUX.to_bytes().into(),
2851 TEST_VALUE.into(),
2852 XattrOp::Set,
2853 )
2854 .expect("set_xattr(security.selinux) failed");
2855 security_server.set_enforcing(true);
2856
2857 let result = fs_node_getsecurity(
2859 locked,
2860 current_task,
2861 node,
2862 XATTR_NAME_SELINUX.to_bytes().into(),
2863 4096,
2864 );
2865 assert_eq!(result, Ok(ValueOrSize::Value(FsString::new(TEST_VALUE.into()))));
2866 },
2867 )
2868 .await;
2869 }
2870
2871 #[fuchsia::test]
2872 async fn set_get_procattr() {
2873 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2874 |_locked, current_task, _security_server| {
2875 assert_eq!(
2876 get_procattr(current_task, current_task, ProcAttr::Exec),
2877 Ok(Vec::new())
2878 );
2879
2880 assert_eq!(
2881 set_procattr(current_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
2883 Ok(())
2884 );
2885
2886 assert_eq!(
2887 set_procattr(
2889 current_task,
2890 ProcAttr::SockCreate,
2891 DIFFERENT_VALID_SECURITY_CONTEXT.into()
2892 ),
2893 error!(EACCES)
2894 );
2895
2896 assert_eq!(
2897 set_procattr(
2899 current_task,
2900 ProcAttr::Previous,
2901 DIFFERENT_VALID_SECURITY_CONTEXT.into()
2902 ),
2903 error!(EINVAL)
2904 );
2905
2906 assert_eq!(
2907 set_procattr(current_task, ProcAttr::Exec, INVALID_SECURITY_CONTEXT.into()),
2909 error!(EINVAL)
2910 );
2911
2912 assert_eq!(
2913 get_procattr(current_task, current_task, ProcAttr::Exec),
2914 Ok(VALID_SECURITY_CONTEXT_WITH_NUL.into())
2915 );
2916
2917 assert!(get_procattr(current_task, current_task, ProcAttr::Current).is_ok());
2918 },
2919 )
2920 .await;
2921 }
2922
2923 #[fuchsia::test]
2924 async fn set_get_procattr_with_nulls() {
2925 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2926 |_locked, current_task, _security_server| {
2927 assert_eq!(
2928 get_procattr(current_task, current_task, ProcAttr::Exec),
2929 Ok(Vec::new())
2930 );
2931
2932 assert_eq!(
2933 set_procattr(
2935 current_task,
2936 ProcAttr::Exec,
2937 VALID_SECURITY_CONTEXT_WITH_NUL.into()
2938 ),
2939 Ok(())
2940 );
2941
2942 assert_eq!(
2943 set_procattr(
2945 current_task,
2946 ProcAttr::FsCreate,
2947 INVALID_SECURITY_CONTEXT_INTERNAL_NUL.into()
2948 ),
2949 error!(EINVAL)
2950 );
2951
2952 assert_eq!(
2953 get_procattr(current_task, current_task, ProcAttr::Exec),
2954 Ok(VALID_SECURITY_CONTEXT_WITH_NUL.into())
2955 );
2956
2957 assert_eq!(
2958 get_procattr(current_task, current_task, ProcAttr::FsCreate),
2959 Ok(Vec::new())
2960 );
2961 },
2962 )
2963 .await;
2964 }
2965
2966 #[fuchsia::test]
2967 async fn set_get_procattr_clear_context() {
2968 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2969 |_locked, current_task, _security_server| {
2970 assert_eq!(
2972 set_procattr(current_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
2973 Ok(())
2974 );
2975 assert_eq!(
2976 set_procattr(
2977 current_task,
2978 ProcAttr::FsCreate,
2979 DIFFERENT_VALID_SECURITY_CONTEXT.into()
2980 ),
2981 Ok(())
2982 );
2983
2984 assert_eq!(set_procattr(current_task, ProcAttr::Exec, b"\0"), Ok(()));
2986 assert_eq!(current_task.current_creds().security_state.exec_sid, None);
2987
2988 assert_eq!(set_procattr(current_task, ProcAttr::FsCreate, b"\x0a"), Ok(()));
2990 assert_eq!(current_task.current_creds().security_state.fscreate_sid, None);
2991 },
2992 )
2993 .await;
2994 }
2995
2996 #[fuchsia::test]
2997 async fn set_get_procattr_setcurrent() {
2998 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2999 |_locked, current_task, _security_server| {
3000 let initial_previous =
3002 get_procattr(current_task, current_task, ProcAttr::Previous).unwrap();
3003
3004 assert_eq!(
3005 set_procattr(current_task, ProcAttr::Current, VALID_SECURITY_CONTEXT.into()),
3007 Ok(())
3008 );
3009
3010 assert_eq!(
3011 get_procattr(current_task, current_task, ProcAttr::Current),
3013 Ok(VALID_SECURITY_CONTEXT_WITH_NUL.into())
3014 );
3015
3016 assert_eq!(
3017 get_procattr(current_task, current_task, ProcAttr::Previous),
3019 Ok(initial_previous.clone())
3020 );
3021
3022 assert_eq!(
3023 set_procattr(
3025 current_task,
3026 ProcAttr::Current,
3027 DIFFERENT_VALID_SECURITY_CONTEXT.into()
3028 ),
3029 Ok(())
3030 );
3031
3032 assert_eq!(
3033 get_procattr(current_task, current_task, ProcAttr::Current),
3035 Ok(DIFFERENT_VALID_SECURITY_CONTEXT_WITH_NUL.into())
3036 );
3037
3038 assert_eq!(
3039 get_procattr(current_task, current_task, ProcAttr::Previous),
3041 Ok(initial_previous.clone())
3042 );
3043 },
3044 )
3045 .await;
3046 }
3047
3048 #[fuchsia::test]
3049 async fn set_get_procattr_selinux_permissive() {
3050 spawn_kernel_with_selinux_hooks_test_policy_and_run(
3051 |_locked, current_task, security_server| {
3052 security_server.set_enforcing(false);
3053 assert_eq!(
3054 get_procattr(current_task, ¤t_task.task, ProcAttr::Exec),
3055 Ok(Vec::new())
3056 );
3057
3058 assert_eq!(
3059 set_procattr(current_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
3061 Ok(())
3062 );
3063
3064 assert_eq!(
3065 set_procattr(
3068 current_task,
3069 ProcAttr::FsCreate,
3070 DIFFERENT_VALID_SECURITY_CONTEXT.into()
3071 ),
3072 Ok(())
3073 );
3074
3075 assert_eq!(
3076 set_procattr(current_task, ProcAttr::Exec, INVALID_SECURITY_CONTEXT.into()),
3078 error!(EINVAL)
3079 );
3080
3081 assert_eq!(
3082 get_procattr(current_task, ¤t_task.task, ProcAttr::Exec),
3083 Ok(VALID_SECURITY_CONTEXT_WITH_NUL.into())
3084 );
3085
3086 assert!(get_procattr(current_task, ¤t_task.task, ProcAttr::Current).is_ok());
3087 },
3088 )
3089 .await;
3090 }
3091
3092 #[fuchsia::test]
3093 async fn set_get_procattr_selinux_disabled() {
3094 spawn_kernel_and_run(async |_, current_task| {
3095 assert_eq!(
3096 set_procattr(¤t_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
3097 error!(EINVAL)
3098 );
3099
3100 assert_eq!(
3101 set_procattr(¤t_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
3103 error!(EINVAL)
3104 );
3105
3106 assert_eq!(
3107 set_procattr(¤t_task, ProcAttr::FsCreate, VALID_SECURITY_CONTEXT.into()),
3109 error!(EINVAL)
3110 );
3111
3112 assert_eq!(
3113 set_procattr(¤t_task, ProcAttr::Exec, INVALID_SECURITY_CONTEXT.into()),
3115 error!(EINVAL)
3116 );
3117
3118 assert_eq!(
3119 get_procattr(¤t_task, ¤t_task.task, ProcAttr::Current),
3120 error!(EINVAL)
3121 );
3122 })
3123 .await;
3124 }
3125
3126 #[fuchsia::test]
3127 async fn create_file_with_fscreate_sid() {
3128 spawn_kernel_with_selinux_hooks_test_policy_and_run(
3129 |locked, current_task, security_server| {
3130 let sid =
3131 security_server.security_context_to_sid(VALID_SECURITY_CONTEXT.into()).unwrap();
3132 let source_node = &testing::create_test_file(locked, current_task).entry.node;
3133
3134 fs_node_setsecurity(
3135 locked,
3136 current_task,
3137 &source_node,
3138 XATTR_NAME_SELINUX.to_bytes().into(),
3139 VALID_SECURITY_CONTEXT.into(),
3140 XattrOp::Set,
3141 )
3142 .expect("set_xattr(security.selinux) failed");
3143
3144 let mut creds = Credentials::clone(¤t_task.current_creds());
3145 security::fs_node_copy_up(current_task, source_node, &source_node.fs(), &mut creds);
3146 let dir_entry = current_task
3147 .override_creds(creds.into(), || {
3148 current_task
3149 .fs()
3150 .root()
3151 .create_node(
3152 locked,
3153 ¤t_task,
3154 "test_file2".into(),
3155 FileMode::IFREG,
3156 DeviceId::NONE,
3157 )
3158 .unwrap()
3159 })
3160 .entry;
3161
3162 assert_eq!(get_cached_sid(&dir_entry.node), Some(sid));
3163 },
3164 )
3165 .await;
3166 }
3167}