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}
74
75impl PermissionFlags {
76 pub fn as_access(&self) -> Access {
77 let mut access = Access::empty();
78 if self.contains(PermissionFlags::READ) {
79 access |= Access::READ;
80 }
81 if self.contains(PermissionFlags::WRITE) {
82 access |= Access::WRITE;
85 }
86 if self.contains(PermissionFlags::EXEC) {
87 access |= Access::EXEC;
88 }
89 access
90 }
91}
92
93impl From<Access> for PermissionFlags {
94 fn from(access: Access) -> Self {
95 let mut permissions = PermissionFlags::empty();
97 if access.contains(Access::READ) {
98 permissions |= PermissionFlags::READ;
99 }
100 if access.contains(Access::WRITE) {
101 permissions |= PermissionFlags::WRITE;
102 }
103 if access.contains(Access::EXEC) {
104 permissions |= PermissionFlags::EXEC;
105 }
106 permissions
107 }
108}
109
110impl From<ProtectionFlags> for PermissionFlags {
111 fn from(protection_flags: ProtectionFlags) -> Self {
112 let mut flags = PermissionFlags::empty();
113 if protection_flags.contains(ProtectionFlags::READ) {
114 flags |= PermissionFlags::READ;
115 }
116 if protection_flags.contains(ProtectionFlags::WRITE) {
117 flags |= PermissionFlags::WRITE;
118 }
119 if protection_flags.contains(ProtectionFlags::EXEC) {
120 flags |= PermissionFlags::EXEC;
121 }
122 flags
123 }
124}
125
126impl From<OpenFlags> for PermissionFlags {
127 fn from(flags: OpenFlags) -> Self {
128 let mut permissions = PermissionFlags::empty();
129 if flags.can_read() {
130 permissions |= PermissionFlags::READ;
131 }
132 if flags.can_write() {
133 permissions |= PermissionFlags::WRITE;
134 if flags.contains(OpenFlags::APPEND) {
135 permissions |= PermissionFlags::APPEND;
136 }
137 }
138 permissions
139 }
140}
141
142impl From<MapFlags> for PermissionFlags {
143 fn from(bpf_flags: MapFlags) -> Self {
144 if bpf_flags.contains(MapFlags::SyscallReadOnly) {
145 PermissionFlags::READ
146 } else if bpf_flags.contains(MapFlags::SyscallWriteOnly) {
147 PermissionFlags::WRITE
148 } else {
149 PermissionFlags::READ | PermissionFlags::WRITE
150 }
151 }
152}
153
154#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
156pub enum PerfEventType {
157 Hardware,
158 Software,
159 Tracepoint,
160 Raw,
161 HwCache,
162 Breakpoint,
163}
164
165#[allow(non_upper_case_globals)]
167impl TryFrom<perf_type_id> for PerfEventType {
168 type Error = Errno;
169
170 fn try_from(type_id: perf_type_id) -> Result<Self, Errno> {
171 match type_id {
172 perf_type_id_PERF_TYPE_HARDWARE => Ok(Self::Hardware),
173 perf_type_id_PERF_TYPE_SOFTWARE => Ok(Self::Software),
174 perf_type_id_PERF_TYPE_TRACEPOINT => Ok(Self::Tracepoint),
175 perf_type_id_PERF_TYPE_RAW => Ok(Self::Raw),
176 perf_type_id_PERF_TYPE_HW_CACHE => Ok(Self::HwCache),
177 perf_type_id_PERF_TYPE_BREAKPOINT => Ok(Self::Breakpoint),
178 _ => {
179 return error!(ENOTSUP);
180 }
181 }
182 }
183}
184
185#[derive(PartialEq, Eq)]
187pub enum TargetTaskType<'a> {
188 AllTasks,
190 CurrentTask,
192 Task(&'a Task),
194}
195
196fn if_selinux_else_with_context<F, R, D, C>(context: C, task: &Task, hook: F, default: D) -> R
200where
201 F: FnOnce(C, &Arc<SecurityServer>) -> R,
202 D: Fn(C) -> R,
203{
204 if let Some(state) = task.kernel().security_state.state.as_ref() {
205 if state.has_policy() { hook(context, &state.server) } else { default(context) }
206 } else {
207 default(context)
208 }
209}
210
211fn if_selinux_else<F, R, D>(task: &Task, hook: F, default: D) -> R
215where
216 F: FnOnce(&Arc<SecurityServer>) -> R,
217 D: Fn() -> R,
218{
219 if_selinux_else_with_context(
220 (),
221 task,
222 |_, security_server| hook(security_server),
223 |_| default(),
224 )
225}
226
227fn if_selinux_else_default_ok_with_context<R, F, C>(
231 context: C,
232 task: &Task,
233 hook: F,
234) -> Result<R, Errno>
235where
236 F: FnOnce(C, &Arc<SecurityServer>) -> Result<R, Errno>,
237 R: Default,
238{
239 if_selinux_else_with_context(context, task, hook, |_| Ok(R::default()))
240}
241
242fn if_selinux_else_default_ok<R, F>(task: &Task, hook: F) -> Result<R, Errno>
246where
247 F: FnOnce(&Arc<SecurityServer>) -> Result<R, Errno>,
248 R: Default,
249{
250 if_selinux_else(task, hook, || Ok(R::default()))
251}
252
253pub fn kernel_init_security(
256 enabled: bool,
257 options: String,
258 exceptions: Vec<String>,
259 inspect_node: &fuchsia_inspect::Node,
260) -> KernelState {
261 track_hook_duration!("security.hooks.kernel_init_security");
262 KernelState {
263 state: enabled
264 .then(|| selinux_hooks::kernel_init_security(options, exceptions, inspect_node)),
265 }
266}
267
268pub fn binder_set_context_mgr(current_task: &CurrentTask) -> Result<(), Errno> {
271 track_hook_duration!("security.hooks.binder_set_context_mgr");
272 if_selinux_else_default_ok(current_task, |security_server| {
273 selinux_hooks::binder::binder_set_context_mgr(security_server, current_task)
274 })
275}
276
277pub fn binder_transaction(
280 current_task: &CurrentTask,
281 target_task: &Task,
282 connection_state: &BinderConnectionState,
283) -> Result<(), Errno> {
284 track_hook_duration!("security.hooks.binder_transaction");
285 if_selinux_else_default_ok(current_task, |security_server| {
286 selinux_hooks::binder::binder_transaction(
287 security_server,
288 &connection_state.state,
289 current_task,
290 target_task,
291 )
292 })
293}
294
295pub fn binder_transfer_binder(current_task: &CurrentTask, target_task: &Task) -> Result<(), Errno> {
298 track_hook_duration!("security.hooks.binder_transfer_binder");
299 if_selinux_else_default_ok(current_task, |security_server| {
300 selinux_hooks::binder::binder_transfer_binder(security_server, current_task, target_task)
301 })
302}
303
304pub fn binder_transfer_file(
307 current_task: &CurrentTask,
308 receiving_task: &Task,
309 file: &FileObject,
310) -> Result<(), Errno> {
311 track_hook_duration!("security.hooks.binder_transfer_file");
312 if_selinux_else_default_ok(current_task, |security_server| {
313 selinux_hooks::binder::binder_transfer_file(
314 security_server,
315 current_task,
316 receiving_task,
317 file,
318 )
319 })
320}
321
322pub fn binder_get_context(
325 current_task: &CurrentTask,
326 connection_state: &BinderConnectionState,
327) -> Option<Vec<u8>> {
328 track_hook_duration!("security.hooks.binder_get_context");
329 if_selinux_else(
330 current_task,
331 |security_server| {
332 selinux_hooks::binder::binder_get_context(&security_server, &connection_state.state)
333 },
334 || None,
335 )
336}
337
338pub fn sb_eat_lsm_opts(
342 kernel: &Kernel,
343 mount_params: &mut MountParams,
344) -> Result<FileSystemMountOptions, Errno> {
345 track_hook_duration!("security.hooks.sb_eat_lsm_opts");
346 if kernel.security_state.state.is_some() {
347 return selinux_hooks::superblock::sb_eat_lsm_opts(mount_params);
348 }
349 Ok(FileSystemMountOptions::default())
350}
351
352pub fn file_system_init_security(
355 mount_options: &FileSystemMountOptions,
356 ops: &dyn FileSystemOps,
357) -> Result<FileSystemState, Errno> {
358 track_hook_duration!("security.hooks.file_system_init_security");
359 Ok(FileSystemState {
360 state: selinux_hooks::superblock::file_system_init_security(mount_options, ops)?,
361 })
362}
363
364pub fn file_system_post_init_security(kernel: &Kernel, file_system: &FileSystemHandle) {
369 track_hook_duration!("security.hooks.file_system_post_init_security");
370 if let Some(state) = &kernel.security_state.state {
371 if !state.has_policy() {
372 log_debug!("Queuing {} FileSystem for labeling", file_system.name());
375 state.pending_file_systems.lock().insert(WeakKey::from(&file_system));
376 }
377 }
378}
379
380pub fn file_system_resolve_security<L>(
385 locked: &mut Locked<L>,
386 current_task: &CurrentTask,
387 file_system: &FileSystemHandle,
388) -> Result<(), Errno>
389where
390 L: LockEqualOrBefore<FileOpsCore>,
391{
392 track_hook_duration!("security.hooks.file_system_resolve_security");
393 if_selinux_else_default_ok_with_context(locked, current_task, |locked, security_server| {
394 selinux_hooks::superblock::file_system_resolve_security(
395 locked,
396 security_server,
397 current_task,
398 file_system,
399 )
400 })
401}
402
403pub struct FsNodeSecurityXattr {
405 pub name: &'static FsStr,
406 pub value: FsString,
407}
408
409pub fn mmap_file(
413 current_task: &CurrentTask,
414 file: Option<&FileHandle>,
415 protection_flags: ProtectionFlags,
416 options: MappingOptions,
417) -> Result<(), Errno> {
418 track_hook_duration!("security.hooks.mmap_file");
419 if_selinux_else_default_ok(current_task, |security_server| {
420 selinux_hooks::file::mmap_file(
421 security_server,
422 current_task,
423 file,
424 protection_flags,
425 options,
426 )
427 })
428}
429
430pub fn file_mprotect(
434 current_task: &CurrentTask,
435 range: &Range<UserAddress>,
436 mapping: &Mapping,
437 prot: ProtectionFlags,
438) -> Result<(), Errno> {
439 track_hook_duration!("security.hooks.file_mprotect");
440 if_selinux_else_default_ok(current_task, |security_server| {
441 selinux_hooks::file::file_mprotect(security_server, current_task, range, mapping, prot)
442 })
443}
444
445pub fn file_permission(
448 current_task: &CurrentTask,
449 file: &FileObject,
450 permission_flags: PermissionFlags,
451) -> Result<(), Errno> {
452 track_hook_duration!("security.hooks.file_permission");
453 if_selinux_else_default_ok(current_task, |security_server| {
454 selinux_hooks::file::file_permission(security_server, current_task, file, permission_flags)
455 })
456}
457
458pub fn file_open(current_task: &CurrentTask, file: &FileObject) -> Result<(), Errno> {
461 track_hook_duration!("security.hooks.file_open");
462 if_selinux_else_default_ok(current_task, |security_server| {
463 selinux_hooks::file::file_open(security_server, current_task, file)
464 })
465}
466
467pub fn fs_node_init_with_dentry<L>(
473 locked: &mut Locked<L>,
474 current_task: &CurrentTask,
475 dir_entry: &DirEntryHandle,
476) -> Result<(), Errno>
477where
478 L: LockEqualOrBefore<FileOpsCore>,
479{
480 track_hook_duration!("security.hooks.fs_node_init_with_dentry");
481 if let Some(state) = ¤t_task.kernel().security_state.state {
486 selinux_hooks::fs_node::fs_node_init_with_dentry(
487 Some(locked.cast_locked()),
488 &state.server,
489 current_task,
490 dir_entry,
491 )
492 } else {
493 Ok(())
494 }
495}
496
497pub fn fs_node_init_with_dentry_no_xattr(
498 current_task: &CurrentTask,
499 dir_entry: &DirEntryHandle,
500) -> Result<(), Errno> {
501 track_hook_duration!("security.hooks.fs_node_init_with_dentry_no_xattr");
502 if let Some(state) = ¤t_task.kernel().security_state.state {
507 if dir_entry.node.is_private() {
510 return selinux_hooks::fs_node::fs_node_init_anon(
511 &state.server,
512 current_task,
513 &dir_entry.node,
514 "",
515 );
516 }
517
518 selinux_hooks::fs_node::fs_node_init_with_dentry(
519 None,
520 &state.server,
521 current_task,
522 dir_entry,
523 )
524 } else {
525 Ok(())
526 }
527}
528
529pub fn fs_node_init_with_dentry_deferred(kernel: &Kernel, dir_entry: &DirEntryHandle) {
533 track_hook_duration!("security.hooks.fs_node_init_with_dentry_no_xattr");
534 if kernel.security_state.state.is_some() {
535 selinux_hooks::fs_node::fs_node_init_with_dentry_deferred(dir_entry);
536 }
537}
538
539pub fn fs_node_notify_security_context(
546 current_task: &CurrentTask,
547 fs_node: &FsNode,
548 context: &FsStr,
549) -> Result<(), Errno> {
550 track_hook_duration!("security.hooks.fs_node_notify_security_context");
551 if_selinux_else(
552 current_task,
553 |security_server| {
554 selinux_hooks::fs_node::fs_node_notify_security_context(
555 security_server,
556 fs_node,
557 context,
558 )
559 },
560 || error!(ENOTSUP),
561 )
562}
563
564pub fn fs_node_init_on_create(
576 current_task: &CurrentTask,
577 new_node: &FsNode,
578 parent: &FsNode,
579 name: &FsStr,
580) -> Result<Option<FsNodeSecurityXattr>, Errno> {
581 track_hook_duration!("security.hooks.fs_node_init_on_create");
582 if_selinux_else_default_ok(current_task, |security_server| {
583 selinux_hooks::fs_node::fs_node_init_on_create(
584 security_server,
585 current_task,
586 new_node,
587 Some(parent),
588 name,
589 )
590 })
591}
592
593pub fn dentry_create_files_as(
601 current_task: &CurrentTask,
602 parent: &FsNode,
603 new_node_mode: FileMode,
604 new_node_name: &FsStr,
605 new_creds: &mut Credentials,
606) -> Result<(), Errno> {
607 track_hook_duration!("security.hooks.dentry_create_files_as");
608 if_selinux_else_default_ok(current_task, |security_server| {
609 selinux_hooks::fs_node::dentry_create_files_as(
610 security_server,
611 current_task,
612 parent,
613 new_node_mode,
614 new_node_name,
615 new_creds,
616 )
617 })
618}
619
620pub fn fs_node_init_anon(
625 current_task: &CurrentTask,
626 new_node: &FsNode,
627 node_type: &str,
628) -> Result<(), Errno> {
629 track_hook_duration!("security.hooks.fs_node_init_anon");
630 if let Some(state) = current_task.kernel().security_state.state.as_ref() {
631 selinux_hooks::fs_node::fs_node_init_anon(&state.server, current_task, new_node, node_type)
632 } else {
633 Ok(())
634 }
635}
636
637pub fn check_fs_node_create_access(
641 current_task: &CurrentTask,
642 parent: &FsNode,
643 mode: FileMode,
644 name: &FsStr,
645) -> Result<(), Errno> {
646 track_hook_duration!("security.hooks.check_fs_node_create_access");
647 if_selinux_else_default_ok(current_task, |security_server| {
648 selinux_hooks::fs_node::check_fs_node_create_access(
649 security_server,
650 current_task,
651 parent,
652 mode,
653 name,
654 )
655 })
656}
657
658pub fn check_fs_node_symlink_access(
662 current_task: &CurrentTask,
663 parent: &FsNode,
664 name: &FsStr,
665 old_path: &FsStr,
666) -> Result<(), Errno> {
667 track_hook_duration!("security.hooks.check_fs_node_symlink_access");
668 if_selinux_else_default_ok(current_task, |security_server| {
669 selinux_hooks::fs_node::check_fs_node_symlink_access(
670 security_server,
671 current_task,
672 parent,
673 name,
674 old_path,
675 )
676 })
677}
678
679pub fn check_fs_node_mkdir_access(
683 current_task: &CurrentTask,
684 parent: &FsNode,
685 mode: FileMode,
686 name: &FsStr,
687) -> Result<(), Errno> {
688 track_hook_duration!("security.hooks.check_fs_node_mkdir_access");
689 if_selinux_else_default_ok(current_task, |security_server| {
690 selinux_hooks::fs_node::check_fs_node_mkdir_access(
691 security_server,
692 current_task,
693 parent,
694 mode,
695 name,
696 )
697 })
698}
699
700pub fn check_fs_node_mknod_access(
706 current_task: &CurrentTask,
707 parent: &FsNode,
708 mode: FileMode,
709 name: &FsStr,
710 device_id: DeviceId,
711) -> Result<(), Errno> {
712 track_hook_duration!("security.hooks.check_fs_node_mknod_access");
713 assert!(!mode.is_reg());
714
715 if_selinux_else_default_ok(current_task, |security_server| {
716 selinux_hooks::fs_node::check_fs_node_mknod_access(
717 security_server,
718 current_task,
719 parent,
720 mode,
721 name,
722 device_id,
723 )
724 })
725}
726
727pub fn check_fs_node_link_access(
730 current_task: &CurrentTask,
731 parent: &FsNode,
732 child: &FsNode,
733) -> Result<(), Errno> {
734 track_hook_duration!("security.hooks.check_fs_node_link_access");
735 if_selinux_else_default_ok(current_task, |security_server| {
736 selinux_hooks::fs_node::check_fs_node_link_access(
737 security_server,
738 current_task,
739 parent,
740 child,
741 )
742 })
743}
744
745pub fn check_fs_node_unlink_access(
748 current_task: &CurrentTask,
749 parent: &FsNode,
750 child: &FsNode,
751 name: &FsStr,
752) -> Result<(), Errno> {
753 track_hook_duration!("security.hooks.check_fs_node_unlink_access");
754 if_selinux_else_default_ok(current_task, |security_server| {
755 selinux_hooks::fs_node::check_fs_node_unlink_access(
756 security_server,
757 current_task,
758 parent,
759 child,
760 name,
761 )
762 })
763}
764
765pub fn check_fs_node_rmdir_access(
768 current_task: &CurrentTask,
769 parent: &FsNode,
770 child: &FsNode,
771 name: &FsStr,
772) -> Result<(), Errno> {
773 track_hook_duration!("security.hooks.check_fs_node_rmdir_access");
774 if_selinux_else_default_ok(current_task, |security_server| {
775 selinux_hooks::fs_node::check_fs_node_rmdir_access(
776 security_server,
777 current_task,
778 parent,
779 child,
780 name,
781 )
782 })
783}
784
785pub fn check_fs_node_rename_access(
790 current_task: &CurrentTask,
791 old_parent: &FsNode,
792 moving_node: &FsNode,
793 new_parent: &FsNode,
794 replaced_node: Option<&FsNode>,
795 old_basename: &FsStr,
796 new_basename: &FsStr,
797) -> Result<(), Errno> {
798 track_hook_duration!("security.hooks.check_fs_node_rename_access");
799 if_selinux_else_default_ok(current_task, |security_server| {
800 selinux_hooks::fs_node::check_fs_node_rename_access(
801 security_server,
802 current_task,
803 old_parent,
804 moving_node,
805 new_parent,
806 replaced_node,
807 old_basename,
808 new_basename,
809 )
810 })
811}
812
813pub fn check_fs_node_read_link_access(
816 current_task: &CurrentTask,
817 fs_node: &FsNode,
818) -> Result<(), Errno> {
819 track_hook_duration!("security.hooks.check_fs_node_read_link_access");
820 if_selinux_else_default_ok(current_task, |security_server| {
821 selinux_hooks::fs_node::check_fs_node_read_link_access(
822 security_server,
823 current_task,
824 fs_node,
825 )
826 })
827}
828
829pub fn fs_node_permission(
832 current_task: &CurrentTask,
833 fs_node: &FsNode,
834 permission_flags: PermissionFlags,
835 audit_context: Auditable<'_>,
836) -> Result<(), Errno> {
837 track_hook_duration!("security.hooks.fs_node_permission");
838 if_selinux_else_default_ok(current_task, |security_server| {
839 selinux_hooks::fs_node::fs_node_permission(
840 security_server,
841 current_task,
842 fs_node,
843 permission_flags,
844 audit_context,
845 )
846 })
847}
848
849pub fn file_receive(current_task: &CurrentTask, file: &FileObject) -> Result<(), Errno> {
852 track_hook_duration!("security.hooks.file_receive");
853 if_selinux_else_default_ok(current_task, |security_server| {
854 let receiving_sid = current_task_state(current_task).current_sid;
855 selinux_hooks::file::file_receive(security_server, current_task, receiving_sid, file)
856 })
857}
858
859pub fn file_alloc_security(current_task: &CurrentTask) -> FileObjectState {
862 track_hook_duration!("security.hooks.file_alloc_security");
863 FileObjectState { state: selinux_hooks::file::file_alloc_security(current_task) }
864}
865
866pub fn binder_connection_alloc(current_task: &CurrentTask) -> BinderConnectionState {
869 track_hook_duration!("security.hooks.binder_connection_alloc");
870 BinderConnectionState { state: selinux_hooks::binder::binder_connection_alloc(current_task) }
871}
872
873pub fn bpf_map_alloc(current_task: &CurrentTask) -> BpfMapState {
877 track_hook_duration!("security.hooks.bpf_map_alloc");
878 BpfMapState { state: selinux_hooks::bpf::bpf_map_alloc(current_task) }
879}
880
881pub fn bpf_prog_alloc(current_task: &CurrentTask) -> BpfProgState {
885 track_hook_duration!("security.hooks.bpf_prog_alloc");
886 BpfProgState { state: selinux_hooks::bpf::bpf_prog_alloc(current_task) }
887}
888
889pub fn check_file_ioctl_access(
892 current_task: &CurrentTask,
893 file: &FileObject,
894 request: u32,
895) -> Result<(), Errno> {
896 track_hook_duration!("security.hooks.check_file_ioctl_access");
897 if_selinux_else_default_ok(current_task, |security_server| {
898 selinux_hooks::file::check_file_ioctl_access(security_server, current_task, file, request)
899 })
900}
901
902pub fn fs_node_copy_up(
912 current_task: &CurrentTask,
913 fs_node: &FsNode,
914 fs: &FileSystem,
915 new_creds: &mut Credentials,
916) {
917 if_selinux_else(
918 current_task,
919 |_security_server| {
920 selinux_hooks::fs_node::fs_node_copy_up(current_task, fs_node, fs, new_creds)
921 },
922 || {},
923 )
924}
925
926pub fn check_file_lock_access(current_task: &CurrentTask, file: &FileObject) -> Result<(), Errno> {
934 track_hook_duration!("security.hooks.check_file_lock_access");
935 if_selinux_else_default_ok(current_task, |security_server| {
936 selinux_hooks::file::check_file_lock_access(security_server, current_task, file)
937 })
938}
939
940pub fn check_file_fcntl_access(
943 current_task: &CurrentTask,
944 file: &FileObject,
945 fcntl_cmd: u32,
946 fcntl_arg: u64,
947) -> Result<(), Errno> {
948 track_hook_duration!("security.hooks.check_file_fcntl_access");
949 if_selinux_else_default_ok(current_task, |security_server| {
950 selinux_hooks::file::check_file_fcntl_access(
951 security_server,
952 current_task,
953 file,
954 fcntl_cmd,
955 fcntl_arg,
956 )
957 })
958}
959
960pub fn check_fs_node_setattr_access(
963 current_task: &CurrentTask,
964 node: &FsNode,
965 attributes: &zxio_node_attr_has_t,
966) -> Result<(), Errno> {
967 track_hook_duration!("security.hooks.check_fs_node_setattr_access");
968 if_selinux_else_default_ok(current_task, |security_server| {
969 selinux_hooks::fs_node::check_fs_node_setattr_access(
970 security_server,
971 current_task,
972 node,
973 attributes,
974 )
975 })
976}
977
978pub fn task_alloc_for_kernel() -> TaskAttrs {
981 track_hook_duration!("security.hooks.task_alloc_for_kernel");
982 TaskAttrs::for_kernel()
983}
984
985pub fn task_to_fs_node(current_task: &CurrentTask, task: &Task, fs_node: &FsNode) {
991 track_hook_duration!("security.hooks.task_to_fs_node");
992 if current_task.kernel().security_state.state.is_some() {
995 selinux_hooks::task::fs_node_init_with_task(task, &fs_node);
996 }
997}
998
999pub fn task_for_context(task: &Task, context: &FsStr) -> Result<TaskAttrs, Errno> {
1005 track_hook_duration!("security.hooks.task_for_context");
1006 Ok(if let Some(kernel_state) = task.kernel().security_state.state.as_ref() {
1007 selinux_hooks::task::task_alloc_from_context(&kernel_state.server, context)
1008 } else {
1009 Ok(TaskAttrs::for_selinux_disabled())
1010 }?)
1011}
1012
1013pub fn has_dontaudit_access(current_task: &CurrentTask, fs_node: &FsNode) -> bool {
1017 track_hook_duration!("security.hooks.has_dontaudit_access");
1018 if_selinux_else(
1019 current_task,
1020 |security_server| {
1021 selinux_hooks::fs_node::has_dontaudit_access(security_server, current_task, fs_node)
1022 },
1023 || false,
1024 )
1025}
1026
1027pub fn is_task_capable_noaudit(
1030 current_task: &CurrentTask,
1031 capability: starnix_uapi::auth::Capabilities,
1032) -> bool {
1033 track_hook_duration!("security.hooks.is_task_capable_noaudit");
1034 return common_cap::capable(current_task, capability).is_ok()
1035 && if_selinux_else(
1036 current_task,
1037 |security_server| {
1038 selinux_hooks::task::is_task_capable_noaudit(
1039 &selinux_hooks::build_permission_check(current_task, security_server),
1040 ¤t_task,
1041 capability,
1042 )
1043 },
1044 || true,
1045 );
1046}
1047
1048pub fn check_creds_capable(
1051 current_task: &CurrentTask,
1052 creds: &Credentials,
1053 capability: starnix_uapi::auth::Capabilities,
1054) -> Result<(), Errno> {
1055 track_hook_duration!("security.hooks.check_creds_capable");
1056 common_cap::creds_capable(creds, capability)?;
1057 if_selinux_else_default_ok(current_task, |security_server| {
1058 selinux_hooks::task::check_creds_capable(
1059 &selinux_hooks::build_permission_check(current_task, security_server),
1060 ¤t_task,
1061 creds,
1062 capability,
1063 )
1064 })
1065}
1066
1067pub fn check_task_capable(
1070 current_task: &CurrentTask,
1071 capability: starnix_uapi::auth::Capabilities,
1072) -> Result<(), Errno> {
1073 check_creds_capable(current_task, &**current_task.current_creds(), capability)
1074}
1075
1076pub fn check_task_create_access(current_task: &CurrentTask) -> Result<(), Errno> {
1079 track_hook_duration!("security.hooks.check_task_create_access");
1080 if_selinux_else_default_ok(current_task, |security_server| {
1081 selinux_hooks::task::check_task_create_access(
1082 &selinux_hooks::build_permission_check(current_task, security_server),
1083 current_task,
1084 )
1085 })
1086}
1087
1088pub fn check_socket_create_access<L>(
1091 locked: &mut Locked<L>,
1092 current_task: &CurrentTask,
1093 domain: SocketDomain,
1094 socket_type: SocketType,
1095 protocol: SocketProtocol,
1096 kernel_private: bool,
1097) -> Result<(), Errno>
1098where
1099 L: LockEqualOrBefore<FileOpsCore>,
1100{
1101 track_hook_duration!("security.hooks.socket_create");
1102 if_selinux_else_default_ok(current_task, |security_server| {
1103 selinux_hooks::socket::check_socket_create_access(
1104 locked,
1105 &security_server,
1106 current_task,
1107 domain,
1108 socket_type,
1109 protocol,
1110 kernel_private,
1111 )
1112 })
1113}
1114
1115pub fn socket_socketpair(
1118 current_task: &CurrentTask,
1119 left: DowncastedFile<'_, SocketFile>,
1120 right: DowncastedFile<'_, SocketFile>,
1121) -> Result<(), Errno> {
1122 track_hook_duration!("security.hooks.socket_socketpair");
1123 if_selinux_else_default_ok(current_task, |_| {
1124 selinux_hooks::socket::socket_socketpair(left, right)
1125 })
1126}
1127
1128pub fn socket_post_create(current_task: &CurrentTask, socket: &Socket) {
1131 track_hook_duration!("security.hooks.socket_post_create");
1132 if let Some(state) = ¤t_task.kernel().security_state.state {
1133 selinux_hooks::socket::socket_post_create(&state.server, socket);
1134 }
1135}
1136
1137pub fn check_socket_bind_access(
1140 current_task: &CurrentTask,
1141 socket: &Socket,
1142 socket_address: &SocketAddress,
1143) -> Result<(), Errno> {
1144 track_hook_duration!("security.hooks.check_socket_bind_access");
1145 if_selinux_else_default_ok(current_task, |security_server| {
1146 selinux_hooks::socket::check_socket_bind_access(
1147 &security_server,
1148 current_task,
1149 socket,
1150 socket_address,
1151 )
1152 })
1153}
1154
1155pub fn check_socket_connect_access(
1158 current_task: &CurrentTask,
1159 socket: DowncastedFile<'_, SocketFile>,
1160 socket_peer: &SocketPeer,
1161) -> Result<(), Errno> {
1162 track_hook_duration!("security.hooks.check_socket_connect_access");
1163 if_selinux_else_default_ok(current_task, |security_server| {
1164 selinux_hooks::socket::check_socket_connect_access(
1165 &security_server,
1166 current_task,
1167 socket,
1168 socket_peer,
1169 )
1170 })
1171}
1172
1173pub fn check_socket_listen_access(
1176 current_task: &CurrentTask,
1177 socket: &Socket,
1178 backlog: i32,
1179) -> Result<(), Errno> {
1180 track_hook_duration!("security.hooks.check_socket_listen_access");
1181 if_selinux_else_default_ok(current_task, |security_server| {
1182 selinux_hooks::socket::check_socket_listen_access(
1183 &security_server,
1184 current_task,
1185 socket,
1186 backlog,
1187 )
1188 })
1189}
1190
1191pub fn socket_accept(
1195 current_task: &CurrentTask,
1196 listening_socket: DowncastedFile<'_, SocketFile>,
1197 accepted_socket: DowncastedFile<'_, SocketFile>,
1198) -> Result<(), Errno> {
1199 track_hook_duration!("security.hooks.check_socket_getname_access");
1200 if_selinux_else_default_ok(current_task, |security_server| {
1201 selinux_hooks::socket::socket_accept(
1202 &security_server,
1203 current_task,
1204 listening_socket,
1205 accepted_socket,
1206 )
1207 })
1208}
1209
1210pub fn check_socket_getsockopt_access(
1213 current_task: &CurrentTask,
1214 socket: &Socket,
1215 level: u32,
1216 optname: u32,
1217) -> Result<(), Errno> {
1218 track_hook_duration!("security.hooks.check_socket_getsockopt_access");
1219 if_selinux_else_default_ok(current_task, |security_server| {
1220 selinux_hooks::socket::check_socket_getsockopt_access(
1221 &security_server,
1222 current_task,
1223 socket,
1224 level,
1225 optname,
1226 )
1227 })
1228}
1229
1230pub fn check_socket_setsockopt_access(
1233 current_task: &CurrentTask,
1234 socket: &Socket,
1235 level: u32,
1236 optname: u32,
1237) -> Result<(), Errno> {
1238 track_hook_duration!("security.hooks.check_socket_setsockopt_access");
1239 if_selinux_else_default_ok(current_task, |security_server| {
1240 selinux_hooks::socket::check_socket_setsockopt_access(
1241 &security_server,
1242 current_task,
1243 socket,
1244 level,
1245 optname,
1246 )
1247 })
1248}
1249
1250pub fn check_socket_sendmsg_access(
1253 current_task: &CurrentTask,
1254 socket: &Socket,
1255) -> Result<(), Errno> {
1256 track_hook_duration!("security.hooks.check_socket_sendmsg_access");
1257 if_selinux_else_default_ok(current_task, |security_server| {
1258 selinux_hooks::socket::check_socket_sendmsg_access(&security_server, current_task, socket)
1259 })
1260}
1261
1262pub fn check_socket_recvmsg_access(
1265 current_task: &CurrentTask,
1266 socket: &Socket,
1267) -> Result<(), Errno> {
1268 track_hook_duration!("security.hooks.check_socket_recvmsg_access");
1269 if_selinux_else_default_ok(current_task, |security_server| {
1270 selinux_hooks::socket::check_socket_recvmsg_access(&security_server, current_task, socket)
1271 })
1272}
1273
1274pub fn check_socket_getsockname_access(
1277 current_task: &CurrentTask,
1278 socket: &Socket,
1279) -> Result<(), Errno> {
1280 track_hook_duration!("security.hooks.check_socket_getname_access");
1281 if_selinux_else_default_ok(current_task, |security_server| {
1282 selinux_hooks::socket::check_socket_getname_access(&security_server, current_task, socket)
1283 })
1284}
1285
1286pub fn check_socket_getpeername_access(
1289 current_task: &CurrentTask,
1290 socket: &Socket,
1291) -> Result<(), Errno> {
1292 track_hook_duration!("security.hooks.check_socket_getname_access");
1293 if_selinux_else_default_ok(current_task, |security_server| {
1294 selinux_hooks::socket::check_socket_getname_access(&security_server, current_task, socket)
1295 })
1296}
1297
1298pub fn check_socket_shutdown_access(
1301 current_task: &CurrentTask,
1302 socket: &Socket,
1303 how: SocketShutdownFlags,
1304) -> Result<(), Errno> {
1305 track_hook_duration!("security.hooks.check_socket_shutdown_access");
1306 if_selinux_else_default_ok(current_task, |security_server| {
1307 selinux_hooks::socket::check_socket_shutdown_access(
1308 &security_server,
1309 current_task,
1310 socket,
1311 how,
1312 )
1313 })
1314}
1315
1316pub fn socket_getpeersec_stream(
1319 current_task: &CurrentTask,
1320 socket: &Socket,
1321) -> Result<Vec<u8>, Errno> {
1322 track_hook_duration!("security.hooks.socket_getpeersec_stream");
1323 if_selinux_else_default_ok(current_task, |security_server| {
1324 selinux_hooks::socket::socket_getpeersec_stream(&security_server, current_task, socket)
1325 })
1326}
1327
1328pub fn socket_getpeersec_dgram(current_task: &CurrentTask, socket: &Socket) -> Vec<u8> {
1332 track_hook_duration!("security.hooks.socket_getpeersec_dgram");
1333 if_selinux_else(
1334 current_task,
1335 |security_server| {
1336 selinux_hooks::socket::socket_getpeersec_dgram(&security_server, current_task, socket)
1337 },
1338 Vec::default,
1339 )
1340}
1341
1342pub fn unix_may_send(
1346 current_task: &CurrentTask,
1347 sending_socket: &Socket,
1348 receiving_socket: &Socket,
1349) -> Result<(), Errno> {
1350 track_hook_duration!("security.hooks.unix_may_send");
1351 if_selinux_else_default_ok(current_task, |security_server| {
1352 selinux_hooks::socket::unix_may_send(
1353 &security_server,
1354 current_task,
1355 sending_socket,
1356 receiving_socket,
1357 )
1358 })
1359}
1360
1361pub fn unix_stream_connect(
1365 current_task: &CurrentTask,
1366 client_socket: &Socket,
1367 listening_socket: &Socket,
1368 server_socket: &Socket,
1369) -> Result<(), Errno> {
1370 track_hook_duration!("security.hooks.unix_stream_connect");
1371 if_selinux_else_default_ok(current_task, |security_server| {
1372 selinux_hooks::socket::unix_stream_connect(
1373 &security_server,
1374 current_task,
1375 client_socket,
1376 listening_socket,
1377 server_socket,
1378 )
1379 })
1380}
1381
1382pub fn check_netlink_send_access(
1386 current_task: &CurrentTask,
1387 socket: &Socket,
1388 message_type: u16,
1389) -> Result<(), Errno> {
1390 track_hook_duration!("security.hooks.check_netlink_send_access");
1391 if_selinux_else_default_ok(current_task, |security_server| {
1392 selinux_hooks::netlink_socket::check_netlink_send_access(
1393 &security_server,
1394 current_task,
1395 socket,
1396 message_type,
1397 )
1398 })
1399}
1400
1401pub fn check_tun_dev_create_access(current_task: &CurrentTask) -> Result<(), Errno> {
1404 track_hook_duration!("security.hooks.check_tun_dev_create_access");
1405 if_selinux_else_default_ok(current_task, |security_server| {
1406 selinux_hooks::socket::check_tun_dev_create_access(&security_server, current_task)
1407 })
1408}
1409
1410pub fn bprm_creds_from_file(
1414 current_task: &CurrentTask,
1415 elf_state: &mut ResolvedElf,
1416) -> Result<(), Errno> {
1417 track_hook_duration!("security.hooks.bprm_creds_from_file");
1418
1419 let (no_new_privs, is_ptraced) = {
1420 let state = current_task.read();
1421 (state.no_new_privs(), state.is_ptraced())
1422 };
1423
1424 let enable_suid = current_task.kernel().features.enable_suid && !no_new_privs && !is_ptraced;
1425 if enable_suid {
1426 elf_state.file.name.apply_suid_and_sgid(&mut elf_state.creds);
1427 }
1428
1429 elf_state.creds.fsuid = elf_state.creds.euid;
1431 elf_state.creds.fsgid = elf_state.creds.egid;
1432
1433 elf_state.creds.saved_uid = elf_state.creds.euid;
1439 elf_state.creds.saved_gid = elf_state.creds.egid;
1440
1441 let prev = current_task.current_creds();
1442 let file_is_privileged = elf_state.creds.euid != prev.euid || elf_state.creds.egid != prev.egid;
1443 let is_secure_exec = file_is_privileged
1444 || elf_state.creds.uid != elf_state.creds.euid
1445 || elf_state.creds.gid != elf_state.creds.egid;
1446
1447 elf_state.secure_exec |= is_secure_exec;
1448
1449 common_cap::bprm_creds_from_file(current_task, elf_state)?;
1450
1451 Ok(())
1452}
1453
1454pub fn bprm_creds_for_exec(
1460 current_task: &CurrentTask,
1461 executable: &NamespaceNode,
1462 elf_state: &mut ResolvedElf,
1463) -> Result<(), Errno> {
1464 track_hook_duration!("security.hooks.bprm_creds_for_exec");
1465 if let Some(state) = ¤t_task.kernel().security_state.state {
1466 if state.has_policy() {
1467 return selinux_hooks::task::bprm_creds_for_exec(
1468 &state.server,
1469 current_task,
1470 executable,
1471 elf_state,
1472 );
1473 } else {
1474 let previous_sid = current_task.current_creds().security_state.current_sid;
1476 elf_state.creds.security_state =
1477 TaskAttrs::for_transition(InitialSid::Init.into(), previous_sid);
1478 }
1479 }
1480 Ok(())
1481}
1482
1483pub fn bprm_committing_creds(
1489 locked: &mut Locked<Unlocked>,
1490 current_task: &CurrentTask,
1491 elf_state: &ResolvedElf,
1492) -> Result<(), Errno> {
1493 track_hook_duration!("security.hooks.bprm_committing_creds");
1494 if_selinux_else_default_ok(current_task, |security_server| {
1495 selinux_hooks::task::bprm_committing_creds(
1496 locked,
1497 security_server,
1498 current_task,
1499 elf_state,
1500 );
1501 Ok(())
1502 })
1503}
1504
1505pub fn bprm_committed_creds(
1509 _locked: &mut Locked<Unlocked>,
1510 current_task: &CurrentTask,
1511) -> Result<(), Errno> {
1512 track_hook_duration!("security.hooks.bprm_committed_creds");
1513 if_selinux_else_default_ok(current_task, |security_server| {
1514 selinux_hooks::task::bprm_committed_creds(security_server, current_task);
1515 Ok(())
1516 })
1517}
1518
1519pub fn check_task_getscheduler_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1522 track_hook_duration!("security.hooks.task_getscheduler");
1523 if_selinux_else_default_ok(source, |security_server| {
1524 selinux_hooks::task::check_getsched_access(
1525 &selinux_hooks::build_permission_check(source, security_server),
1526 &source,
1527 &target,
1528 )
1529 })
1530}
1531
1532pub fn check_task_setscheduler_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1535 track_hook_duration!("security.hooks.task_setscheduler");
1536 if_selinux_else_default_ok(source, |security_server| {
1537 selinux_hooks::task::check_setsched_access(
1538 &selinux_hooks::build_permission_check(source, security_server),
1539 &source,
1540 &target,
1541 )
1542 })
1543}
1544
1545pub fn check_task_setnice_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1548 track_hook_duration!("security.hooks.task_setnice");
1549 if_selinux_else_default_ok(source, |security_server| {
1550 selinux_hooks::task::check_setsched_access(
1551 &selinux_hooks::build_permission_check(source, security_server),
1552 &source,
1553 &target,
1554 )
1555 })
1556}
1557
1558pub fn check_getpgid_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1561 track_hook_duration!("security.hooks.check_getpgid_access");
1562 if_selinux_else_default_ok(source, |security_server| {
1563 selinux_hooks::task::check_getpgid_access(
1564 &selinux_hooks::build_permission_check(source, security_server),
1565 &source,
1566 &target,
1567 )
1568 })
1569}
1570
1571pub fn check_setpgid_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1574 track_hook_duration!("security.hooks.check_setpgid_access");
1575 if_selinux_else_default_ok(source, |security_server| {
1576 selinux_hooks::task::check_setpgid_access(
1577 &selinux_hooks::build_permission_check(source, security_server),
1578 &source,
1579 &target,
1580 )
1581 })
1582}
1583
1584pub fn check_task_getsid(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1587 track_hook_duration!("security.hooks.check_task_getsid");
1588 if_selinux_else_default_ok(source, |security_server| {
1589 selinux_hooks::task::check_task_getsid(
1590 &selinux_hooks::build_permission_check(source, security_server),
1591 &source,
1592 &target,
1593 )
1594 })
1595}
1596
1597pub fn check_getcap_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1600 track_hook_duration!("security.hooks.check_getcap_access");
1601 if_selinux_else_default_ok(source, |security_server| {
1602 selinux_hooks::task::check_getcap_access(
1603 &selinux_hooks::build_permission_check(source, security_server),
1604 &source,
1605 &target,
1606 )
1607 })
1608}
1609
1610pub fn check_setcap_access(source: &CurrentTask, target: &Task) -> Result<(), Errno> {
1614 track_hook_duration!("security.hooks.check_setcap_access");
1615 if_selinux_else_default_ok(source, |security_server| {
1616 selinux_hooks::task::check_setcap_access(
1617 &selinux_hooks::build_permission_check(source, security_server),
1618 &source,
1619 &target,
1620 )
1621 })
1622}
1623
1624pub fn check_signal_access(
1627 source: &CurrentTask,
1628 target: &Task,
1629 signal: Signal,
1630) -> Result<(), Errno> {
1631 track_hook_duration!("security.hooks.check_signal_access");
1632 if_selinux_else_default_ok(source, |security_server| {
1633 selinux_hooks::task::check_signal_access(
1634 &selinux_hooks::build_permission_check(source, security_server),
1635 &source,
1636 &target,
1637 signal,
1638 )
1639 })
1640}
1641
1642pub fn check_syslog_access(source: &CurrentTask, action: SyslogAction) -> Result<(), Errno> {
1645 track_hook_duration!("security.hooks.check_syslog_access");
1646 if_selinux_else_default_ok(source, |security_server| {
1647 selinux_hooks::task::check_syslog_access(
1648 &selinux_hooks::build_permission_check(source, security_server),
1649 &source,
1650 action,
1651 )
1652 })
1653}
1654
1655pub fn ptrace_traceme(current_task: &CurrentTask, parent_tracer_task: &Task) -> Result<(), Errno> {
1658 track_hook_duration!("security.hooks.ptrace_traceme");
1659 yama::ptrace_traceme(current_task, parent_tracer_task)?;
1660 common_cap::ptrace_traceme(current_task, parent_tracer_task)?;
1661 if_selinux_else_default_ok(current_task, |security_server| {
1662 selinux_hooks::task::ptrace_traceme(
1663 &selinux_hooks::build_permission_check(current_task, security_server),
1664 current_task,
1665 parent_tracer_task,
1666 )
1667 })
1668}
1669
1670pub fn ptrace_access_check(
1673 current_task: &CurrentTask,
1674 tracee_task: &Task,
1675 mode: PtraceAccessMode,
1676) -> Result<(), Errno> {
1677 track_hook_duration!("security.hooks.ptrace_access_check");
1678 yama::ptrace_access_check(current_task, tracee_task, mode)?;
1679 common_cap::ptrace_access_check(current_task, tracee_task, mode)?;
1680 if_selinux_else_default_ok(current_task, |security_server| {
1681 selinux_hooks::task::ptrace_access_check(
1682 &selinux_hooks::build_permission_check(current_task, security_server),
1683 current_task,
1684 tracee_task,
1685 mode,
1686 )
1687 })
1688}
1689
1690pub fn task_prlimit(
1693 source: &CurrentTask,
1694 target: &Task,
1695 check_get_rlimit: bool,
1696 check_set_rlimit: bool,
1697) -> Result<(), Errno> {
1698 track_hook_duration!("security.hooks.task_prlimit");
1699 if_selinux_else_default_ok(source, |security_server| {
1700 selinux_hooks::task::task_prlimit(
1701 &selinux_hooks::build_permission_check(source, security_server),
1702 &source,
1703 &target,
1704 check_get_rlimit,
1705 check_set_rlimit,
1706 )
1707 })
1708}
1709
1710pub fn task_setrlimit(
1713 source: &CurrentTask,
1714 target: &Task,
1715 old_limit: rlimit,
1716 new_limit: rlimit,
1717) -> Result<(), Errno> {
1718 track_hook_duration!("security.hooks.task_setrlimit");
1719 if_selinux_else_default_ok(source, |security_server| {
1720 selinux_hooks::task::task_setrlimit(
1721 &selinux_hooks::build_permission_check(source, security_server),
1722 &source,
1723 &target,
1724 old_limit,
1725 new_limit,
1726 )
1727 })
1728}
1729
1730pub fn sb_kern_mount(current_task: &CurrentTask, fs: &FileSystem) -> Result<(), Errno> {
1733 track_hook_duration!("security.hooks.sb_kern_mount");
1734 if_selinux_else_default_ok(current_task, |security_server| {
1735 selinux_hooks::superblock::sb_kern_mount(
1736 &selinux_hooks::build_permission_check(current_task, security_server),
1737 current_task,
1738 fs,
1739 )
1740 })
1741}
1742
1743pub fn sb_mount(
1747 current_task: &CurrentTask,
1748 path: &NamespaceNode,
1749 flags: MountFlags,
1750) -> Result<(), Errno> {
1751 track_hook_duration!("security.hooks.sb_mount");
1752 if_selinux_else_default_ok(current_task, |security_server| {
1753 selinux_hooks::superblock::sb_mount(
1754 &selinux_hooks::build_permission_check(current_task, security_server),
1755 current_task,
1756 path,
1757 flags,
1758 )
1759 })
1760}
1761
1762pub fn sb_remount(
1765 current_task: &CurrentTask,
1766 mount: &Mount,
1767 new_mount_options: FileSystemMountOptions,
1768) -> Result<(), Errno> {
1769 track_hook_duration!("security.hooks.sb_remount");
1770 if_selinux_else_default_ok(current_task, |security_server| {
1771 selinux_hooks::superblock::sb_remount(security_server, mount, new_mount_options)
1772 })
1773}
1774
1775pub fn sb_show_options<'a>(
1778 _kernel: &Kernel,
1779 fs: &'a FileSystem,
1780) -> Result<impl std::fmt::Display + 'a, Errno> {
1781 track_hook_duration!("security.hooks.sb_show_options");
1782 selinux_hooks::superblock::sb_show_options(fs)
1783}
1784
1785pub fn sb_statfs(current_task: &CurrentTask, fs: &FileSystem) -> Result<(), Errno> {
1788 track_hook_duration!("security.hooks.sb_statfs");
1789 if_selinux_else_default_ok(current_task, |security_server| {
1790 selinux_hooks::superblock::sb_statfs(
1791 &selinux_hooks::build_permission_check(current_task, security_server),
1792 current_task,
1793 fs,
1794 )
1795 })
1796}
1797
1798pub fn sb_umount(
1802 current_task: &CurrentTask,
1803 node: &NamespaceNode,
1804 flags: UnmountFlags,
1805) -> Result<(), Errno> {
1806 track_hook_duration!("security.hooks.sb_umount");
1807 if_selinux_else_default_ok(current_task, |security_server| {
1808 selinux_hooks::superblock::sb_umount(
1809 &selinux_hooks::build_permission_check(current_task, security_server),
1810 current_task,
1811 node,
1812 flags,
1813 )
1814 })
1815}
1816
1817pub fn check_fs_node_getattr_access(
1820 current_task: &CurrentTask,
1821 fs_node: &FsNode,
1822) -> Result<(), Errno> {
1823 track_hook_duration!("security.hooks.check_fs_node_getattr_access");
1824 if_selinux_else_default_ok(current_task, |security_server| {
1825 selinux_hooks::fs_node::check_fs_node_getattr_access(security_server, current_task, fs_node)
1826 })
1827}
1828
1829pub fn fs_node_xattr_skipcap(_current_task: &CurrentTask, name: &FsStr) -> bool {
1832 selinux_hooks::fs_node::fs_node_xattr_skipcap(name)
1833}
1834
1835pub fn check_fs_node_setxattr_access(
1841 current_task: &CurrentTask,
1842 fs_node: &FsNode,
1843 name: &FsStr,
1844 value: &FsStr,
1845 op: XattrOp,
1846) -> Result<(), Errno> {
1847 track_hook_duration!("security.hooks.check_fs_node_setxattr_access");
1848 common_cap::fs_node_setxattr(current_task, fs_node, name, value, op)?;
1849 if_selinux_else_default_ok(current_task, |security_server| {
1850 selinux_hooks::fs_node::check_fs_node_setxattr_access(
1851 security_server,
1852 current_task,
1853 fs_node,
1854 name,
1855 value,
1856 op,
1857 )
1858 })
1859}
1860
1861pub fn check_fs_node_getxattr_access(
1863 current_task: &CurrentTask,
1864 fs_node: &FsNode,
1865 name: &FsStr,
1866) -> Result<(), Errno> {
1867 track_hook_duration!("security.hooks.check_fs_node_getxattr_access");
1868 if_selinux_else_default_ok(current_task, |security_server| {
1869 selinux_hooks::fs_node::check_fs_node_getxattr_access(
1870 security_server,
1871 current_task,
1872 fs_node,
1873 name,
1874 )
1875 })
1876}
1877
1878pub fn check_fs_node_listxattr_access(
1880 current_task: &CurrentTask,
1881 fs_node: &FsNode,
1882) -> Result<(), Errno> {
1883 track_hook_duration!("security.hooks.check_fs_node_listxattr_access");
1884 if_selinux_else_default_ok(current_task, |security_server| {
1885 selinux_hooks::fs_node::check_fs_node_listxattr_access(
1886 security_server,
1887 current_task,
1888 fs_node,
1889 )
1890 })
1891}
1892
1893pub fn check_fs_node_removexattr_access(
1895 current_task: &CurrentTask,
1896 fs_node: &FsNode,
1897 name: &FsStr,
1898) -> Result<(), Errno> {
1899 track_hook_duration!("security.hooks.check_fs_node_removexattr_access");
1900 common_cap::fs_node_removexattr(current_task, fs_node, name)?;
1901 if_selinux_else_default_ok(current_task, |security_server| {
1902 selinux_hooks::fs_node::check_fs_node_removexattr_access(
1903 security_server,
1904 current_task,
1905 fs_node,
1906 name,
1907 )
1908 })
1909}
1910
1911pub fn fs_node_listsecurity(current_task: &CurrentTask, fs_node: &FsNode) -> Option<FsString> {
1918 track_hook_duration!("security.hooks.fs_node_listsecurity");
1919 if_selinux_else(
1920 current_task,
1921 |_| selinux_hooks::fs_node::fs_node_listsecurity(fs_node),
1922 || None,
1923 )
1924}
1925
1926pub fn fs_node_getsecurity<L>(
1934 locked: &mut Locked<L>,
1935 current_task: &CurrentTask,
1936 fs_node: &FsNode,
1937 name: &FsStr,
1938 max_size: usize,
1939) -> Result<ValueOrSize<FsString>, Errno>
1940where
1941 L: LockEqualOrBefore<FileOpsCore>,
1942{
1943 track_hook_duration!("security.hooks.fs_node_getsecurity");
1944 if_selinux_else_with_context(
1945 locked,
1946 current_task,
1947 |locked, security_server| {
1948 selinux_hooks::fs_node::fs_node_getsecurity(
1949 locked,
1950 security_server,
1951 current_task,
1952 fs_node,
1953 name,
1954 max_size,
1955 )
1956 },
1957 |locked| {
1958 fs_node.ops().get_xattr(
1959 locked.cast_locked::<FileOpsCore>(),
1960 fs_node,
1961 current_task,
1962 name,
1963 max_size,
1964 )
1965 },
1966 )
1967}
1968
1969pub fn fs_node_setsecurity<L>(
1975 locked: &mut Locked<L>,
1976 current_task: &CurrentTask,
1977 fs_node: &FsNode,
1978 name: &FsStr,
1979 value: &FsStr,
1980 op: XattrOp,
1981) -> Result<(), Errno>
1982where
1983 L: LockEqualOrBefore<FileOpsCore>,
1984{
1985 track_hook_duration!("security.hooks.fs_node_setsecurity");
1986 if_selinux_else_with_context(
1987 locked,
1988 current_task,
1989 |locked, security_server| {
1990 selinux_hooks::fs_node::fs_node_setsecurity(
1991 locked,
1992 security_server,
1993 current_task,
1994 fs_node,
1995 name,
1996 value,
1997 op,
1998 )
1999 },
2000 |locked| {
2001 fs_node.ops().set_xattr(
2002 locked.cast_locked::<FileOpsCore>(),
2003 fs_node,
2004 current_task,
2005 name,
2006 value,
2007 op,
2008 )
2009 },
2010 )
2011}
2012
2013pub fn check_bpf_access<Attr: FromBytes>(
2017 current_task: &CurrentTask,
2018 cmd: bpf_cmd,
2019 attr: &Attr,
2020 attr_size: u32,
2021) -> Result<(), Errno> {
2022 track_hook_duration!("security.hooks.check_bpf_access");
2023 if_selinux_else_default_ok(current_task, |security_server| {
2024 selinux_hooks::bpf::check_bpf_access(security_server, current_task, cmd, attr, attr_size)
2025 })
2026}
2027
2028pub fn check_bpf_map_access(
2032 current_task: &CurrentTask,
2033 bpf_map_state: &BpfMapState,
2034 flags: PermissionFlags,
2035) -> Result<(), Errno> {
2036 track_hook_duration!("security.hooks.check_bpf_map_access");
2037 if_selinux_else_default_ok(current_task, |security_server| {
2038 let subject_sid = current_task_state(current_task).current_sid;
2039 selinux_hooks::bpf::check_bpf_map_access(
2040 security_server,
2041 current_task,
2042 subject_sid,
2043 bpf_map_state,
2044 flags,
2045 )
2046 })
2047}
2048
2049pub fn check_bpf_prog_access(
2054 current_task: &CurrentTask,
2055 bpf_program_state: &BpfProgState,
2056) -> Result<(), Errno> {
2057 track_hook_duration!("security.hooks.check_bpf_prog_access");
2058 if_selinux_else_default_ok(current_task, |security_server| {
2059 let subject_sid = current_task_state(current_task).current_sid;
2060 selinux_hooks::bpf::check_bpf_prog_access(
2061 security_server,
2062 current_task,
2063 subject_sid,
2064 bpf_program_state,
2065 )
2066 })
2067}
2068
2069pub fn check_perf_event_open_access(
2073 current_task: &CurrentTask,
2074 target_task_type: TargetTaskType<'_>,
2075 attr: &perf_event_attr,
2076 event_type: PerfEventType,
2077) -> Result<(), Errno> {
2078 track_hook_duration!("security.hooks.check_perf_event_open_access");
2079 if_selinux_else_default_ok(current_task, |security_server| {
2080 selinux_hooks::perf_event::check_perf_event_open_access(
2081 security_server,
2082 current_task,
2083 target_task_type,
2084 attr,
2085 event_type,
2086 )
2087 })
2088}
2089
2090pub fn perf_event_alloc(current_task: &CurrentTask) -> PerfEventState {
2094 track_hook_duration!("security.hooks.perf_event_alloc");
2095 PerfEventState { state: selinux_hooks::perf_event::perf_event_alloc(current_task) }
2096}
2097
2098pub fn check_perf_event_read_access(
2101 current_task: &CurrentTask,
2102 perf_event_file: &PerfEventFile,
2103) -> Result<(), Errno> {
2104 track_hook_duration!("security.hooks.check_perf_event_read_access");
2105 if_selinux_else_default_ok(current_task, |security_server| {
2106 selinux_hooks::perf_event::check_perf_event_read_access(
2107 security_server,
2108 current_task,
2109 perf_event_file,
2110 )
2111 })
2112}
2113
2114pub fn check_perf_event_write_access(
2117 current_task: &CurrentTask,
2118 perf_event_file: &PerfEventFile,
2119) -> Result<(), Errno> {
2120 track_hook_duration!("security.hooks.check_perf_event_write_access");
2121 if_selinux_else_default_ok(current_task, |security_server| {
2122 selinux_hooks::perf_event::check_perf_event_write_access(
2123 security_server,
2124 current_task,
2125 perf_event_file,
2126 )
2127 })
2128}
2129
2130#[derive(Debug, Clone, Copy, PartialEq)]
2132pub enum ProcAttr {
2133 Current,
2134 Exec,
2135 FsCreate,
2136 KeyCreate,
2137 Previous,
2138 SockCreate,
2139}
2140
2141pub fn get_procattr(
2144 current_task: &CurrentTask,
2145 target: &Task,
2146 attr: ProcAttr,
2147) -> Result<Vec<u8>, Errno> {
2148 track_hook_duration!("security.hooks.get_procattr");
2149 if_selinux_else(
2150 current_task,
2151 |security_server| {
2152 selinux_hooks::task::get_procattr(security_server, current_task, target, attr)
2153 },
2154 || error!(EINVAL),
2156 )
2157}
2158
2159pub fn set_procattr(
2162 current_task: &CurrentTask,
2163 attr: ProcAttr,
2164 context: &[u8],
2165) -> Result<(), Errno> {
2166 track_hook_duration!("security.hooks.set_procattr");
2167 if_selinux_else(
2168 current_task,
2169 |security_server| {
2170 selinux_hooks::task::set_procattr(security_server, current_task, attr, context)
2171 },
2172 || error!(EINVAL),
2174 )
2175}
2176
2177pub fn fs_is_xattr_labeled(fs: FileSystemHandle) -> bool {
2179 fs.security_state.state.supports_xattr()
2180}
2181
2182pub fn selinuxfs_init_null(current_task: &CurrentTask, null_fs_node: &FileHandle) {
2185 selinux_hooks::selinuxfs::selinuxfs_init_null(current_task, null_fs_node)
2188}
2189
2190pub fn selinuxfs_policy_loaded<L>(locked: &mut Locked<L>, current_task: &CurrentTask)
2196where
2197 L: LockEqualOrBefore<FileOpsCore>,
2198{
2199 track_hook_duration!("security.hooks.selinuxfs_policy_loaded");
2200 selinux_hooks::selinuxfs::selinuxfs_policy_loaded(locked, current_task)
2201}
2202
2203pub fn selinuxfs_get_admin_api(current_task: &CurrentTask) -> Option<Arc<SecurityServer>> {
2207 current_task.kernel().security_state.state.as_ref().map(|state| state.server.clone())
2208}
2209
2210pub fn selinuxfs_check_access(
2213 current_task: &CurrentTask,
2214 permission: SecurityPermission,
2215) -> Result<(), Errno> {
2216 track_hook_duration!("security.hooks.selinuxfs_check_access");
2217 if_selinux_else_default_ok(current_task, |security_server| {
2218 selinux_hooks::selinuxfs::selinuxfs_check_access(security_server, current_task, permission)
2219 })
2220}
2221
2222pub fn creds_start_internal_operation(current_task: &CurrentTask) -> Arc<Credentials> {
2225 track_hook_duration!("security.hooks.creds_start_internal_operation");
2226 let mut creds = Credentials::clone(¤t_task.current_creds());
2227 creds.security_state.internal_operation = true;
2228 creds.into()
2229}
2230
2231pub mod testing {
2232 use super::{Arc, KernelState, SecurityServer, selinux_hooks};
2233 use starnix_sync::LockDepMutex;
2234 use std::sync::OnceLock;
2235 use std::sync::atomic::AtomicU64;
2236
2237 pub fn kernel_state(security_server: Option<Arc<SecurityServer>>) -> KernelState {
2240 let state = security_server.map(|server| selinux_hooks::KernelState {
2241 server,
2242 pending_file_systems: LockDepMutex::default(),
2243 selinuxfs_null: OnceLock::default(),
2244 access_denial_count: AtomicU64::new(0u64),
2245 has_policy: false.into(),
2246 _inspect_node: fuchsia_inspect::Node::default(),
2247 });
2248 KernelState { state }
2249 }
2250}
2251
2252#[cfg(test)]
2253mod tests {
2254 use super::*;
2255 use crate::security;
2256 use crate::security::selinux_hooks::get_cached_sid;
2257 use crate::security::selinux_hooks::testing::{
2258 self, spawn_kernel_with_selinux_hooks_test_policy_and_run,
2259 };
2260 use crate::testing::{create_task, spawn_kernel_and_run, spawn_kernel_with_selinux_and_run};
2261 use linux_uapi::XATTR_NAME_SELINUX;
2262 use selinux::InitialSid;
2263 use starnix_uapi::auth::PTRACE_MODE_ATTACH;
2264 use starnix_uapi::signals::SIGTERM;
2265
2266 const VALID_SECURITY_CONTEXT: &[u8] = b"u:object_r:test_valid_t:s0";
2267 const VALID_SECURITY_CONTEXT_WITH_NUL: &[u8] = b"u:object_r:test_valid_t:s0\0";
2268
2269 const DIFFERENT_VALID_SECURITY_CONTEXT: &[u8] = b"u:object_r:test_different_valid_t:s0";
2270 const DIFFERENT_VALID_SECURITY_CONTEXT_WITH_NUL: &[u8] =
2271 b"u:object_r:test_different_valid_t:s0\0";
2272
2273 const INVALID_SECURITY_CONTEXT_INTERNAL_NUL: &[u8] = b"u:object_r:test_valid_\0t:s0";
2274
2275 const INVALID_SECURITY_CONTEXT: &[u8] = b"not_a_u:object_r:test_valid_t:s0";
2276
2277 #[derive(Default, Debug, PartialEq)]
2278 enum TestHookResult {
2279 WasRun,
2280 WasNotRun,
2281 #[default]
2282 WasNotRunDefault,
2283 }
2284
2285 #[fuchsia::test]
2286 async fn if_selinux_else_disabled() {
2287 spawn_kernel_and_run(async |_, current_task| {
2288 assert!(current_task.kernel().security_state.state.is_none());
2289
2290 let check_result =
2291 if_selinux_else_default_ok(current_task, |_| Ok(TestHookResult::WasRun));
2292 assert_eq!(check_result, Ok(TestHookResult::WasNotRunDefault));
2293
2294 let run_else_result = if_selinux_else(
2295 current_task,
2296 |_| TestHookResult::WasRun,
2297 || TestHookResult::WasNotRun,
2298 );
2299 assert_eq!(run_else_result, TestHookResult::WasNotRun);
2300 })
2301 .await;
2302 }
2303
2304 #[fuchsia::test]
2305 async fn if_selinux_else_without_policy() {
2306 spawn_kernel_with_selinux_and_run(async |_locked, current_task, _security_server| {
2307 let check_result =
2308 if_selinux_else_default_ok(current_task, |_| Ok(TestHookResult::WasRun));
2309 assert_eq!(check_result, Ok(TestHookResult::WasNotRunDefault));
2310
2311 let run_else_result = if_selinux_else(
2312 current_task,
2313 |_| TestHookResult::WasRun,
2314 || TestHookResult::WasNotRun,
2315 );
2316 assert_eq!(run_else_result, TestHookResult::WasNotRun);
2317 })
2318 .await;
2319 }
2320
2321 #[fuchsia::test]
2322 async fn if_selinux_else_with_policy() {
2323 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2324 |_locked, current_task, _security_server| {
2325 let check_result =
2326 if_selinux_else_default_ok(current_task, |_| Ok(TestHookResult::WasRun));
2327 assert_eq!(check_result, Ok(TestHookResult::WasRun));
2328
2329 let run_else_result = if_selinux_else(
2330 current_task,
2331 |_| TestHookResult::WasRun,
2332 || TestHookResult::WasNotRun,
2333 );
2334 assert_eq!(run_else_result, TestHookResult::WasRun);
2335 },
2336 )
2337 .await;
2338 }
2339
2340 #[fuchsia::test]
2341 async fn task_create_access_allowed_for_selinux_disabled() {
2342 spawn_kernel_and_run(async |_, current_task| {
2343 assert!(current_task.kernel().security_state.state.is_none());
2344 assert_eq!(check_task_create_access(current_task), Ok(()));
2345 })
2346 .await;
2347 }
2348
2349 #[fuchsia::test]
2350 async fn task_create_access_allowed_for_permissive_mode() {
2351 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2352 |_locked, current_task, security_server| {
2353 security_server.set_enforcing(false);
2354 assert_eq!(check_task_create_access(current_task), Ok(()));
2355 },
2356 )
2357 .await;
2358 }
2359
2360 #[fuchsia::test]
2361 async fn exec_access_allowed_for_selinux_disabled() {
2362 spawn_kernel_and_run(async |locked, current_task| {
2363 assert!(current_task.kernel().security_state.state.is_none());
2364 let executable = testing::create_test_file(locked, current_task);
2365 let mut resolved_elf =
2366 testing::make_resolved_elf(locked, current_task, executable.clone());
2367 assert_eq!(bprm_creds_for_exec(current_task, &executable, &mut resolved_elf), Ok(()));
2368 })
2369 .await;
2370 }
2371
2372 #[fuchsia::test]
2373 async fn exec_access_allowed_for_permissive_mode() {
2374 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2375 |locked, current_task, security_server| {
2376 security_server.set_enforcing(false);
2377 let executable = testing::create_test_file(locked, current_task);
2378 let mut resolved_elf =
2379 testing::make_resolved_elf(locked, current_task, executable.clone());
2380 let result = bprm_creds_for_exec(current_task, &executable, &mut resolved_elf);
2382 assert!(result.is_ok());
2383 },
2384 )
2385 .await;
2386 }
2387
2388 #[fuchsia::test]
2389 async fn exec_no_state_update_for_selinux_disabled() {
2390 spawn_kernel_and_run(async |locked, current_task| {
2391 let target_sid = InitialSid::Unlabeled.into();
2392
2393 assert!(selinux_hooks::current_task_state(current_task).current_sid != target_sid);
2394
2395 testing::mutate_attrs_for_test(current_task, |attrs| {
2397 attrs.exec_sid = Some(target_sid);
2398 });
2399
2400 let executable = testing::create_test_file(locked, current_task);
2401 let mut resolved_elf =
2402 testing::make_resolved_elf(locked, current_task, executable.clone());
2403
2404 let before_hook_sid = selinux_hooks::current_task_state(current_task).current_sid;
2405
2406 bprm_creds_for_exec(current_task, &executable, &mut resolved_elf).unwrap();
2407 assert_eq!(resolved_elf.creds.security_state.current_sid, before_hook_sid);
2408 })
2409 .await;
2410 }
2411
2412 #[fuchsia::test]
2413 async fn exec_initial_context_for_selinux_without_policy() {
2414 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2415 let elf_sid = InitialSid::Unlabeled.into();
2416 assert_ne!(selinux_hooks::current_task_state(current_task).current_sid, elf_sid);
2417 assert_ne!(
2418 selinux_hooks::current_task_state(current_task).current_sid,
2419 InitialSid::Init.into()
2420 );
2421
2422 testing::mutate_attrs_for_test(current_task, |attrs| {
2424 attrs.exec_sid = Some(elf_sid);
2425 });
2426
2427 let executable = testing::create_test_file(locked, current_task);
2428 let mut resolved_elf =
2429 testing::make_resolved_elf(locked, current_task, executable.clone());
2430
2431 bprm_creds_for_exec(current_task, &executable, &mut resolved_elf).unwrap();
2432
2433 assert_eq!(resolved_elf.creds.security_state.current_sid, InitialSid::Init.into());
2434 })
2435 .await;
2436 }
2437
2438 #[fuchsia::test]
2439 async fn exec_state_update_for_permissive_mode() {
2440 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2441 |locked, current_task, security_server| {
2442 security_server.set_enforcing(false);
2443 let elf_sid = security_server
2444 .security_context_to_sid(b"u:object_r:fork_no_t:s0".into())
2445 .expect("invalid security context");
2446
2447 assert_ne!(elf_sid, selinux_hooks::current_task_state(current_task).current_sid);
2448
2449 testing::mutate_attrs_for_test(current_task, |attrs| {
2451 attrs.exec_sid = Some(elf_sid);
2452 });
2453
2454 let executable = testing::create_test_file(locked, current_task);
2455 let mut resolved_elf =
2456 testing::make_resolved_elf(locked, current_task, executable.clone());
2457
2458 bprm_creds_for_exec(current_task, &executable, &mut resolved_elf).unwrap();
2459 assert_eq!(resolved_elf.creds.security_state.current_sid, elf_sid);
2460 },
2461 )
2462 .await;
2463 }
2464
2465 #[fuchsia::test]
2466 async fn getsched_access_allowed_for_selinux_disabled() {
2467 spawn_kernel_and_run(async |locked, current_task| {
2468 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2469 assert_eq!(check_task_getscheduler_access(current_task, &another_task), Ok(()));
2470 })
2471 .await;
2472 }
2473
2474 #[fuchsia::test]
2475 async fn getsched_access_allowed_for_permissive_mode() {
2476 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2477 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2478 assert_eq!(check_task_getscheduler_access(current_task, &another_task), Ok(()));
2479 })
2480 .await;
2481 }
2482
2483 #[fuchsia::test]
2484 async fn setsched_access_allowed_for_selinux_disabled() {
2485 spawn_kernel_and_run(async |locked, current_task| {
2486 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2487 assert_eq!(check_task_setscheduler_access(current_task, &another_task), Ok(()));
2488 })
2489 .await;
2490 }
2491
2492 #[fuchsia::test]
2493 async fn setsched_access_allowed_for_permissive_mode() {
2494 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2495 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2496 assert_eq!(check_task_setscheduler_access(current_task, &another_task), Ok(()));
2497 })
2498 .await;
2499 }
2500
2501 #[fuchsia::test]
2502 async fn getpgid_access_allowed_for_selinux_disabled() {
2503 spawn_kernel_and_run(async |locked, current_task| {
2504 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2505 assert_eq!(check_getpgid_access(current_task, &another_task), Ok(()));
2506 })
2507 .await;
2508 }
2509
2510 #[fuchsia::test]
2511 async fn getpgid_access_allowed_for_permissive_mode() {
2512 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2513 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2514 assert_eq!(check_getpgid_access(current_task, &another_task), Ok(()));
2515 })
2516 .await;
2517 }
2518
2519 #[fuchsia::test]
2520 async fn setpgid_access_allowed_for_selinux_disabled() {
2521 spawn_kernel_and_run(async |locked, current_task| {
2522 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2523 assert_eq!(check_setpgid_access(current_task, &another_task), Ok(()));
2524 })
2525 .await;
2526 }
2527
2528 #[fuchsia::test]
2529 async fn setpgid_access_allowed_for_permissive_mode() {
2530 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2531 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2532 assert_eq!(check_setpgid_access(current_task, &another_task), Ok(()));
2533 })
2534 .await;
2535 }
2536
2537 #[fuchsia::test]
2538 async fn task_getsid_allowed_for_selinux_disabled() {
2539 spawn_kernel_and_run(async |locked, current_task| {
2540 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2541 assert_eq!(check_task_getsid(current_task, &another_task), Ok(()));
2542 })
2543 .await;
2544 }
2545
2546 #[fuchsia::test]
2547 async fn task_getsid_allowed_for_permissive_mode() {
2548 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2549 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2550 assert_eq!(check_task_getsid(current_task, &another_task), Ok(()));
2551 })
2552 .await;
2553 }
2554
2555 #[fuchsia::test]
2556 async fn signal_access_allowed_for_selinux_disabled() {
2557 spawn_kernel_and_run(async |locked, current_task| {
2558 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2559 assert_eq!(check_signal_access(current_task, &another_task, SIGTERM), Ok(()));
2560 })
2561 .await;
2562 }
2563
2564 #[fuchsia::test]
2565 async fn signal_access_allowed_for_permissive_mode() {
2566 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2567 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2568 assert_eq!(check_signal_access(current_task, &another_task, SIGTERM), Ok(()));
2569 })
2570 .await;
2571 }
2572
2573 #[fuchsia::test]
2574 async fn ptrace_traceme_access_allowed_for_selinux_disabled() {
2575 spawn_kernel_and_run(async |locked, current_task| {
2576 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2577 assert_eq!(ptrace_traceme(current_task, &another_task), Ok(()));
2578 })
2579 .await;
2580 }
2581
2582 #[fuchsia::test]
2583 async fn ptrace_traceme_access_allowed_for_permissive_mode() {
2584 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2585 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2586 assert_eq!(ptrace_traceme(current_task, &another_task), Ok(()));
2587 })
2588 .await;
2589 }
2590
2591 #[fuchsia::test]
2592 async fn ptrace_attach_access_allowed_for_selinux_disabled() {
2593 spawn_kernel_and_run(async |locked, current_task| {
2594 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2595 assert_eq!(
2596 ptrace_access_check(current_task, &another_task, PTRACE_MODE_ATTACH),
2597 Ok(())
2598 );
2599 })
2600 .await;
2601 }
2602
2603 #[fuchsia::test]
2604 async fn ptrace_attach_access_allowed_for_permissive_mode() {
2605 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2606 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2607 assert_eq!(
2608 ptrace_access_check(current_task, &another_task, PTRACE_MODE_ATTACH),
2609 Ok(())
2610 );
2611 })
2612 .await;
2613 }
2614
2615 #[fuchsia::test]
2616 async fn task_prlimit_access_allowed_for_selinux_disabled() {
2617 spawn_kernel_and_run(async |locked, current_task| {
2618 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2619 assert_eq!(task_prlimit(current_task, &another_task, true, true), Ok(()));
2620 })
2621 .await;
2622 }
2623
2624 #[fuchsia::test]
2625 async fn task_prlimit_access_allowed_for_permissive_mode() {
2626 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2627 let another_task = create_task(locked, ¤t_task.kernel(), "another-task");
2628 assert_eq!(task_prlimit(current_task, &another_task, true, true), Ok(()));
2629 })
2630 .await;
2631 }
2632
2633 #[fuchsia::test]
2634 async fn fs_node_task_to_fs_node_noop_selinux_disabled() {
2635 spawn_kernel_and_run(async |locked, current_task| {
2636 let node = &testing::create_test_file(locked, current_task).entry.node;
2637 task_to_fs_node(current_task, ¤t_task.task, &node);
2638 assert_eq!(None, selinux_hooks::get_cached_sid(node));
2639 })
2640 .await;
2641 }
2642
2643 #[fuchsia::test]
2644 async fn fs_node_setsecurity_selinux_disabled_only_sets_xattr() {
2645 spawn_kernel_and_run(async |locked, current_task| {
2646 let node = &testing::create_test_file(locked, current_task).entry.node;
2647
2648 fs_node_setsecurity(
2649 locked,
2650 current_task,
2651 &node,
2652 XATTR_NAME_SELINUX.to_bytes().into(),
2653 VALID_SECURITY_CONTEXT.into(),
2654 XattrOp::Set,
2655 )
2656 .expect("set_xattr(security.selinux) failed");
2657
2658 assert_eq!(None, selinux_hooks::get_cached_sid(node));
2659 })
2660 .await;
2661 }
2662
2663 #[fuchsia::test]
2664 async fn fs_node_setsecurity_selinux_without_policy_only_sets_xattr() {
2665 spawn_kernel_with_selinux_and_run(async |locked, current_task, _security_server| {
2666 let node = &testing::create_test_file(locked, current_task).entry.node;
2667 fs_node_setsecurity(
2668 locked,
2669 current_task,
2670 &node,
2671 XATTR_NAME_SELINUX.to_bytes().into(),
2672 VALID_SECURITY_CONTEXT.into(),
2673 XattrOp::Set,
2674 )
2675 .expect("set_xattr(security.selinux) failed");
2676
2677 assert_eq!(None, selinux_hooks::get_cached_sid(node));
2678 })
2679 .await;
2680 }
2681
2682 #[fuchsia::test]
2683 async fn fs_node_setsecurity_selinux_permissive_sets_xattr_and_label() {
2684 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2685 |locked, current_task, security_server| {
2686 security_server.set_enforcing(false);
2687 let expected_sid = security_server
2688 .security_context_to_sid(VALID_SECURITY_CONTEXT.into())
2689 .expect("no SID for VALID_SECURITY_CONTEXT");
2690 let node = &testing::create_test_file(locked, ¤t_task).entry.node;
2691
2692 assert_ne!(Some(expected_sid), selinux_hooks::get_cached_sid(node));
2694
2695 fs_node_setsecurity(
2696 locked,
2697 current_task,
2698 &node,
2699 XATTR_NAME_SELINUX.to_bytes().into(),
2700 VALID_SECURITY_CONTEXT.into(),
2701 XattrOp::Set,
2702 )
2703 .expect("set_xattr(security.selinux) failed");
2704
2705 assert_eq!(Some(expected_sid), selinux_hooks::get_cached_sid(node));
2708 },
2709 )
2710 .await;
2711 }
2712
2713 #[fuchsia::test]
2714 async fn fs_node_setsecurity_not_selinux_only_sets_xattr() {
2715 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2716 |locked, current_task, security_server| {
2717 let valid_security_context_sid = security_server
2718 .security_context_to_sid(VALID_SECURITY_CONTEXT.into())
2719 .expect("no SID for VALID_SECURITY_CONTEXT");
2720 let node = &testing::create_test_file(locked, current_task).entry.node;
2721 let whatever_sid = selinux_hooks::get_cached_sid(node);
2725 assert_ne!(Some(valid_security_context_sid), whatever_sid);
2726
2727 fs_node_setsecurity(
2728 locked,
2729 current_task,
2730 &node,
2731 "security.selinu!".into(), VALID_SECURITY_CONTEXT.into(),
2733 XattrOp::Set,
2734 )
2735 .expect("set_xattr(security.selinux) failed");
2736
2737 assert_eq!(whatever_sid, selinux_hooks::get_cached_sid(node));
2739 },
2740 )
2741 .await;
2742 }
2743
2744 #[fuchsia::test]
2745 async fn fs_node_setsecurity_selinux_enforcing_invalid_context_fails() {
2746 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2747 |locked, current_task, _security_server| {
2748 let node = &testing::create_test_file(locked, current_task).entry.node;
2749
2750 let before_sid = selinux_hooks::get_cached_sid(node);
2751 assert_ne!(Some(InitialSid::Unlabeled.into()), before_sid);
2752
2753 assert!(
2754 check_fs_node_setxattr_access(
2755 ¤t_task,
2756 &node,
2757 XATTR_NAME_SELINUX.to_bytes().into(),
2758 "!".into(), XattrOp::Set,
2760 )
2761 .is_err()
2762 );
2763
2764 assert_eq!(before_sid, selinux_hooks::get_cached_sid(node));
2765 },
2766 )
2767 .await;
2768 }
2769
2770 #[fuchsia::test]
2771 async fn fs_node_setsecurity_selinux_permissive_invalid_context_sets_xattr_and_label() {
2772 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2773 |locked, current_task, security_server| {
2774 security_server.set_enforcing(false);
2775 let node = &testing::create_test_file(locked, current_task).entry.node;
2776
2777 assert_ne!(Some(InitialSid::Unlabeled.into()), selinux_hooks::get_cached_sid(node));
2778
2779 fs_node_setsecurity(
2780 locked,
2781 current_task,
2782 &node,
2783 XATTR_NAME_SELINUX.to_bytes().into(),
2784 "!".into(), XattrOp::Set,
2786 )
2787 .expect("set_xattr(security.selinux) failed");
2788
2789 assert_eq!(Some(InitialSid::Unlabeled.into()), selinux_hooks::get_cached_sid(node));
2790 },
2791 )
2792 .await;
2793 }
2794
2795 #[fuchsia::test]
2796 async fn fs_node_setsecurity_different_sid_for_different_context() {
2797 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2798 |locked, current_task, _security_server| {
2799 let node = &testing::create_test_file(locked, current_task).entry.node;
2800
2801 fs_node_setsecurity(
2802 locked,
2803 current_task,
2804 &node,
2805 XATTR_NAME_SELINUX.to_bytes().into(),
2806 VALID_SECURITY_CONTEXT.into(),
2807 XattrOp::Set,
2808 )
2809 .expect("set_xattr(security.selinux) failed");
2810
2811 assert!(selinux_hooks::get_cached_sid(node).is_some());
2812
2813 let first_sid = selinux_hooks::get_cached_sid(node).unwrap();
2814 fs_node_setsecurity(
2815 locked,
2816 current_task,
2817 &node,
2818 XATTR_NAME_SELINUX.to_bytes().into(),
2819 DIFFERENT_VALID_SECURITY_CONTEXT.into(),
2820 XattrOp::Set,
2821 )
2822 .expect("set_xattr(security.selinux) failed");
2823
2824 assert!(selinux_hooks::get_cached_sid(node).is_some());
2825
2826 let second_sid = selinux_hooks::get_cached_sid(node).unwrap();
2827
2828 assert_ne!(first_sid, second_sid);
2829 },
2830 )
2831 .await;
2832 }
2833
2834 #[fuchsia::test]
2835 async fn fs_node_getsecurity_returns_cached_context() {
2836 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2837 |locked, current_task, security_server| {
2838 let node = &testing::create_test_file(locked, current_task).entry.node;
2839
2840 const TEST_VALUE: &str = "Something Random";
2842 node.ops()
2843 .set_xattr(
2844 locked.cast_locked::<FileOpsCore>(),
2845 node,
2846 current_task,
2847 XATTR_NAME_SELINUX.to_bytes().into(),
2848 TEST_VALUE.into(),
2849 XattrOp::Set,
2850 )
2851 .expect("set_xattr(security.selinux) failed");
2852
2853 let sid = security_server
2855 .security_context_to_sid(VALID_SECURITY_CONTEXT.into())
2856 .expect("security context to SID");
2857 selinux_hooks::set_cached_sid(&node, sid);
2858
2859 let result = fs_node_getsecurity(
2861 locked,
2862 current_task,
2863 node,
2864 XATTR_NAME_SELINUX.to_bytes().into(),
2865 4096,
2866 );
2867 assert_eq!(
2868 result,
2869 Ok(ValueOrSize::Value(FsString::new(VALID_SECURITY_CONTEXT_WITH_NUL.into())))
2870 );
2871 },
2872 )
2873 .await;
2874 }
2875
2876 #[fuchsia::test]
2877 async fn fs_node_getsecurity_delegates_to_get_xattr() {
2878 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2879 |locked, current_task, security_server| {
2880 let node = &testing::create_test_file(locked, current_task).entry.node;
2881
2882 security_server.set_enforcing(false);
2885 const TEST_VALUE: &str = "Something Random";
2886 fs_node_setsecurity(
2887 locked,
2888 current_task,
2889 node,
2890 XATTR_NAME_SELINUX.to_bytes().into(),
2891 TEST_VALUE.into(),
2892 XattrOp::Set,
2893 )
2894 .expect("set_xattr(security.selinux) failed");
2895 security_server.set_enforcing(true);
2896
2897 let result = fs_node_getsecurity(
2899 locked,
2900 current_task,
2901 node,
2902 XATTR_NAME_SELINUX.to_bytes().into(),
2903 4096,
2904 );
2905 assert_eq!(result, Ok(ValueOrSize::Value(FsString::new(TEST_VALUE.into()))));
2906 },
2907 )
2908 .await;
2909 }
2910
2911 #[fuchsia::test]
2912 async fn set_get_procattr() {
2913 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2914 |_locked, current_task, _security_server| {
2915 assert_eq!(
2916 get_procattr(current_task, current_task, ProcAttr::Exec),
2917 Ok(Vec::new())
2918 );
2919
2920 assert_eq!(
2921 set_procattr(current_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
2923 Ok(())
2924 );
2925
2926 assert_eq!(
2927 set_procattr(
2929 current_task,
2930 ProcAttr::SockCreate,
2931 DIFFERENT_VALID_SECURITY_CONTEXT.into()
2932 ),
2933 error!(EACCES)
2934 );
2935
2936 assert_eq!(
2937 set_procattr(
2939 current_task,
2940 ProcAttr::Previous,
2941 DIFFERENT_VALID_SECURITY_CONTEXT.into()
2942 ),
2943 error!(EINVAL)
2944 );
2945
2946 assert_eq!(
2947 set_procattr(current_task, ProcAttr::Exec, INVALID_SECURITY_CONTEXT.into()),
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!(get_procattr(current_task, current_task, ProcAttr::Current).is_ok());
2958 },
2959 )
2960 .await;
2961 }
2962
2963 #[fuchsia::test]
2964 async fn set_get_procattr_with_nulls() {
2965 spawn_kernel_with_selinux_hooks_test_policy_and_run(
2966 |_locked, current_task, _security_server| {
2967 assert_eq!(
2968 get_procattr(current_task, current_task, ProcAttr::Exec),
2969 Ok(Vec::new())
2970 );
2971
2972 assert_eq!(
2973 set_procattr(
2975 current_task,
2976 ProcAttr::Exec,
2977 VALID_SECURITY_CONTEXT_WITH_NUL.into()
2978 ),
2979 Ok(())
2980 );
2981
2982 assert_eq!(
2983 set_procattr(
2985 current_task,
2986 ProcAttr::FsCreate,
2987 INVALID_SECURITY_CONTEXT_INTERNAL_NUL.into()
2988 ),
2989 error!(EINVAL)
2990 );
2991
2992 assert_eq!(
2993 get_procattr(current_task, current_task, ProcAttr::Exec),
2994 Ok(VALID_SECURITY_CONTEXT_WITH_NUL.into())
2995 );
2996
2997 assert_eq!(
2998 get_procattr(current_task, current_task, ProcAttr::FsCreate),
2999 Ok(Vec::new())
3000 );
3001 },
3002 )
3003 .await;
3004 }
3005
3006 #[fuchsia::test]
3007 async fn set_get_procattr_clear_context() {
3008 spawn_kernel_with_selinux_hooks_test_policy_and_run(
3009 |_locked, current_task, _security_server| {
3010 assert_eq!(
3012 set_procattr(current_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
3013 Ok(())
3014 );
3015 assert_eq!(
3016 set_procattr(
3017 current_task,
3018 ProcAttr::FsCreate,
3019 DIFFERENT_VALID_SECURITY_CONTEXT.into()
3020 ),
3021 Ok(())
3022 );
3023
3024 assert_eq!(set_procattr(current_task, ProcAttr::Exec, b"\0"), Ok(()));
3026 assert_eq!(current_task.current_creds().security_state.exec_sid, None);
3027
3028 assert_eq!(set_procattr(current_task, ProcAttr::FsCreate, b"\x0a"), Ok(()));
3030 assert_eq!(current_task.current_creds().security_state.fscreate_sid, None);
3031 },
3032 )
3033 .await;
3034 }
3035
3036 #[fuchsia::test]
3037 async fn set_get_procattr_setcurrent() {
3038 spawn_kernel_with_selinux_hooks_test_policy_and_run(
3039 |_locked, current_task, _security_server| {
3040 let initial_previous =
3042 get_procattr(current_task, current_task, ProcAttr::Previous).unwrap();
3043
3044 assert_eq!(
3045 set_procattr(current_task, ProcAttr::Current, VALID_SECURITY_CONTEXT.into()),
3047 Ok(())
3048 );
3049
3050 assert_eq!(
3051 get_procattr(current_task, current_task, ProcAttr::Current),
3053 Ok(VALID_SECURITY_CONTEXT_WITH_NUL.into())
3054 );
3055
3056 assert_eq!(
3057 get_procattr(current_task, current_task, ProcAttr::Previous),
3059 Ok(initial_previous.clone())
3060 );
3061
3062 assert_eq!(
3063 set_procattr(
3065 current_task,
3066 ProcAttr::Current,
3067 DIFFERENT_VALID_SECURITY_CONTEXT.into()
3068 ),
3069 Ok(())
3070 );
3071
3072 assert_eq!(
3073 get_procattr(current_task, current_task, ProcAttr::Current),
3075 Ok(DIFFERENT_VALID_SECURITY_CONTEXT_WITH_NUL.into())
3076 );
3077
3078 assert_eq!(
3079 get_procattr(current_task, current_task, ProcAttr::Previous),
3081 Ok(initial_previous.clone())
3082 );
3083 },
3084 )
3085 .await;
3086 }
3087
3088 #[fuchsia::test]
3089 async fn set_get_procattr_selinux_permissive() {
3090 spawn_kernel_with_selinux_hooks_test_policy_and_run(
3091 |_locked, current_task, security_server| {
3092 security_server.set_enforcing(false);
3093 assert_eq!(
3094 get_procattr(current_task, ¤t_task.task, ProcAttr::Exec),
3095 Ok(Vec::new())
3096 );
3097
3098 assert_eq!(
3099 set_procattr(current_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
3101 Ok(())
3102 );
3103
3104 assert_eq!(
3105 set_procattr(
3108 current_task,
3109 ProcAttr::FsCreate,
3110 DIFFERENT_VALID_SECURITY_CONTEXT.into()
3111 ),
3112 Ok(())
3113 );
3114
3115 assert_eq!(
3116 set_procattr(current_task, ProcAttr::Exec, INVALID_SECURITY_CONTEXT.into()),
3118 error!(EINVAL)
3119 );
3120
3121 assert_eq!(
3122 get_procattr(current_task, ¤t_task.task, ProcAttr::Exec),
3123 Ok(VALID_SECURITY_CONTEXT_WITH_NUL.into())
3124 );
3125
3126 assert!(get_procattr(current_task, ¤t_task.task, ProcAttr::Current).is_ok());
3127 },
3128 )
3129 .await;
3130 }
3131
3132 #[fuchsia::test]
3133 async fn set_get_procattr_selinux_disabled() {
3134 spawn_kernel_and_run(async |_, current_task| {
3135 assert_eq!(
3136 set_procattr(¤t_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
3137 error!(EINVAL)
3138 );
3139
3140 assert_eq!(
3141 set_procattr(¤t_task, ProcAttr::Exec, VALID_SECURITY_CONTEXT.into()),
3143 error!(EINVAL)
3144 );
3145
3146 assert_eq!(
3147 set_procattr(¤t_task, ProcAttr::FsCreate, VALID_SECURITY_CONTEXT.into()),
3149 error!(EINVAL)
3150 );
3151
3152 assert_eq!(
3153 set_procattr(¤t_task, ProcAttr::Exec, INVALID_SECURITY_CONTEXT.into()),
3155 error!(EINVAL)
3156 );
3157
3158 assert_eq!(
3159 get_procattr(¤t_task, ¤t_task.task, ProcAttr::Current),
3160 error!(EINVAL)
3161 );
3162 })
3163 .await;
3164 }
3165
3166 #[fuchsia::test]
3167 async fn create_file_with_fscreate_sid() {
3168 spawn_kernel_with_selinux_hooks_test_policy_and_run(
3169 |locked, current_task, security_server| {
3170 let sid =
3171 security_server.security_context_to_sid(VALID_SECURITY_CONTEXT.into()).unwrap();
3172 let source_node = &testing::create_test_file(locked, current_task).entry.node;
3173
3174 fs_node_setsecurity(
3175 locked,
3176 current_task,
3177 &source_node,
3178 XATTR_NAME_SELINUX.to_bytes().into(),
3179 VALID_SECURITY_CONTEXT.into(),
3180 XattrOp::Set,
3181 )
3182 .expect("set_xattr(security.selinux) failed");
3183
3184 let mut creds = Credentials::clone(¤t_task.current_creds());
3185 security::fs_node_copy_up(current_task, source_node, &source_node.fs(), &mut creds);
3186 let dir_entry = current_task
3187 .override_creds(creds.into(), || {
3188 current_task
3189 .fs()
3190 .root()
3191 .create_node(
3192 locked,
3193 ¤t_task,
3194 "test_file2".into(),
3195 FileMode::IFREG,
3196 DeviceId::NONE,
3197 )
3198 .unwrap()
3199 })
3200 .entry;
3201
3202 assert_eq!(get_cached_sid(&dir_entry.node), Some(sid));
3203 },
3204 )
3205 .await;
3206 }
3207}