1use fuchsia_rcu::RcuDroppable;
6use std::num::NonZeroU32;
7use zerocopy::{Immutable, IntoBytes};
8
9#[derive(
11 Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, IntoBytes, Immutable, RcuDroppable,
12)]
13pub struct SecurityId(pub NonZeroU32);
14
15#[repr(u64)]
19pub enum ReferenceInitialSid {
20 Kernel = 1,
21 Security = 2,
22 Unlabeled = 3,
23 _Fs = 4,
24 File = 5,
25 Init = 7,
26 _Port = 9,
27 _Netif = 10,
28 _Netmsg = 11,
29 _Node = 12,
30 _Sysctl = 17,
31 Devnull = 27,
32
33 FirstUnused,
36}
37
38#[macro_export]
39macro_rules! initial_sid_enum {
40 ($(#[$meta:meta])* $name:ident {
41 $($(#[$variant_meta:meta])* $variant:ident ($variant_name: literal)),*,
42 }) => {
43 $(#[$meta])*
44 pub enum $name {
45 $($(#[$variant_meta])* $variant = ReferenceInitialSid::$variant as isize),*
46 }
47
48 impl $name {
49 pub fn all_variants() -> &'static [Self] {
50 &[
51 $($name::$variant),*
52 ]
53 }
54
55 pub fn name(&self) -> &'static str {
56 match self {
57 $($name::$variant => $variant_name),*
58 }
59 }
60 }
61 }
62}
63
64initial_sid_enum! {
65#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
68 InitialSid {
69 Devnull("devnull"),
71 File("file"),
72 Init("init"),
73 Kernel("kernel"),
74 Security("security"),
75 Unlabeled("unlabeled"),
76 }
78}
79
80impl From<InitialSid> for SecurityId {
81 fn from(initial_sid: InitialSid) -> Self {
82 Self(NonZeroU32::new(initial_sid as u32).unwrap())
86 }
87}
88
89#[derive(Clone, Debug, PartialEq, RcuDroppable)]
91pub struct TaskAttrs {
92 pub current_sid: SecurityId,
94
95 pub exec_sid: Option<SecurityId>,
97
98 pub fscreate_sid: Option<SecurityId>,
100
101 pub keycreate_sid: Option<SecurityId>,
103
104 pub previous_sid: SecurityId,
106
107 pub sockcreate_sid: Option<SecurityId>,
109
110 pub internal_operation: bool,
113}
114
115impl TaskAttrs {
116 pub fn for_kernel() -> Self {
118 Self::for_transition(InitialSid::Kernel.into(), InitialSid::Kernel.into())
119 }
120
121 pub fn for_selinux_disabled() -> Self {
123 Self::for_transition(InitialSid::Unlabeled.into(), InitialSid::Unlabeled.into())
124 }
125
126 pub fn for_transition(new_sid: SecurityId, previous_sid: SecurityId) -> Self {
128 Self {
129 current_sid: new_sid,
130 previous_sid,
131 exec_sid: None,
132 fscreate_sid: None,
133 keycreate_sid: None,
134 sockcreate_sid: None,
135 internal_operation: false,
136 }
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143
144 #[test]
145 fn task_alloc_for_kernel() {
146 let for_kernel = TaskAttrs::for_kernel();
147 assert_eq!(for_kernel.current_sid, InitialSid::Kernel.into());
148 assert_eq!(for_kernel.previous_sid, for_kernel.current_sid);
149 assert_eq!(for_kernel.exec_sid, None);
150 assert_eq!(for_kernel.fscreate_sid, None);
151 assert_eq!(for_kernel.keycreate_sid, None);
152 assert_eq!(for_kernel.sockcreate_sid, None);
153 }
154}