Skip to main content

selinux/kernel/
mod.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
5//! Starnix kernel object class and permission definitions, policy-to-kernel index, and access
6//! vector cache (AVC).
7
8mod avc;
9mod index;
10mod permissions;
11
12pub use avc::{
13    AccessCacheStorage, AccessQueryArgs, CacheStats, ConcurrentAccessCache, DEFAULT_SHARED_SIZE,
14    PerThreadCache, QueryCacheCapacity,
15};
16pub(crate) use avc::{AccessVectorCache, Query};
17pub(crate) use index::PolicyIndex;
18pub use permissions::*;
19
20use crate::policy::{AccessDecision, AccessVector, ClassId, XpermsBitmap};
21use std::num::NonZeroU32;
22
23/// Identifies a specific class by its policy-defined Id, or as a kernel object class enum Id.
24#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
25pub enum ObjectClass {
26    /// Refers to a well-known SELinux [`KernelClass`] (e.g. "process", "file", "capability").
27    Kernel(KernelClass),
28    /// Refers to a policy-defined class by its policy-defined numeric [`ClassId`]. This is most
29    /// commonly used when handling queries from userspace, which refer to classes by ID.
30    ClassId(ClassId),
31}
32
33impl From<ClassId> for ObjectClass {
34    fn from(id: ClassId) -> Self {
35        Self::ClassId(id)
36    }
37}
38
39impl<T: Into<KernelClass>> From<T> for ObjectClass {
40    fn from(class: T) -> Self {
41        Self::Kernel(class.into())
42    }
43}
44
45/// Access decision translated into kernel permission bit positions for a [`KernelClass`].
46#[derive(Clone, Copy, Debug, PartialEq, Eq)]
47pub struct KernelAccessDecision {
48    pub allow: AccessVector,
49    pub audit: AccessVector,
50    pub flags: u32,
51    pub todo_bug: Option<NonZeroU32>,
52}
53
54/// Extended permission access decision as seen from the kernel.
55#[derive(Clone, Copy, PartialEq, Debug)]
56pub(crate) struct KernelXpermsAccessDecision {
57    /// Set of xperms that are allowed.
58    pub allow: XpermsBitmap,
59    /// Set of xperms that should be audited (as allowed or denials depending on `allow`).
60    pub audit: XpermsBitmap,
61    /// Whether the domain is permissive.
62    pub permissive: bool,
63    /// Whether the entry has an associated todo.
64    pub has_todo: bool,
65}
66
67/// Owner of policy information that can translate [`KernelPermission`] values into
68/// [`AccessVector`] values that are consistent with the owned policy.
69pub(crate) trait AccessVectorComputer {
70    /// Translates the given [`AccessDecision`] to a [`KernelAccessDecision`].
71    ///
72    /// The loaded policy's "handle unknown" configuration determines how `permissions`
73    /// entries not explicitly defined by the policy are handled. Allow-unknown will
74    /// result in unknown `permissions` being allowed, while they are denied (and audited)
75    /// if the policy uses deny-unknown.
76    fn access_decision_to_kernel_access_decision(
77        &self,
78        class: KernelClass,
79        access_decision: AccessDecision,
80    ) -> KernelAccessDecision;
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn object_class_permissions() {
89        let test_class_id = ClassId::for_test(20);
90        assert_eq!(ObjectClass::ClassId(test_class_id), test_class_id.into());
91        for variant in ProcessPermission::PERMISSIONS {
92            assert_eq!(KernelClass::Process, variant.class());
93            assert_eq!("process", variant.class().name());
94            assert_eq!(ObjectClass::Kernel(KernelClass::Process), variant.class().into());
95        }
96    }
97}