starnix_core/security/
non_private.rs1use super::{Auditable, common_cap, selinux_hooks};
6use crate::vfs::socket::{Socket, SocketFile, SocketHandle};
7use crate::vfs::{DirEntryHandle, DowncastedFile, FsNode};
8use std::ops::Deref;
9
10#[derive(Debug, Default)]
16pub struct FsNodeState {
17 selinux: selinux_hooks::FsNodeState,
18 common_cap: common_cap::FsNodeState,
19}
20
21impl FsNodeState {
22 #[cfg(test)]
23 pub(super) fn selinux_for_test(&self) -> &selinux_hooks::FsNodeState {
24 &self.selinux
25 }
26}
27
28#[derive(Clone, Copy, Debug)]
30pub(super) struct NonPrivateFsNode<'a> {
31 fs_node: &'a FsNode,
32}
33
34impl<'a> NonPrivateFsNode<'a> {
35 pub(super) fn new(fs_node: &'a FsNode) -> Option<Self> {
37 (!fs_node.is_private()).then_some(Self { fs_node })
38 }
39
40 pub(super) fn assert_from(fs_node: &'a FsNode) -> Option<Self> {
43 debug_assert!(!fs_node.is_private());
44 Self::new(fs_node)
45 }
46
47 pub(super) fn as_fs_node(self) -> &'a FsNode {
49 self.fs_node
50 }
51
52 pub(super) fn selinux_state(self) -> &'a selinux_hooks::FsNodeState {
54 &self.fs_node.security_state.selinux
55 }
56
57 pub(super) fn common_cap_state(self) -> &'a common_cap::FsNodeState {
59 &self.fs_node.security_state.common_cap
60 }
61}
62
63impl Deref for NonPrivateFsNode<'_> {
64 type Target = FsNode;
65
66 fn deref(&self) -> &Self::Target {
67 self.fs_node
68 }
69}
70
71impl<'a> From<NonPrivateFsNode<'a>> for Auditable<'a> {
72 fn from(value: NonPrivateFsNode<'a>) -> Self {
73 Auditable::FsNode(value.fs_node)
74 }
75}
76
77#[derive(Clone, Copy, Debug)]
80pub(super) struct NonPrivateDirEntry<'a> {
81 dir_entry: &'a DirEntryHandle,
82 fs_node: NonPrivateFsNode<'a>,
83}
84
85impl<'a> NonPrivateDirEntry<'a> {
86 pub(super) fn new(dir_entry: &'a DirEntryHandle) -> Option<Self> {
88 let fs_node = NonPrivateFsNode::new(&dir_entry.node)?;
89 Some(Self { dir_entry, fs_node })
90 }
91
92 pub(super) fn assert_from(dir_entry: &'a DirEntryHandle) -> Option<Self> {
95 let fs_node = NonPrivateFsNode::assert_from(&dir_entry.node)?;
96 Some(Self { dir_entry, fs_node })
97 }
98
99 pub(super) fn as_dir_entry(self) -> &'a DirEntryHandle {
101 self.dir_entry
102 }
103
104 pub(super) fn node(self) -> NonPrivateFsNode<'a> {
106 self.fs_node
107 }
108}
109
110impl Deref for NonPrivateDirEntry<'_> {
111 type Target = DirEntryHandle;
112
113 fn deref(&self) -> &Self::Target {
114 self.dir_entry
115 }
116}
117
118impl<'a> From<NonPrivateDirEntry<'a>> for Auditable<'a> {
119 fn from(value: NonPrivateDirEntry<'a>) -> Self {
120 value.dir_entry.into()
121 }
122}
123
124#[derive(Clone, Copy)]
126pub(super) struct NonPrivateSocket<'a> {
127 socket: &'a Socket,
128 fs_node: Option<NonPrivateFsNode<'a>>,
129}
130
131impl<'a> NonPrivateSocket<'a> {
132 pub(super) fn new(socket: &'a Socket) -> Option<Self> {
134 let fs_node = match socket.fs_node() {
135 Some(node) => Some(NonPrivateFsNode::new(node)?),
136 None => None,
137 };
138 Some(Self { socket, fs_node })
139 }
140
141 pub(super) fn fs_node(self) -> Option<NonPrivateFsNode<'a>> {
143 self.fs_node
144 }
145}
146
147impl Deref for NonPrivateSocket<'_> {
148 type Target = Socket;
149
150 fn deref(&self) -> &Self::Target {
151 self.socket
152 }
153}
154
155#[derive(Clone, Copy)]
158pub(super) struct NonPrivateSocketFile<'a> {
159 socket_file: DowncastedFile<'a, SocketFile>,
160 fs_node: NonPrivateFsNode<'a>,
161}
162
163impl<'a> NonPrivateSocketFile<'a> {
164 pub(super) fn new(socket_file: DowncastedFile<'a, SocketFile>) -> Option<Self> {
166 let fs_node = NonPrivateFsNode::new(socket_file.file().node())?;
167 Some(Self { socket_file, fs_node })
168 }
169
170 pub(super) fn assert_from(socket_file: DowncastedFile<'a, SocketFile>) -> Option<Self> {
174 let fs_node = NonPrivateFsNode::assert_from(socket_file.file().node())?;
175 Some(Self { socket_file, fs_node })
176 }
177
178 pub(super) fn socket(self) -> &'a SocketHandle {
180 self.socket_file.socket()
181 }
182
183 pub(super) fn node(self) -> NonPrivateFsNode<'a> {
185 self.fs_node
186 }
187}