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