Skip to main content

selinux/policy/
parser.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::fmt::Debug;
6use std::marker::PhantomData;
7use std::ops::Deref;
8use std::sync::Arc;
9
10use selinux_policy_derive::{Parse, Serialize, Validate};
11use zerocopy::{FromBytes, Immutable, KnownLayout, Unaligned, little_endian as le};
12
13use super::Policy;
14use super::error::{ParseError, SerializeError, ValidateError};
15use super::metadata::PolicyVersion;
16use super::traits::{Parse, Serialize, Validate};
17
18/// Raw binary policy data buffer.
19pub type PolicyData = Arc<[u8]>;
20
21/// Cursor used to parse elements from the binary policy data.
22#[derive(Debug)]
23pub struct PolicyCursor<'a> {
24    data: &'a [u8],
25    offset: usize,
26    policy_version: PolicyVersion,
27    types_count: u32,
28}
29
30impl<'a> PolicyCursor<'a> {
31    /// Creates a new [`PolicyCursor`] wrapping the supplied `data`.
32    pub fn new(data: &'a [u8]) -> Self {
33        Self { data, offset: 0, policy_version: PolicyVersion::V30, types_count: 0 }
34    }
35
36    /// Sets the SELinux policy database version on this cursor.
37    pub fn set_policy_version(&mut self, version: PolicyVersion) {
38        self.policy_version = version;
39    }
40
41    /// Returns the SELinux policy database version recorded on this cursor.
42    pub fn policy_version(&self) -> PolicyVersion {
43        self.policy_version
44    }
45
46    /// Sets the number of types recorded on this cursor.
47    pub fn set_types_count(&mut self, count: u32) {
48        self.types_count = count;
49    }
50
51    /// Returns the number of types recorded on this cursor.
52    pub fn types_count(&self) -> u32 {
53        self.types_count
54    }
55
56    /// Returns the current offset of the cursor.
57    pub fn offset(&self) -> usize {
58        self.offset
59    }
60
61    /// Returns the number of unconsumed bytes remaining in the cursor.
62    pub fn remaining(&self) -> usize {
63        self.data.len() - self.offset
64    }
65
66    /// Parses a type `T` that implements [`Parse`] from the cursor.
67    pub fn parse<T: Parse>(&mut self) -> Result<T, ParseError> {
68        T::parse(self)
69    }
70
71    /// Parses `count` contiguous elements of type `T` from the cursor.
72    pub(super) fn parse_elements<T: Parse>(
73        &mut self,
74        count: usize,
75    ) -> Result<Box<[T]>, ParseError> {
76        if count > self.remaining() {
77            return Err(ParseError::MissingData {
78                type_name: std::any::type_name::<T>(),
79                type_size: count,
80                num_bytes: self.remaining(),
81            });
82        }
83        let mut elements = Vec::with_capacity(count);
84        for _ in 0..count {
85            elements.push(self.parse()?);
86        }
87        Ok(elements.into_boxed_slice())
88    }
89
90    /// Reads a generic sized, zerocopyable type directly from the cursor.
91    fn read<T: FromBytes + KnownLayout + Immutable + Unaligned>(
92        &mut self,
93    ) -> Result<T, ParseError> {
94        let size = std::mem::size_of::<T>();
95        let bytes = self.read_bytes(size)?;
96        // Safe because T is FromBytes, Immutable, Unaligned and bytes is exactly `size` bytes.
97        let value = T::read_from_bytes(bytes).map_err(|_| ParseError::MissingData {
98            type_name: std::any::type_name::<T>(),
99            type_size: size,
100            num_bytes: bytes.len(),
101        })?;
102        Ok(value)
103    }
104
105    /// Reads a byte slice of `count` bytes from the cursor.
106    pub fn read_bytes(&mut self, count: usize) -> Result<&'a [u8], ParseError> {
107        if count > self.remaining() {
108            return Err(ParseError::MissingData {
109                type_name: "bytes",
110                type_size: count,
111                num_bytes: self.remaining(),
112            });
113        }
114        let bytes = &self.data[self.offset..self.offset + count];
115        self.offset += count;
116        Ok(bytes)
117    }
118}
119
120/// Writer used to serialize elements into a byte vector for a specific policy version.
121#[derive(Debug)]
122pub struct PolicyWriter<'a> {
123    version: PolicyVersion,
124    writer: &'a mut Vec<u8>,
125}
126
127impl<'a> PolicyWriter<'a> {
128    /// Creates a new [`PolicyWriter`] wrapping `writer` for the specified `version`.
129    pub fn new(version: PolicyVersion, writer: &'a mut Vec<u8>) -> Self {
130        Self { version, writer }
131    }
132
133    /// Returns target [`PolicyVersion`].
134    pub fn version(&self) -> PolicyVersion {
135        self.version
136    }
137
138    /// Appends raw bytes into destination writer.
139    pub fn write_bytes(&mut self, bytes: &[u8]) {
140        self.writer.extend_from_slice(bytes);
141    }
142}
143
144impl Parse for u8 {
145    fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
146        cursor.read::<u8>()
147    }
148}
149
150impl Serialize for u8 {
151    fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
152        writer.write_bytes(&[*self]);
153        Ok(())
154    }
155}
156
157impl Validate for u8 {
158    fn validate(&self, _policy: &Policy) -> Result<(), ValidateError> {
159        Ok(())
160    }
161}
162
163impl Parse for u16 {
164    fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
165        let val: le::U16 = cursor.read::<le::U16>()?;
166        Ok(val.get())
167    }
168}
169
170impl Serialize for u16 {
171    fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
172        let val = le::U16::new(*self);
173        writer.write_bytes(zerocopy::IntoBytes::as_bytes(&val));
174        Ok(())
175    }
176}
177
178impl Validate for u16 {
179    fn validate(&self, _policy: &Policy) -> Result<(), ValidateError> {
180        Ok(())
181    }
182}
183
184impl Parse for u32 {
185    fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
186        let val: le::U32 = cursor.read::<le::U32>()?;
187        Ok(val.get())
188    }
189}
190
191impl Serialize for u32 {
192    fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
193        let val = le::U32::new(*self);
194        writer.write_bytes(zerocopy::IntoBytes::as_bytes(&val));
195        Ok(())
196    }
197}
198
199impl Validate for u32 {
200    fn validate(&self, _policy: &Policy) -> Result<(), ValidateError> {
201        Ok(())
202    }
203}
204
205/// Sequence of raw bytes prefixed by a `u32` byte count in the binary policy format.
206#[derive(Debug, Clone, PartialEq, Eq, Validate)]
207pub struct ByteArray {
208    data: Box<[u8]>,
209}
210
211impl Deref for ByteArray {
212    type Target = [u8];
213    fn deref(&self) -> &Self::Target {
214        &self.data
215    }
216}
217
218impl AsRef<[u8]> for ByteArray {
219    fn as_ref(&self) -> &[u8] {
220        &self.data
221    }
222}
223
224impl Parse for ByteArray {
225    fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
226        let count = u32::parse(cursor)? as usize;
227        let bytes = cursor.read_bytes(count)?;
228        Ok(Self { data: Box::from(bytes) })
229    }
230}
231
232impl Serialize for ByteArray {
233    fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
234        let count = self.data.len() as u32;
235        count.serialize(writer)?;
236        writer.write_bytes(&self.data);
237        Ok(())
238    }
239}
240
241impl Parse for u64 {
242    fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
243        let val: le::U64 = cursor.read::<le::U64>()?;
244        Ok(val.get())
245    }
246}
247
248impl Serialize for u64 {
249    fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
250        let val = le::U64::new(*self);
251        writer.write_bytes(zerocopy::IntoBytes::as_bytes(&val));
252        Ok(())
253    }
254}
255
256impl Validate for u64 {
257    fn validate(&self, _policy: &Policy) -> Result<(), ValidateError> {
258        Ok(())
259    }
260}
261
262impl<T: Parse, const N: usize> Parse for [T; N] {
263    fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
264        let mut items = Vec::with_capacity(N);
265        for _ in 0..N {
266            items.push(T::parse(cursor)?);
267        }
268        Ok(items.try_into().ok().expect("pushed N items"))
269    }
270}
271
272impl<T: Serialize, const N: usize> Serialize for [T; N] {
273    fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
274        for item in self {
275            item.serialize(writer)?;
276        }
277        Ok(())
278    }
279}
280
281impl<T: Validate, const N: usize> Validate for [T; N] {
282    fn validate(&self, policy: &Policy) -> Result<(), ValidateError> {
283        for item in self {
284            item.validate(policy)?;
285        }
286        Ok(())
287    }
288}
289
290impl<T: Serialize> Serialize for Box<[T]> {
291    fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
292        for item in self.iter() {
293            item.serialize(writer)?;
294        }
295        Ok(())
296    }
297}
298
299impl<T: Validate> Validate for Box<[T]> {
300    fn validate(&self, policy: &Policy) -> Result<(), ValidateError> {
301        for item in self.iter() {
302            item.validate(policy)?;
303        }
304        Ok(())
305    }
306}
307
308impl<T> Parse for PhantomData<T> {
309    fn parse(_cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
310        Ok(Self)
311    }
312}
313
314impl<T> Serialize for PhantomData<T> {
315    fn serialize(&self, _writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
316        Ok(())
317    }
318}
319
320impl<T> Validate for PhantomData<T> {
321    fn validate(&self, _policy: &Policy) -> Result<(), ValidateError> {
322        Ok(())
323    }
324}
325
326/// Standard policy array container, storing elements in a heap-allocated slice.
327/// Prefixed by a 32-bit count field in the binary policy format.
328#[derive(Debug, Clone, PartialEq, Eq, Hash, Validate)]
329pub struct Array<T> {
330    elements: Box<[T]>,
331}
332
333impl<T> Default for Array<T> {
334    fn default() -> Self {
335        Self { elements: Box::new([]) }
336    }
337}
338
339impl<T> From<Vec<T>> for Array<T> {
340    fn from(v: Vec<T>) -> Self {
341        Self { elements: v.into_boxed_slice() }
342    }
343}
344
345impl<T> Deref for Array<T> {
346    type Target = [T];
347    fn deref(&self) -> &Self::Target {
348        &self.elements
349    }
350}
351
352#[cfg(test)]
353impl<T> std::ops::DerefMut for Array<T> {
354    fn deref_mut(&mut self) -> &mut Self::Target {
355        &mut self.elements
356    }
357}
358
359impl<T> AsRef<[T]> for Array<T> {
360    fn as_ref(&self) -> &[T] {
361        &self.elements
362    }
363}
364
365impl<T: Parse> Parse for Array<T> {
366    fn parse(cursor: &mut PolicyCursor<'_>) -> Result<Self, ParseError> {
367        let count = u32::parse(cursor)? as usize;
368        let elements = cursor.parse_elements(count)?;
369        Ok(Self { elements })
370    }
371}
372
373impl<T: Serialize> Serialize for Array<T> {
374    fn serialize(&self, writer: &mut PolicyWriter<'_>) -> Result<(), SerializeError> {
375        let count = self.elements.len() as u32;
376        count.serialize(writer)?;
377        self.elements.serialize(writer)
378    }
379}
380
381/// Symbol list header and associated array of items.
382///
383/// In the SELinux binary policy database, each symbol table is prefixed by a header
384/// containing a `primary_names_count` field, followed by the array of items (which itself
385/// is prefixed by an `items_count` field).
386#[derive(Debug, Parse, Serialize)]
387pub struct SymbolArray<T> {
388    /// Number of primary names in this array (excluding aliases).
389    /// Included in the policy to allow allocation of index structures to be optimized.
390    primary_names_count: u32,
391    items: Array<T>,
392}
393
394impl<T> AsRef<[T]> for SymbolArray<T> {
395    fn as_ref(&self) -> &[T] {
396        &self.items
397    }
398}
399
400#[cfg(test)]
401impl<T> SymbolArray<T> {
402    pub fn as_mut_slice(&mut self) -> &mut [T] {
403        &mut self.items
404    }
405}
406
407impl<T: Validate> Validate for SymbolArray<T> {
408    fn validate(&self, policy: &Policy) -> Result<(), ValidateError> {
409        self.items.validate(policy)?;
410        if self.primary_names_count > self.items.len() as u32 {
411            return Err(ValidateError::InvalidPrimaryNamesCount {
412                expected_at_most: self.items.len() as u32,
413                found: self.primary_names_count,
414            });
415        }
416        Ok(())
417    }
418}
419
420#[cfg(test)]
421mod tests {
422    use super::*;
423    use crate::policy::metadata::PolicyVersion;
424
425    #[test]
426    fn test_policy_cursor_parse_u32() {
427        let data = [1, 0, 0, 0, 2, 0, 0, 0];
428        let mut cursor = PolicyCursor::new(&data);
429
430        let val1 = cursor.parse::<u32>().unwrap();
431        assert_eq!(val1, 1);
432        assert_eq!(cursor.offset, 4);
433
434        let val2 = cursor.parse::<u32>().unwrap();
435        assert_eq!(val2, 2);
436        assert_eq!(cursor.offset, 8);
437    }
438
439    #[test]
440    fn test_policy_cursor_parse_u64() {
441        let data = [1, 0, 0, 0, 0, 0, 0, 0];
442        let mut cursor = PolicyCursor::new(&data);
443        let val = cursor.parse::<u64>().unwrap();
444        assert_eq!(val, 1);
445        assert_eq!(cursor.offset, 8);
446    }
447
448    #[test]
449    fn test_policy_cursor_parse_elements() {
450        let data = [1, 0, 0, 0, 2, 0, 0, 0];
451        let mut cursor = PolicyCursor::new(&data);
452
453        let elements = cursor.parse_elements::<u32>(2).unwrap();
454        assert_eq!(elements.as_ref(), &[1, 2]);
455        assert_eq!(cursor.offset, 8);
456    }
457
458    #[test]
459    fn test_policy_cursor_missing_data_u32() {
460        let data = [1, 0];
461        let mut cursor = PolicyCursor::new(&data);
462
463        let err = cursor.parse::<u32>().unwrap_err();
464        assert!(matches!(
465            err,
466            ParseError::MissingData { type_name: "bytes", type_size: 4, num_bytes: 2 }
467        ));
468    }
469
470    #[test]
471    fn test_u32_serialize() {
472        let val = 42u32;
473        let mut writer = Vec::new();
474        let mut policy_writer = PolicyWriter::new(PolicyVersion::V33, &mut writer);
475        val.serialize(&mut policy_writer).unwrap();
476        assert_eq!(writer, [42, 0, 0, 0]);
477    }
478
479    #[test]
480    fn test_u64_serialize() {
481        let val = 42u64;
482        let mut writer = Vec::new();
483        let mut policy_writer = PolicyWriter::new(PolicyVersion::V33, &mut writer);
484        val.serialize(&mut policy_writer).unwrap();
485        assert_eq!(writer, [42, 0, 0, 0, 0, 0, 0, 0]);
486    }
487
488    #[test]
489    fn test_policy_cursor_byte_array() {
490        let data = [4, 0, 0, 0, 5, 6, 7, 8];
491        let mut cursor = PolicyCursor::new(&data);
492
493        let array = cursor.parse::<ByteArray>().unwrap();
494        assert_eq!(array.as_ref(), &[5, 6, 7, 8]);
495        assert_eq!(cursor.offset, 8);
496    }
497
498    #[test]
499    fn test_policy_cursor_byte_array_missing_data() {
500        let data = [5, 0, 0, 0, 6, 7, 8];
501        let mut cursor = PolicyCursor::new(&data);
502
503        let err = cursor.parse::<ByteArray>().unwrap_err();
504        assert!(matches!(
505            err,
506            ParseError::MissingData { type_name: "bytes", type_size: 5, num_bytes: 3 }
507        ));
508    }
509
510    #[test]
511    fn test_byte_array_serialize() {
512        let array = ByteArray { data: vec![5, 6, 7, 8].into_boxed_slice() };
513        let mut writer = Vec::new();
514        let mut policy_writer = PolicyWriter::new(PolicyVersion::V33, &mut writer);
515        array.serialize(&mut policy_writer).unwrap();
516        assert_eq!(writer, [4, 0, 0, 0, 5, 6, 7, 8]);
517    }
518
519    #[test]
520    fn test_array_parse_and_serialize() {
521        let data = [2, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0];
522        let mut cursor = PolicyCursor::new(&data);
523
524        let array = cursor.parse::<Array<u32>>().unwrap();
525        assert_eq!(array.as_ref(), &[10, 20]);
526        assert_eq!(cursor.offset, 12);
527
528        let mut writer = Vec::new();
529        let mut policy_writer = PolicyWriter::new(PolicyVersion::V33, &mut writer);
530        array.serialize(&mut policy_writer).unwrap();
531        assert_eq!(writer, data);
532    }
533
534    #[test]
535    fn test_symbol_array_parse_and_serialize() {
536        // primary_names_count = 5, array count = 2, elements = [10, 20]
537        let data = [5, 0, 0, 0, 2, 0, 0, 0, 10, 0, 0, 0, 20, 0, 0, 0];
538        let mut cursor = PolicyCursor::new(&data);
539
540        let sym_array = cursor.parse::<SymbolArray<u32>>().unwrap();
541        assert_eq!(sym_array.primary_names_count, 5);
542        assert_eq!(sym_array.as_ref(), &[10, 20]);
543        assert_eq!(cursor.offset, 16);
544
545        let mut writer = Vec::new();
546        let mut policy_writer = PolicyWriter::new(PolicyVersion::V33, &mut writer);
547        sym_array.serialize(&mut policy_writer).unwrap();
548        assert_eq!(writer, data);
549    }
550}