twizzler_security/sec_ctx/
base.rs

1use core::fmt::Display;
2
3use heapless::{FnvIndexMap, Vec};
4use twizzler_abi::object::{ObjID, Protections, NULLPAGE_SIZE};
5
6use crate::{Cap, Del};
7
8/// completely arbitrary amount of mask entries in a security context
9pub const MASKS_MAX: usize = 16;
10/// completely arbitrary amount of capabilites and delegations in a security context
11pub const SEC_CTX_MAP_LEN: usize = 16;
12/// arbitrary number of map items per target object
13pub const MAP_ITEMS_PER_OBJ: usize = 16;
14
15#[derive(Debug)]
16pub struct Mask {
17    /// object whose permissions will be masked.
18    pub target: ObjID,
19    /// Specifies a mask on the permissions granted by capabilties and delegations in this security
20    /// context.
21    pub permmask: Protections,
22    /// an override mask on the context's global mask.
23    pub ovrmask: Protections,
24    // not sure what these flags are for?
25    // flags: BitField
26}
27
28impl Mask {
29    pub fn new(target: ObjID, permmask: Protections, ovrmask: Protections) -> Self {
30        Mask {
31            target,
32            permmask,
33            ovrmask,
34        }
35    }
36}
37
38#[derive(Clone, Copy, Debug, Default)]
39pub enum CtxMapItemType {
40    #[default]
41    Cap,
42    Del,
43}
44
45#[derive(Clone, Copy, Debug, Default)]
46pub struct CtxMapItem {
47    /// Type of the Map Item
48    pub item_type: CtxMapItemType,
49    /// The offset into the object
50    pub offset: usize,
51}
52
53bitflags::bitflags! {
54    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
55    pub struct SecCtxFlags: u16 {
56        // a security context should have an undetachable bit,
57        const UNDETACHABLE = 1;
58    }
59}
60
61/// The base of a Security Context, holding a map to the capabilities and delegations stored inside,
62/// masks on targets
63#[derive(Debug)]
64pub struct SecCtxBase {
65    /// A map that holds the mapping from an ObjID to the capabilities and delegations stored
66    /// inside this context that apply to that target ObjID.
67    pub map: FnvIndexMap<ObjID, Vec<CtxMapItem, MAP_ITEMS_PER_OBJ>, SEC_CTX_MAP_LEN>,
68    /// A map holding masks that apply for a target ObjID.
69    pub masks: FnvIndexMap<ObjID, Mask, MASKS_MAX>,
70    /// The global mask that applies to all protections gratned by this Security Context.
71    pub global_mask: Protections,
72    /// The running offset into the object where a new entry can be inserted.
73    pub offset: usize,
74    /// Flags specific to this security context.
75    pub flags: SecCtxFlags,
76}
77
78pub const OBJECT_ROOT_OFFSET: usize = size_of::<SecCtxBase>() + NULLPAGE_SIZE;
79
80pub enum InsertType {
81    Cap(Cap),
82    Del(Del),
83}
84
85impl SecCtxBase {
86    pub fn new(global_mask: Protections, flags: SecCtxFlags) -> Self {
87        Self {
88            map: FnvIndexMap::<ObjID, Vec<CtxMapItem, MAP_ITEMS_PER_OBJ>, SEC_CTX_MAP_LEN>::new(),
89            masks: FnvIndexMap::<ObjID, Mask, MASKS_MAX>::new(),
90            global_mask,
91            offset: 0,
92            flags,
93        }
94    }
95}
96
97#[cfg(feature = "user")]
98use twizzler::marker::BaseType;
99
100#[cfg(feature = "user")]
101impl BaseType for SecCtxBase {
102    //NOTE: unsure if this is what the fingerprint "should" be, just chose a random number.
103    fn fingerprint() -> u64 {
104        16
105    }
106}
107
108impl Display for CtxMapItem {
109    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
110        write!(f, "Item Type: {:?}\n", self.item_type)?;
111        write!(f, "Offset: {:#X}\n", self.offset)?;
112        Ok(())
113    }
114}
115
116impl Default for SecCtxBase {
117    fn default() -> Self {
118        Self::new(Protections::all(), SecCtxFlags::empty())
119    }
120}