selinux/new_policy/
mod.rs1pub(super) mod access_vector;
6pub(super) mod bitmap;
7pub(super) mod common_symbols;
8pub(super) mod error;
9pub(super) mod id_type;
10pub(super) mod indexed;
11pub(super) mod metadata;
12pub(super) mod parser;
13pub(super) mod permissions;
14pub(super) mod traits;
15
16use selinux_policy_derive::{Parse, Serialize, Validate};
17
18use error::{ParseError, ValidateError};
19use metadata::{Config, Counts, Magic, PolicyVersion, Signature};
20pub use metadata::{HandleUnknown, POLICYDB_VERSION_MAX};
21use parser::{PolicyCursor, RemainingBytes};
22use traits::Validate;
23
24pub(super) mod types;
25
26pub use access_vector::AccessVector;
27pub use bitmap::ExtensibleBitmap;
28pub use common_symbols::CommonSymbol;
29pub use id_type::IdType;
30pub use parser::SymbolArray;
31pub use permissions::PermissionId;
32pub use types::*;
33
34#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
36pub struct UserTag;
37
38pub type UserId = IdType<std::num::NonZeroU16, UserTag>;
40
41#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
43pub struct RoleTag;
44
45pub type RoleId = IdType<std::num::NonZeroU16, RoleTag>;
47
48#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
50pub struct ClassTag;
51
52pub type ClassId = IdType<std::num::NonZeroU16, ClassTag>;
54
55#[derive(Debug, Clone, Parse, Serialize, Validate)]
58pub struct NewPolicy {
59 magic: Magic,
60 signature: Signature,
61 version: PolicyVersion,
62 config: Config,
63 counts: Counts,
64 policy_capabilities: ExtensibleBitmap,
65 permissive_map: PermissiveTypeSet,
66 common_symbols: SymbolArray<CommonSymbol>,
67 rest: RemainingBytes,
68}
69
70impl NewPolicy {
71 pub fn parse(data: &[u8]) -> Result<Self, ParseError> {
73 let mut cursor = PolicyCursor::new(data);
74 cursor.parse()
75 }
76
77 pub fn validate(&self) -> Result<(), ValidateError> {
79 Validate::validate(self, self)
80 }
81
82 pub fn policy_version(&self) -> u32 {
84 self.version.get()
85 }
86
87 pub fn handle_unknown(&self) -> HandleUnknown {
89 self.config.handle_unknown()
90 }
91
92 pub fn policy_capabilities(&self) -> &ExtensibleBitmap {
94 &self.policy_capabilities
95 }
96
97 pub fn permissive_map(&self) -> &PermissiveTypeSet {
99 &self.permissive_map
100 }
101
102 pub fn common_symbols(&self) -> &SymbolArray<CommonSymbol> {
104 &self.common_symbols
105 }
106
107 pub fn rest_bytes(&self) -> std::sync::Arc<[u8]> {
109 self.rest.bytes.clone()
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116 use crate::new_policy::traits::{Parse, Serialize};
117
118 #[derive(Copy, Clone, Debug, Eq, PartialEq, Parse, Serialize, Validate)]
119 #[policy(wire_type = u32)]
120 enum TestEnum {
121 ValueOne = 1,
122 ValueTwo = 2,
123 }
124
125 #[test]
126 fn test_enum_derive() {
127 let mut cursor = PolicyCursor::new(&[1, 0, 0, 0]);
128 let parsed = TestEnum::parse(&mut cursor).unwrap();
129 assert_eq!(parsed, TestEnum::ValueOne);
130
131 let mut cursor = PolicyCursor::new(&[2, 0, 0, 0]);
132 let parsed = TestEnum::parse(&mut cursor).unwrap();
133 assert_eq!(parsed, TestEnum::ValueTwo);
134
135 let mut cursor = PolicyCursor::new(&[3, 0, 0, 0]);
136 let err = TestEnum::parse(&mut cursor).unwrap_err();
137 assert!(matches!(err, ParseError::InvalidEnumValue { enum_name: "TestEnum", value: 3 }));
138
139 let mut writer = Vec::new();
140 TestEnum::ValueOne.serialize(&mut writer).unwrap();
141 assert_eq!(writer, vec![1, 0, 0, 0]);
142
143 let mut writer = Vec::new();
144 TestEnum::ValueTwo.serialize(&mut writer).unwrap();
145 assert_eq!(writer, vec![2, 0, 0, 0]);
146
147 let policy_bytes = include_bytes!("../../testdata/policies/selinux_testsuite");
148 let policy = NewPolicy::parse(policy_bytes).unwrap();
149 TestEnum::ValueOne.validate(&policy).unwrap();
150 }
151
152 #[test]
153 fn test_real_policy_roundtrip() {
154 let policy_bytes = include_bytes!("../../testdata/policies/selinux_testsuite");
155 let new_policy = NewPolicy::parse(policy_bytes).unwrap();
156 new_policy.validate().unwrap();
157
158 assert!(new_policy.policy_version() >= 30);
160 assert_eq!(new_policy.handle_unknown(), HandleUnknown::Allow);
161
162 let _caps = new_policy.policy_capabilities();
166 let _permissive = new_policy.permissive_map();
167
168 assert!(!new_policy.common_symbols().is_empty());
170 let common = &new_policy.common_symbols()[0];
171 assert!(!common.name_bytes().is_empty());
172 assert!(!common.permissions().is_empty());
173
174 let mut serialized = Vec::new();
176 new_policy.serialize(&mut serialized).unwrap();
177 assert_eq!(serialized.len(), policy_bytes.len());
178 assert_eq!(serialized, policy_bytes);
179 }
180}