selinux/new_policy/
metadata.rs1use selinux_policy_derive::{Parse, Serialize, Validate};
6
7use super::error::{ParseError, SerializeError, ValidateError};
8use super::parser::{ByteArray, PolicyCursor};
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, Clone, 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, Clone, 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 { found_signature: self.value.to_vec() });
76 }
77 Ok(())
78 }
79}
80
81#[derive(Debug, Clone, Parse, Serialize)]
83pub(super) struct PolicyVersion {
84 value: u32,
85}
86
87impl PolicyVersion {
88 pub(super) fn get(&self) -> u32 {
90 self.value
91 }
92}
93
94impl Validate for PolicyVersion {
95 fn validate(&self, _policy: &super::NewPolicy) -> Result<(), ValidateError> {
96 let version = self.value;
97 if version < POLICYDB_VERSION_MIN || version > POLICYDB_VERSION_MAX {
98 return Err(ValidateError::InvalidPolicyVersion { found_policy_version: version });
99 }
100 Ok(())
101 }
102}
103
104#[derive(Debug, Clone, PartialEq, Eq)]
106pub(super) struct Config {
107 handle_unknown: HandleUnknown,
108 raw_flags: u32,
109}
110
111impl Config {
112 pub(super) fn handle_unknown(&self) -> HandleUnknown {
114 self.handle_unknown
115 }
116}
117
118impl Parse for Config {
119 fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
120 let flags = u32::parse(cursor)?;
121
122 let mls_enabled = (flags & CONFIG_MLS_FLAG) != 0;
124 if !mls_enabled {
125 return Err(ParseError::ConfigMissingMlsFlag { found_config: flags });
126 }
127
128 let masked_bits = flags & CONFIG_HANDLE_UNKNOWN_MASK;
130 let handle_unknown = match masked_bits {
131 CONFIG_HANDLE_UNKNOWN_REJECT_FLAG => HandleUnknown::Reject,
132 CONFIG_HANDLE_UNKNOWN_ALLOW_FLAG => HandleUnknown::Allow,
133 0 => HandleUnknown::Deny,
134 _ => return Err(ParseError::InvalidConfigFlags { flags }),
135 };
136
137 let raw_flags = flags & !CONFIG_HANDLE_UNKNOWN_MASK;
139
140 Ok(Self { handle_unknown, raw_flags })
141 }
142}
143
144impl Serialize for Config {
145 fn serialize(&self, writer: &mut Vec<u8>) -> Result<(), SerializeError> {
146 let mut flags = self.raw_flags;
147 match self.handle_unknown {
148 HandleUnknown::Reject => flags |= CONFIG_HANDLE_UNKNOWN_REJECT_FLAG,
149 HandleUnknown::Allow => flags |= CONFIG_HANDLE_UNKNOWN_ALLOW_FLAG,
150 HandleUnknown::Deny => {}
151 }
152 flags.serialize(writer)
153 }
154}
155
156impl Validate for Config {
157 fn validate(&self, _policy: &super::NewPolicy) -> Result<(), ValidateError> {
158 Ok(())
159 }
160}
161
162#[derive(Debug, Clone, Parse, Serialize, Validate)]
165pub(super) struct Counts {
166 symbols_count: u32,
168 object_context_count: u32,
170}