selinux/policy/
metadata.rs1use selinux_policy_derive::{Parse, Serialize, Validate};
6
7use super::error::{ParseError, SerializeError, ValidateError};
8use super::parser::{ByteArray, PolicyCursor, PolicyWriter};
9use super::traits::{Parse, Serialize, Validate};
10
11pub const SELINUX_MAGIC: u32 = 0xf97cff8c;
13
14pub const POLICYDB_SIGNATURE: &[u8] = b"SE Linux";
16
17pub const POLICYDB_VERSION_MIN: u32 = 30;
19
20pub const POLICYDB_VERSION_MAX: u32 = 33;
22
23pub const CONFIG_MLS_FLAG: u32 = 1;
25
26const CONFIG_HANDLE_UNKNOWN_REJECT_FLAG: u32 = 1 << 1;
28
29const CONFIG_HANDLE_UNKNOWN_ALLOW_FLAG: u32 = 1 << 2;
31
32const CONFIG_HANDLE_UNKNOWN_MASK: u32 =
34 CONFIG_HANDLE_UNKNOWN_REJECT_FLAG | CONFIG_HANDLE_UNKNOWN_ALLOW_FLAG;
35
36#[derive(Clone, Copy, Debug, PartialEq, Eq)]
38pub enum HandleUnknown {
39 Deny,
40 Reject,
41 Allow,
42}
43
44#[derive(Debug, Parse, Serialize)]
46pub struct Magic {
47 value: u32,
48}
49
50impl Validate for Magic {
51 fn validate(&self, _policy: &super::Policy) -> Result<(), ValidateError> {
52 if self.value != SELINUX_MAGIC {
53 return Err(ValidateError::InvalidMagic { found_magic: self.value });
54 }
55 Ok(())
56 }
57}
58
59#[derive(Debug, Parse, Serialize)]
61pub struct Signature {
62 value: ByteArray,
63}
64
65impl Validate for Signature {
66 fn validate(&self, _policy: &super::Policy) -> Result<(), ValidateError> {
67 if self.value.as_ref() != POLICYDB_SIGNATURE {
68 return Err(ValidateError::InvalidSignature {
69 found_signature: self.value.as_ref().into(),
70 });
71 }
72 Ok(())
73 }
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
78pub struct PolicyVersion {
79 value: u32,
80}
81
82impl Parse for PolicyVersion {
83 fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
84 let value = u32::parse(cursor)?;
85 let version = Self { value };
86 cursor.set_policy_version(version);
87 Ok(version)
88 }
89}
90
91impl PolicyVersion {
92 pub const V30: Self = Self { value: 30 };
93 pub const V33: Self = Self { value: 33 };
94
95 pub const MIN_INFINIBAND: Self = Self { value: 31 };
97
98 #[cfg(test)]
100 pub fn get(&self) -> u32 {
101 self.value
102 }
103}
104
105impl Validate for PolicyVersion {
106 fn validate(&self, _policy: &super::Policy) -> Result<(), ValidateError> {
107 let version = self.value;
108 if version < POLICYDB_VERSION_MIN || version > POLICYDB_VERSION_MAX {
109 return Err(ValidateError::InvalidPolicyVersion { found_policy_version: version });
110 }
111 Ok(())
112 }
113}
114
115#[derive(Debug)]
117pub struct Config {
118 handle_unknown: HandleUnknown,
119 raw_flags: u32,
120}
121
122impl Config {
123 pub fn handle_unknown(&self) -> HandleUnknown {
125 self.handle_unknown
126 }
127}
128
129impl Parse for Config {
130 fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
131 let flags = u32::parse(cursor)?;
132
133 let mls_enabled = (flags & CONFIG_MLS_FLAG) != 0;
135 if !mls_enabled {
136 return Err(ParseError::ConfigMissingMlsFlag { found_config: flags });
137 }
138
139 let masked_bits = flags & CONFIG_HANDLE_UNKNOWN_MASK;
141 let handle_unknown = match masked_bits {
142 CONFIG_HANDLE_UNKNOWN_REJECT_FLAG => HandleUnknown::Reject,
143 CONFIG_HANDLE_UNKNOWN_ALLOW_FLAG => HandleUnknown::Allow,
144 0 => HandleUnknown::Deny,
145 _ => return Err(ParseError::InvalidConfigFlags { flags }),
146 };
147
148 let raw_flags = flags & !CONFIG_HANDLE_UNKNOWN_MASK;
150
151 Ok(Self { handle_unknown, raw_flags })
152 }
153}
154
155impl Serialize for Config {
156 fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
157 let mut flags = self.raw_flags;
158 match self.handle_unknown {
159 HandleUnknown::Reject => flags |= CONFIG_HANDLE_UNKNOWN_REJECT_FLAG,
160 HandleUnknown::Allow => flags |= CONFIG_HANDLE_UNKNOWN_ALLOW_FLAG,
161 HandleUnknown::Deny => {}
162 }
163 flags.serialize(writer)
164 }
165}
166
167impl Validate for Config {
168 fn validate(&self, _policy: &super::Policy) -> Result<(), ValidateError> {
169 Ok(())
170 }
171}
172
173#[derive(Debug, Parse, Serialize, Validate)]
175pub struct Counts {
176 symbols_count: u32,
178 object_context_count: u32,
180}