selinux/lib.rs
1// Copyright 2024 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
5pub mod permission_check;
6pub mod policy;
7pub mod security_server;
8
9pub use security_server::SecurityServer;
10
11mod access_vector_cache;
12mod exceptions_config;
13mod fifo_cache;
14mod sid_table;
15mod sync;
16
17use policy::arrays::FsUseType;
18
19use std::num::NonZeroU32;
20
21/// Numeric class Ids are provided to the userspace AVC surfaces (e.g. "create", "access", etc).
22pub use policy::ClassId;
23
24/// The Security ID (SID) used internally to refer to a security context.
25#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
26pub struct SecurityId(NonZeroU32);
27
28impl From<InitialSid> for SecurityId {
29 fn from(initial_sid: InitialSid) -> Self {
30 // Initial SIDs are used by the kernel as placeholder `SecurityId` values for objects
31 // created prior to the SELinux policy being loaded, and are resolved to the policy-defined
32 // Security Context when referenced after policy load.
33 Self(NonZeroU32::new(initial_sid as u32).unwrap())
34 }
35}
36
37/// Identifies a specific class by its policy-defined Id, or as a kernel object class enum Id.
38#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
39pub enum ObjectClass {
40 /// Refers to a well-known SELinux kernel object class (e.g. "process", "file", "capability").
41 Kernel(KernelClass),
42 /// Refers to a policy-defined class by its policy-defined numeric Id. This is most commonly
43 /// used when handling queries from userspace, which refer to classes by-Id.
44 ClassId(ClassId),
45}
46
47impl From<ClassId> for ObjectClass {
48 fn from(id: ClassId) -> Self {
49 Self::ClassId(id)
50 }
51}
52
53impl<T: Into<KernelClass>> From<T> for ObjectClass {
54 fn from(class: T) -> Self {
55 Self::Kernel(class.into())
56 }
57}
58
59/// Declares an `enum` and implements an `all_variants()` API for it.
60macro_rules! enumerable_enum {
61 ($(#[$meta:meta])* $name:ident $(extends $common_name:ident)? {
62 $($(#[$variant_meta:meta])* $variant:ident,)*
63 }) => {
64 $(#[$meta])*
65 pub enum $name {
66 $($(#[$variant_meta])* $variant,)*
67 $(Common($common_name),)?
68 }
69
70 impl $name {
71 pub fn all_variants() -> impl Iterator<Item=Self> {
72 let iter = [$($name::$variant),*].iter().map(Clone::clone);
73 $(let iter = iter.chain($common_name::all_variants().map($name::Common));)?
74 iter
75 }
76 }
77 }
78}
79
80enumerable_enum! {
81 /// A well-known class in SELinux policy that has a particular meaning in policy enforcement
82 /// hooks.
83 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
84 KernelClass {
85 // keep-sorted start
86 /// The SELinux "anon_inode" object class.
87 AnonFsNode,
88 /// The SELinux "binder" object class.
89 Binder,
90 /// The SELinux "blk_file" object class.
91 Block,
92 /// The SELinux "bpf" object class.
93 Bpf,
94 /// The SELinux "capability" object class.
95 Capability,
96 /// The SELinux "capability2" object class.
97 Capability2,
98 /// The SELinux "chr_file" object class.
99 Character,
100 /// The SELinux "dir" object class.
101 Dir,
102 /// The SELinux "fd" object class.
103 Fd,
104 /// The SELinux "fifo_file" object class.
105 Fifo,
106 /// The SELinux "file" object class.
107 File,
108 /// The SELinux "filesystem" object class.
109 FileSystem,
110 /// The SELinux "key_socket" object class.
111 KeySocket,
112 /// The SELinux "lnk_file" object class.
113 Link,
114 /// The SELinux "memfd_file" object class.
115 MemFdFile,
116 /// The SELinux "netlink_audit_socket" object class.
117 NetlinkAuditSocket,
118 /// The SELinux "netlink_connector_socket" object class.
119 NetlinkConnectorSocket,
120 /// The SELinux "netlink_crypto_socket" object class.
121 NetlinkCryptoSocket,
122 /// The SELinux "netlink_dnrt_socket" object class.
123 NetlinkDnrtSocket,
124 /// The SELinux "netlink_fib_lookup_socket" object class.
125 NetlinkFibLookupSocket,
126 /// The SELinux "netlink_firewall_socket" object class.
127 NetlinkFirewallSocket,
128 /// The SELinux "netlink_generic_socket" object class.
129 NetlinkGenericSocket,
130 /// The SELinux "netlink_ip6fw_socket" object class.
131 NetlinkIp6FwSocket,
132 /// The SELinux "netlink_iscsi_socket" object class.
133 NetlinkIscsiSocket,
134 /// The SELinux "netlink_kobject_uevent_socket" object class.
135 NetlinkKobjectUeventSocket,
136 /// The SELinux "netlink_netfilter_socket" object class.
137 NetlinkNetfilterSocket,
138 /// The SELinux "netlink_nflog_socket" object class.
139 NetlinkNflogSocket,
140 /// The SELinux "netlink_rdma_socket" object class.
141 NetlinkRdmaSocket,
142 /// The SELinux "netlink_route_socket" object class.
143 NetlinkRouteSocket,
144 /// The SELinux "netlink_scsitransport_socket" object class.
145 NetlinkScsitransportSocket,
146 /// The SELinux "netlink_selinux_socket" object class.
147 NetlinkSelinuxSocket,
148 /// The SELinux "netlink_socket" object class.
149 NetlinkSocket,
150 /// The SELinux "netlink_tcpdiag_socket" object class.
151 NetlinkTcpDiagSocket,
152 /// The SELinux "netlink_xfrm_socket" object class.
153 NetlinkXfrmSocket,
154 /// The SELinux "packet_socket" object class.
155 PacketSocket,
156 /// The SELinux "perf_event" object class.
157 PerfEvent,
158 /// The SELinux "process" object class.
159 Process,
160 /// The SELinux "process2" object class.
161 Process2,
162 /// The SELinux "qipcrtr_socket" object class.
163 QipcrtrSocket,
164 /// The SELinux "rawip_socket" object class.
165 RawIpSocket,
166 /// The SELinux "security" object class.
167 Security,
168 /// The SELinux "sock_file" object class.
169 SockFile,
170 /// The SELinux "socket" object class.
171 Socket,
172 /// The SELinux "system" object class.
173 System,
174 /// The SELinux "tcp_socket" object class.
175 TcpSocket,
176 /// The SELinux "tun_socket" object class.
177 TunSocket,
178 /// The SELinux "udp_socket" object class.
179 UdpSocket,
180 /// The SELinux "unix_dgram_socket" object class.
181 UnixDgramSocket,
182 /// The SELinux "unix_stream_socket" object class.
183 UnixStreamSocket,
184 /// The SELinux "vsock_socket" object class.
185 VSockSocket,
186 // keep-sorted end
187 }
188}
189
190impl KernelClass {
191 /// Returns the name used to refer to this object class in the SELinux binary policy.
192 pub fn name(&self) -> &'static str {
193 match self {
194 // keep-sorted start
195 Self::AnonFsNode => "anon_inode",
196 Self::Binder => "binder",
197 Self::Block => "blk_file",
198 Self::Bpf => "bpf",
199 Self::Capability => "capability",
200 Self::Capability2 => "capability2",
201 Self::Character => "chr_file",
202 Self::Dir => "dir",
203 Self::Fd => "fd",
204 Self::Fifo => "fifo_file",
205 Self::File => "file",
206 Self::FileSystem => "filesystem",
207 Self::KeySocket => "key_socket",
208 Self::Link => "lnk_file",
209 Self::MemFdFile => "memfd_file",
210 Self::NetlinkAuditSocket => "netlink_audit_socket",
211 Self::NetlinkConnectorSocket => "netlink_connector_socket",
212 Self::NetlinkCryptoSocket => "netlink_crypto_socket",
213 Self::NetlinkDnrtSocket => "netlink_dnrt_socket",
214 Self::NetlinkFibLookupSocket => "netlink_fib_lookup_socket",
215 Self::NetlinkFirewallSocket => "netlink_firewall_socket",
216 Self::NetlinkGenericSocket => "netlink_generic_socket",
217 Self::NetlinkIp6FwSocket => "netlink_ip6fw_socket",
218 Self::NetlinkIscsiSocket => "netlink_iscsi_socket",
219 Self::NetlinkKobjectUeventSocket => "netlink_kobject_uevent_socket",
220 Self::NetlinkNetfilterSocket => "netlink_netfilter_socket",
221 Self::NetlinkNflogSocket => "netlink_nflog_socket",
222 Self::NetlinkRdmaSocket => "netlink_rdma_socket",
223 Self::NetlinkRouteSocket => "netlink_route_socket",
224 Self::NetlinkScsitransportSocket => "netlink_scsitransport_socket",
225 Self::NetlinkSelinuxSocket => "netlink_selinux_socket",
226 Self::NetlinkSocket => "netlink_socket",
227 Self::NetlinkTcpDiagSocket => "netlink_tcpdiag_socket",
228 Self::NetlinkXfrmSocket => "netlink_xfrm_socket",
229 Self::PacketSocket => "packet_socket",
230 Self::PerfEvent => "perf_event",
231 Self::Process => "process",
232 Self::Process2 => "process2",
233 Self::QipcrtrSocket => "qipcrtr_socket",
234 Self::RawIpSocket => "rawip_socket",
235 Self::Security => "security",
236 Self::SockFile => "sock_file",
237 Self::Socket => "socket",
238 Self::System => "system",
239 Self::TcpSocket => "tcp_socket",
240 Self::TunSocket => "tun_socket",
241 Self::UdpSocket => "udp_socket",
242 Self::UnixDgramSocket => "unix_dgram_socket",
243 Self::UnixStreamSocket => "unix_stream_socket",
244 Self::VSockSocket => "vsock_socket",
245 // keep-sorted end
246 }
247 }
248}
249
250impl<T: Into<KernelClass>> ForClass<T> for KernelPermission {
251 fn for_class(&self, class: T) -> KernelPermission {
252 assert_eq!(self.class(), class.into());
253 self.clone()
254 }
255}
256
257pub trait ForClass<T> {
258 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
259 /// This is used to allow hooks to resolve e.g. common "sys_nice" permission access based on the
260 /// "allow" rules for the correct target object class.
261 fn for_class(&self, class: T) -> KernelPermission;
262}
263
264enumerable_enum! {
265 /// Covers the set of classes that inherit from the common "cap" symbol (e.g. "capability" for
266 /// now and "cap_userns" after Starnix gains user namespacing support).
267 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
268 CapClass {
269 // keep-sorted start
270 /// The SELinux "capability" object class.
271 Capability,
272 // keep-sorted end
273 }
274}
275
276impl From<CapClass> for KernelClass {
277 fn from(cap_class: CapClass) -> Self {
278 match cap_class {
279 // keep-sorted start
280 CapClass::Capability => Self::Capability,
281 // keep-sorted end
282 }
283 }
284}
285
286enumerable_enum! {
287 /// Covers the set of classes that inherit from the common "cap2" symbol (e.g. "capability2" for
288 /// now and "cap2_userns" after Starnix gains user namespacing support).
289 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
290 Cap2Class {
291 // keep-sorted start
292 /// The SELinux "capability2" object class.
293 Capability2,
294 // keep-sorted end
295 }
296}
297
298impl From<Cap2Class> for KernelClass {
299 fn from(cap2_class: Cap2Class) -> Self {
300 match cap2_class {
301 // keep-sorted start
302 Cap2Class::Capability2 => Self::Capability2,
303 // keep-sorted end
304 }
305 }
306}
307
308enumerable_enum! {
309 /// A well-known file-like class in SELinux policy that has a particular meaning in policy
310 /// enforcement hooks.
311 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
312 FileClass {
313 // keep-sorted start
314 /// The SELinux "anon_inode" object class.
315 AnonFsNode,
316 /// The SELinux "blk_file" object class.
317 Block,
318 /// The SELinux "chr_file" object class.
319 Character,
320 /// The SELinux "dir" object class.
321 Dir,
322 /// The SELinux "fifo_file" object class.
323 Fifo,
324 /// The SELinux "file" object class.
325 File,
326 /// The SELinux "lnk_file" object class.
327 Link,
328 /// The SELinux "memfd_file" object class.
329 MemFdFile,
330 /// The SELinux "sock_file" object class.
331 SockFile,
332 // keep-sorted end
333 }
334}
335
336impl From<FileClass> for KernelClass {
337 fn from(file_class: FileClass) -> Self {
338 match file_class {
339 // keep-sorted start
340 FileClass::AnonFsNode => Self::AnonFsNode,
341 FileClass::Block => Self::Block,
342 FileClass::Character => Self::Character,
343 FileClass::Dir => Self::Dir,
344 FileClass::Fifo => Self::Fifo,
345 FileClass::File => Self::File,
346 FileClass::Link => Self::Link,
347 FileClass::MemFdFile => Self::MemFdFile,
348 FileClass::SockFile => Self::SockFile,
349 // keep-sorted end
350 }
351 }
352}
353
354enumerable_enum! {
355 /// Distinguishes socket-like kernel object classes defined in SELinux policy.
356 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
357 SocketClass {
358 // keep-sorted start
359 Key,
360 Netlink,
361 NetlinkAudit,
362 NetlinkConnector,
363 NetlinkCrypto,
364 NetlinkDnrt,
365 NetlinkFibLookup,
366 NetlinkFirewall,
367 NetlinkGeneric,
368 NetlinkIp6Fw,
369 NetlinkIscsi,
370 NetlinkKobjectUevent,
371 NetlinkNetfilter,
372 NetlinkNflog,
373 NetlinkRdma,
374 NetlinkRoute,
375 NetlinkScsitransport,
376 NetlinkSelinux,
377 NetlinkTcpDiag,
378 NetlinkXfrm,
379 Packet,
380 Qipcrtr,
381 RawIp,
382 /// Generic socket class applied to all socket-like objects for which no more specific
383 /// class is defined.
384 Socket,
385 Tcp,
386 Tun,
387 Udp,
388 UnixDgram,
389 UnixStream,
390 Vsock,
391 // keep-sorted end
392 }
393}
394
395impl From<SocketClass> for KernelClass {
396 fn from(socket_class: SocketClass) -> Self {
397 match socket_class {
398 // keep-sorted start
399 SocketClass::Key => Self::KeySocket,
400 SocketClass::Netlink => Self::NetlinkSocket,
401 SocketClass::NetlinkAudit => Self::NetlinkAuditSocket,
402 SocketClass::NetlinkConnector => Self::NetlinkConnectorSocket,
403 SocketClass::NetlinkCrypto => Self::NetlinkCryptoSocket,
404 SocketClass::NetlinkDnrt => Self::NetlinkDnrtSocket,
405 SocketClass::NetlinkFibLookup => Self::NetlinkFibLookupSocket,
406 SocketClass::NetlinkFirewall => Self::NetlinkFirewallSocket,
407 SocketClass::NetlinkGeneric => Self::NetlinkGenericSocket,
408 SocketClass::NetlinkIp6Fw => Self::NetlinkIp6FwSocket,
409 SocketClass::NetlinkIscsi => Self::NetlinkIscsiSocket,
410 SocketClass::NetlinkKobjectUevent => Self::NetlinkKobjectUeventSocket,
411 SocketClass::NetlinkNetfilter => Self::NetlinkNetfilterSocket,
412 SocketClass::NetlinkNflog => Self::NetlinkNflogSocket,
413 SocketClass::NetlinkRdma => Self::NetlinkRdmaSocket,
414 SocketClass::NetlinkRoute => Self::NetlinkRouteSocket,
415 SocketClass::NetlinkScsitransport => Self::NetlinkScsitransportSocket,
416 SocketClass::NetlinkSelinux => Self::NetlinkSelinuxSocket,
417 SocketClass::NetlinkTcpDiag => Self::NetlinkTcpDiagSocket,
418 SocketClass::NetlinkXfrm => Self::NetlinkXfrmSocket,
419 SocketClass::Packet => Self::PacketSocket,
420 SocketClass::Qipcrtr => Self::QipcrtrSocket,
421 SocketClass::RawIp => Self::RawIpSocket,
422 SocketClass::Socket => Self::Socket,
423 SocketClass::Tcp => Self::TcpSocket,
424 SocketClass::Tun => Self::TunSocket,
425 SocketClass::Udp => Self::UdpSocket,
426 SocketClass::UnixDgram => Self::UnixDgramSocket,
427 SocketClass::UnixStream => Self::UnixStreamSocket,
428 SocketClass::Vsock => Self::VSockSocket,
429 // keep-sorted end
430 }
431 }
432}
433
434/// Container for a security class that could be associated with a [`crate::vfs::FsNode`], to allow
435/// permissions common to both file-like and socket-like classes to be generated easily by hooks.
436#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
437pub enum FsNodeClass {
438 File(FileClass),
439 Socket(SocketClass),
440}
441
442impl From<FsNodeClass> for KernelClass {
443 fn from(class: FsNodeClass) -> Self {
444 match class {
445 FsNodeClass::File(file_class) => file_class.into(),
446 FsNodeClass::Socket(sock_class) => sock_class.into(),
447 }
448 }
449}
450
451impl From<FileClass> for FsNodeClass {
452 fn from(file_class: FileClass) -> Self {
453 FsNodeClass::File(file_class)
454 }
455}
456
457impl From<SocketClass> for FsNodeClass {
458 fn from(sock_class: SocketClass) -> Self {
459 FsNodeClass::Socket(sock_class)
460 }
461}
462
463pub trait ClassPermission {
464 fn class(&self) -> KernelClass;
465}
466
467macro_rules! permission_enum {
468 ($(#[$meta:meta])* $name:ident {
469 $($(#[$variant_meta:meta])* $variant:ident($inner:ident)),*,
470 }) => {
471 $(#[$meta])*
472 pub enum $name {
473 $($(#[$variant_meta])* $variant($inner)),*
474 }
475
476 $(impl From<$inner> for $name {
477 fn from(v: $inner) -> Self {
478 Self::$variant(v)
479 }
480 })*
481
482 impl ClassPermission for $name {
483 fn class(&self) -> KernelClass {
484 match self {
485 $($name::$variant(_) => KernelClass::$variant),*
486 }
487 }
488 }
489
490 impl $name {
491 pub fn name(&self) -> &'static str {
492 match self {
493 $($name::$variant(v) => v.name()),*
494 }
495 }
496
497 pub fn all_variants() -> impl Iterator<Item=Self> {
498 let iter = [].iter().map(Clone::clone);
499 $(let iter = iter.chain($inner::all_variants().map($name::from));)*
500 iter
501 }
502 }
503 }
504}
505
506permission_enum! {
507 /// A well-known `(class, permission)` pair in SELinux policy that has a particular meaning in
508 /// policy enforcement hooks.
509 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
510 KernelPermission {
511 // keep-sorted start
512 /// Permissions for the well-known SELinux "anon_inode" file-like object class.
513 AnonFsNode(AnonFsNodePermission),
514 /// Permissions for the well-known SELinux "binder" file-like object class.
515 Binder(BinderPermission),
516 /// Permissions for the well-known SELinux "blk_file" file-like object class.
517 Block(BlockFilePermission),
518 /// Permissions for the well-known SELinux "bpf" file-like object class.
519 Bpf(BpfPermission),
520 /// Permissions for the well-known SELinux "capability" object class.
521 Capability(CapabilityPermission),
522 /// Permissions for the well-known SELinux "capability2" object class.
523 Capability2(Capability2Permission),
524 /// Permissions for the well-known SELinux "chr_file" file-like object class.
525 Character(CharacterFilePermission),
526 /// Permissions for the well-known SELinux "dir" file-like object class.
527 Dir(DirPermission),
528 /// Permissions for the well-known SELinux "fd" object class.
529 Fd(FdPermission),
530 /// Permissions for the well-known SELinux "fifo_file" file-like object class.
531 Fifo(FifoFilePermission),
532 /// Permissions for the well-known SELinux "file" object class.
533 File(FilePermission),
534 /// Permissions for the well-known SELinux "filesystem" object class.
535 FileSystem(FileSystemPermission),
536 /// Permissions for the well-known SELinux "packet_socket" object class.
537 KeySocket(KeySocketPermission),
538 /// Permissions for the well-known SELinux "lnk_file" file-like object class.
539 Link(LinkFilePermission),
540 /// Permissions for the well-known SELinux "memfd_file" file-like object class.
541 MemFdFile(MemFdFilePermission),
542 /// Permissions for the well-known SELinux "netlink_audit_socket" file-like object class.
543 NetlinkAuditSocket(NetlinkAuditSocketPermission),
544 /// Permissions for the well-known SELinux "netlink_connector_socket" file-like object class.
545 NetlinkConnectorSocket(NetlinkConnectorSocketPermission),
546 /// Permissions for the well-known SELinux "netlink_crypto_socket" file-like object class.
547 NetlinkCryptoSocket(NetlinkCryptoSocketPermission),
548 /// Permissions for the well-known SELinux "netlink_dnrt_socket" file-like object class.
549 NetlinkDnrtSocket(NetlinkDnrtSocketPermission),
550 /// Permissions for the well-known SELinux "netlink_fib_lookup_socket" file-like object class.
551 NetlinkFibLookupSocket(NetlinkFibLookupSocketPermission),
552 /// Permissions for the well-known SELinux "netlink_firewall_socket" file-like object class.
553 NetlinkFirewallSocket(NetlinkFirewallSocketPermission),
554 /// Permissions for the well-known SELinux "netlink_generic_socket" file-like object class.
555 NetlinkGenericSocket(NetlinkGenericSocketPermission),
556 /// Permissions for the well-known SELinux "netlink_ip6fw_socket" file-like object class.
557 NetlinkIp6FwSocket(NetlinkIp6FwSocketPermission),
558 /// Permissions for the well-known SELinux "netlink_iscsi_socket" file-like object class.
559 NetlinkIscsiSocket(NetlinkIscsiSocketPermission),
560 /// Permissions for the well-known SELinux "netlink_kobject_uevent_socket" file-like object class.
561 NetlinkKobjectUeventSocket(NetlinkKobjectUeventSocketPermission),
562 /// Permissions for the well-known SELinux "netlink_netfilter_socket" file-like object class.
563 NetlinkNetfilterSocket(NetlinkNetfilterSocketPermission),
564 /// Permissions for the well-known SELinux "netlink_nflog_socket" file-like object class.
565 NetlinkNflogSocket(NetlinkNflogSocketPermission),
566 /// Permissions for the well-known SELinux "netlink_rdma_socket" file-like object class.
567 NetlinkRdmaSocket(NetlinkRdmaSocketPermission),
568 /// Permissions for the well-known SELinux "netlink_route_socket" file-like object class.
569 NetlinkRouteSocket(NetlinkRouteSocketPermission),
570 /// Permissions for the well-known SELinux "netlink_scsitransport_socket" file-like object class.
571 NetlinkScsitransportSocket(NetlinkScsitransportSocketPermission),
572 /// Permissions for the well-known SELinux "netlink_selinux_socket" file-like object class.
573 NetlinkSelinuxSocket(NetlinkSelinuxSocketPermission),
574 /// Permissions for the well-known SELinux "netlink_socket" file-like object class.
575 NetlinkSocket(NetlinkSocketPermission),
576 /// Permissions for the well-known SELinux "netlink_tcpdiag_socket" file-like object class.
577 NetlinkTcpDiagSocket(NetlinkTcpDiagSocketPermission),
578 /// Permissions for the well-known SELinux "netlink_xfrm_socket" file-like object class.
579 NetlinkXfrmSocket(NetlinkXfrmSocketPermission),
580 /// Permissions for the well-known SELinux "packet_socket" object class.
581 PacketSocket(PacketSocketPermission),
582 /// Permissions for the well-known SELinux "perf_event" object class.
583 PerfEvent(PerfEventPermission),
584 /// Permissions for the well-known SELinux "process" object class.
585 Process(ProcessPermission),
586 /// Permissions for the well-known SELinux "process2" object class.
587 Process2(Process2Permission),
588 /// Permissions for the well-known SELinux "qipcrtr_socket" object class.
589 QipcrtrSocket(QipcrtrSocketPermission),
590 /// Permissions for the well-known SELinux "rawip_socket" object class.
591 RawIpSocket(RawIpSocketPermission),
592 /// Permissions for access to parts of the "selinuxfs" used to administer and query SELinux.
593 Security(SecurityPermission),
594 /// Permissions for the well-known SELinux "sock_file" file-like object class.
595 SockFile(SockFilePermission),
596 /// Permissions for the well-known SELinux "socket" object class.
597 Socket(SocketPermission),
598 /// Permissions for the well-known SELinux "system" object class.
599 System(SystemPermission),
600 /// Permissions for the well-known SELinux "tcp_socket" object class.
601 TcpSocket(TcpSocketPermission),
602 /// Permissions for the well-known SELinux "tun_socket" object class.
603 TunSocket(TunSocketPermission),
604 /// Permissions for the well-known SELinux "udp_socket" object class.
605 UdpSocket(UdpSocketPermission),
606 /// Permissions for the well-known SELinux "unix_dgram_socket" object class.
607 UnixDgramSocket(UnixDgramSocketPermission),
608 /// Permissions for the well-known SELinux "unix_stream_socket" object class.
609 UnixStreamSocket(UnixStreamSocketPermission),
610 /// Permissions for the well-known SELinux "vsock_socket" object class.
611 VSockSocket(VsockSocketPermission),
612 // keep-sorted end
613 }
614}
615
616/// Helper used to define an enum of permission values, with specified names.
617/// Uses of this macro should not rely on "extends", which is solely for use to express permission
618/// inheritance in `class_permission_enum`.
619macro_rules! common_permission_enum {
620 ($(#[$meta:meta])* $name:ident $(extends $common_name:ident)? {
621 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
622 }) => {
623 enumerable_enum! {
624 $(#[$meta])* $name $(extends $common_name)? {
625 $($(#[$variant_meta])* $variant,)*
626 }
627 }
628
629 impl $name {
630 fn name(&self) -> &'static str {
631 match self {
632 $($name::$variant => $variant_name,)*
633 $(Self::Common(v) => {let v:$common_name = v.clone(); v.name()},)?
634 }
635 }
636 }
637 }
638}
639
640/// Helper used to declare the set of named permissions associated with an SELinux class.
641/// The `ClassType` trait is implemented on the declared `enum`, enabling values to be wrapped into
642/// the generic `KernelPermission` container.
643/// If an "extends" type is specified then a `Common` enum case is added, encapsulating the values
644/// of that underlying permission type. This is used to represent e.g. SELinux "dir" class deriving
645/// a basic set of permissions from the common "file" symbol.
646macro_rules! class_permission_enum {
647 ($(#[$meta:meta])* $name:ident $(extends $common_name:ident)? {
648 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
649 }) => {
650 common_permission_enum! {
651 $(#[$meta])* $name $(extends $common_name)? {
652 $($(#[$variant_meta])* $variant ($variant_name),)*
653 }
654 }
655
656 impl ClassPermission for $name {
657 fn class(&self) -> KernelClass {
658 KernelPermission::from(self.clone()).class()
659 }
660 }
661 }
662}
663
664common_permission_enum! {
665 /// Permissions common to all cap-like object classes (e.g. "capability" for now and
666 /// "cap_userns" after Starnix gains user namespacing support). These are combined with a
667 /// specific `CapabilityClass` by policy enforcement hooks, to obtain class-affine permission
668 /// values to check.
669 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
670 CommonCapPermission {
671 // keep-sorted start
672
673 AuditControl("audit_control"),
674 AuditWrite("audit_write"),
675 Chown("chown"),
676 DacOverride("dac_override"),
677 DacReadSearch("dac_read_search"),
678 Fowner("fowner"),
679 Fsetid("fsetid"),
680 IpcLock("ipc_lock"),
681 IpcOwner("ipc_owner"),
682 Kill("kill"),
683 Lease("lease"),
684 LinuxImmutable("linux_immutable"),
685 Mknod("mknod"),
686 NetAdmin("net_admin"),
687 NetBindService("net_bind_service"),
688 NetBroadcast("net_broadcast"),
689 NetRaw("net_raw"),
690 Setfcap("setfcap"),
691 Setgid("setgid"),
692 Setpcap("setpcap"),
693 Setuid("setuid"),
694 SysAdmin("sys_admin"),
695 SysBoot("sys_boot"),
696 SysChroot("sys_chroot"),
697 SysModule("sys_module"),
698 SysNice("sys_nice"),
699 SysPacct("sys_pacct"),
700 SysPtrace("sys_ptrace"),
701 SysRawio("sys_rawio"),
702 SysResource("sys_resource"),
703 SysTime("sys_time"),
704 SysTtyConfig("sys_tty_config"),
705
706 // keep-sorted end
707 }
708}
709
710class_permission_enum! {
711 /// A well-known "capability" class permission in SELinux policy that has a particular meaning
712 /// in policy enforcement hooks.
713 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
714 CapabilityPermission extends CommonCapPermission {}
715}
716
717impl ForClass<CapClass> for CommonCapPermission {
718 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
719 /// This is used to allow hooks to resolve e.g. common "sys_nice" permission access based on the
720 /// "allow" rules for the correct target object class.
721 fn for_class(&self, class: CapClass) -> KernelPermission {
722 match class {
723 CapClass::Capability => CapabilityPermission::Common(self.clone()).into(),
724 }
725 }
726}
727
728common_permission_enum! {
729 /// Permissions common to all cap2-like object classes (e.g. "capability2" for now and
730 /// "cap2_userns" after Starnix gains user namespacing support). These are combined with a
731 /// specific `Capability2Class` by policy enforcement hooks, to obtain class-affine permission
732 /// values to check.
733 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
734 CommonCap2Permission {
735 // keep-sorted start
736
737 AuditRead("audit_read"),
738 BlockSuspend("block_suspend"),
739 Bpf("bpf"),
740 MacAdmin("mac_admin"),
741 MacOverride("mac_override"),
742 Perfmon("perfmon"),
743 Syslog("syslog"),
744 WakeAlarm("wake_alarm"),
745
746 // keep-sorted end
747 }
748}
749
750class_permission_enum! {
751 /// A well-known "capability2" class permission in SELinux policy that has a particular meaning
752 /// in policy enforcement hooks.
753 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
754 Capability2Permission extends CommonCap2Permission {}
755}
756
757impl ForClass<Cap2Class> for CommonCap2Permission {
758 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
759 /// This is used to allow hooks to resolve e.g. common "mac_admin" permission access based on
760 /// the "allow" rules for the correct target object class.
761 fn for_class(&self, class: Cap2Class) -> KernelPermission {
762 match class {
763 Cap2Class::Capability2 => Capability2Permission::Common(self.clone()).into(),
764 }
765 }
766}
767
768common_permission_enum! {
769 /// Permissions meaningful for all [`crate::vfs::FsNode`]s, whether file- or socket-like.
770 ///
771 /// This extra layer of common permissions is not reflected in the hierarchy defined by the
772 /// SELinux Reference Policy. Because even common permissions are mapped per-class, by name, to
773 /// the policy equivalents, the implementation and policy notions of common permissions need not
774 /// be identical.
775 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
776 CommonFsNodePermission {
777 // keep-sorted start
778 /// Permission to append to a file or socket.
779 Append("append"),
780 /// Pseudo-permission used in `dontaudit` access-rules to allow access checks to be made
781 /// between specific sources & targets without generating audit logs.
782 AuditAccess("audit_access"),
783 /// Permission to create a file or socket.
784 Create("create"),
785 /// Permission to query attributes, including uid, gid and extended attributes.
786 GetAttr("getattr"),
787 /// Permission to execute ioctls on the file or socket.
788 Ioctl("ioctl"),
789 /// Permission to set and unset file or socket locks.
790 Lock("lock"),
791 /// Permission to map a file.
792 Map("map"),
793 /// Permission to read content from a file or socket, as well as reading or following links.
794 Read("read"),
795 /// Permission checked against the existing label when updating a node's security label.
796 RelabelFrom("relabelfrom"),
797 /// Permission checked against the new label when updating a node's security label.
798 RelabelTo("relabelto"),
799 /// Permission to modify attributes, including uid, gid and extended attributes.
800 SetAttr("setattr"),
801 /// Permission to write contents to the file or socket.
802 Write("write"),
803 // keep-sorted end
804 }
805}
806
807impl<T: Into<FsNodeClass>> ForClass<T> for CommonFsNodePermission {
808 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
809 /// This is used to allow hooks to resolve e.g. common "read" permission access based on the
810 /// "allow" rules for the correct target object class.
811 fn for_class(&self, class: T) -> KernelPermission {
812 match class.into() {
813 FsNodeClass::File(file_class) => {
814 CommonFilePermission::Common(self.clone()).for_class(file_class)
815 }
816 FsNodeClass::Socket(sock_class) => {
817 CommonSocketPermission::Common(self.clone()).for_class(sock_class)
818 }
819 }
820 }
821}
822common_permission_enum! {
823 /// Permissions common to all socket-like object classes. These are combined with a specific
824 /// `SocketClass` by policy enforcement hooks, to obtain class-affine permission values.
825 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
826 CommonSocketPermission extends CommonFsNodePermission {
827 // keep-sorted start
828 /// Permission to accept a connection.
829 Accept("accept"),
830 /// Permission to bind to a name.
831 Bind("bind"),
832 /// Permission to initiate a connection.
833 Connect("connect"),
834 /// Permission to get socket options.
835 GetOpt("getopt"),
836 /// Permission to listen for connections.
837 Listen("listen"),
838 /// Permission to send datagrams to the socket.
839 SendTo("sendto"),
840 /// Permission to set socket options.
841 SetOpt("setopt"),
842 /// Permission to terminate connection.
843 Shutdown("shutdown"),
844 // keep-sorted end
845 }
846}
847
848impl ForClass<SocketClass> for CommonSocketPermission {
849 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
850 /// This is used to allow hooks to resolve e.g. common "read" permission access based on the
851 /// "allow" rules for the correct target object class.
852 fn for_class(&self, class: SocketClass) -> KernelPermission {
853 match class {
854 SocketClass::Key => KeySocketPermission::Common(self.clone()).into(),
855 SocketClass::Netlink => NetlinkSocketPermission::Common(self.clone()).into(),
856 SocketClass::NetlinkAudit => NetlinkAuditSocketPermission::Common(self.clone()).into(),
857 SocketClass::NetlinkConnector => {
858 NetlinkConnectorSocketPermission::Common(self.clone()).into()
859 }
860 SocketClass::NetlinkCrypto => {
861 NetlinkCryptoSocketPermission::Common(self.clone()).into()
862 }
863 SocketClass::NetlinkDnrt => NetlinkDnrtSocketPermission::Common(self.clone()).into(),
864 SocketClass::NetlinkFibLookup => {
865 NetlinkFibLookupSocketPermission::Common(self.clone()).into()
866 }
867 SocketClass::NetlinkFirewall => {
868 NetlinkFirewallSocketPermission::Common(self.clone()).into()
869 }
870 SocketClass::NetlinkGeneric => {
871 NetlinkGenericSocketPermission::Common(self.clone()).into()
872 }
873 SocketClass::NetlinkIp6Fw => NetlinkIp6FwSocketPermission::Common(self.clone()).into(),
874 SocketClass::NetlinkIscsi => NetlinkIscsiSocketPermission::Common(self.clone()).into(),
875 SocketClass::NetlinkKobjectUevent => {
876 NetlinkKobjectUeventSocketPermission::Common(self.clone()).into()
877 }
878 SocketClass::NetlinkNetfilter => {
879 NetlinkNetfilterSocketPermission::Common(self.clone()).into()
880 }
881 SocketClass::NetlinkNflog => NetlinkNflogSocketPermission::Common(self.clone()).into(),
882 SocketClass::NetlinkRdma => NetlinkRdmaSocketPermission::Common(self.clone()).into(),
883 SocketClass::NetlinkRoute => NetlinkRouteSocketPermission::Common(self.clone()).into(),
884 SocketClass::NetlinkScsitransport => {
885 NetlinkScsitransportSocketPermission::Common(self.clone()).into()
886 }
887 SocketClass::NetlinkSelinux => {
888 NetlinkSelinuxSocketPermission::Common(self.clone()).into()
889 }
890 SocketClass::NetlinkTcpDiag => {
891 NetlinkTcpDiagSocketPermission::Common(self.clone()).into()
892 }
893 SocketClass::NetlinkXfrm => NetlinkXfrmSocketPermission::Common(self.clone()).into(),
894 SocketClass::Packet => PacketSocketPermission::Common(self.clone()).into(),
895 SocketClass::Qipcrtr => QipcrtrSocketPermission::Common(self.clone()).into(),
896 SocketClass::RawIp => RawIpSocketPermission::Common(self.clone()).into(),
897 SocketClass::Socket => SocketPermission::Common(self.clone()).into(),
898 SocketClass::Tcp => TcpSocketPermission::Common(self.clone()).into(),
899 SocketClass::Tun => TunSocketPermission::Common(self.clone()).into(),
900 SocketClass::Udp => UdpSocketPermission::Common(self.clone()).into(),
901 SocketClass::UnixDgram => UnixDgramSocketPermission::Common(self.clone()).into(),
902 SocketClass::UnixStream => UnixStreamSocketPermission::Common(self.clone()).into(),
903 SocketClass::Vsock => VsockSocketPermission::Common(self.clone()).into(),
904 }
905 }
906}
907
908class_permission_enum! {
909 /// A well-known "key_socket" class permission in SELinux policy that has a particular meaning in
910 /// policy enforcement hooks.
911 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
912 KeySocketPermission extends CommonSocketPermission {
913 }
914}
915class_permission_enum! {
916 /// A well-known "netlink_socket" class permission in SELinux policy that has a particular meaning in
917 /// policy enforcement hooks.
918 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
919 NetlinkSocketPermission extends CommonSocketPermission {
920 }
921}
922
923class_permission_enum! {
924 /// A well-known "netlink_route_socket" class permission in SELinux policy that has a particular meaning in
925 /// policy enforcement hooks.
926 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
927 NetlinkRouteSocketPermission extends CommonSocketPermission {
928 // keep-sorted start
929 /// Permission for nlmsg xperms.
930 Nlmsg("nlmsg"),
931 /// Permission to read the kernel routing table.
932 NlmsgRead("nlmsg_read"),
933 /// Permission to write to the kernel routing table.
934 NlmsgWrite("nlmsg_write"),
935 // keep-sorted end
936 }
937}
938
939class_permission_enum! {
940 /// A well-known "netlink_firewall_socket" class permission in SELinux policy that has a particular meaning in
941 /// policy enforcement hooks.
942 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
943 NetlinkFirewallSocketPermission extends CommonSocketPermission {
944 }
945}
946
947class_permission_enum! {
948 /// A well-known "netlink_tcpdiag_socket" class permission in SELinux policy that has a particular meaning in
949 /// policy enforcement hooks.
950 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
951 NetlinkTcpDiagSocketPermission extends CommonSocketPermission {
952 // keep-sorted start
953 /// Permission for nlmsg xperms.
954 Nlmsg("nlmsg"),
955 /// Permission to request information about a protocol.
956 NlmsgRead("nlmsg_read"),
957 /// Permission to write netlink message.
958 NlmsgWrite("nlmsg_write"),
959 // keep-sorted end
960 }
961}
962
963class_permission_enum! {
964 /// A well-known "netlink_nflog_socket" class permission in SELinux policy that has a particular meaning in
965 /// policy enforcement hooks.
966 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
967 NetlinkNflogSocketPermission extends CommonSocketPermission {
968 }
969}
970
971class_permission_enum! {
972 /// A well-known "netlink_xfrm_socket" class permission in SELinux policy that has a particular meaning in
973 /// policy enforcement hooks.
974 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
975 NetlinkXfrmSocketPermission extends CommonSocketPermission {
976 // keep-sorted start
977 /// Permission for nlmsg xperms.
978 Nlmsg("nlmsg"),
979 /// Permission to get IPSec configuration information.
980 NlmsgRead("nlmsg_read"),
981 /// Permission to set IPSec configuration information.
982 NlmsgWrite("nlmsg_write"),
983 // keep-sorted end
984 }
985}
986
987class_permission_enum! {
988 /// A well-known "netlink_selinux_socket" class permission in SELinux policy that has a particular meaning in
989 /// policy enforcement hooks.
990 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
991 NetlinkSelinuxSocketPermission extends CommonSocketPermission {
992 }
993}
994
995class_permission_enum! {
996 /// A well-known "netlink_iscsi_socket" class permission in SELinux policy that has a particular meaning in
997 /// policy enforcement hooks.
998 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
999 NetlinkIscsiSocketPermission extends CommonSocketPermission {
1000 }
1001}
1002
1003class_permission_enum! {
1004 /// A well-known "netlink_audit_socket" class permission in SELinux policy that has a particular meaning in
1005 /// policy enforcement hooks.
1006 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1007 NetlinkAuditSocketPermission extends CommonSocketPermission {
1008 // keep-sorted start
1009 /// Permission for nlmsg xperms.
1010 Nlmsg("nlmsg"),
1011 /// Permission to query status of audit service.
1012 NlmsgRead("nlmsg_read"),
1013 /// Permission to list auditing configuration rules.
1014 NlmsgReadPriv("nlmsg_readpriv"),
1015 /// Permission to send userspace audit messages to the audit service.
1016 NlmsgRelay("nlmsg_relay"),
1017 /// Permission to control TTY auditing.
1018 NlmsgTtyAudit("nlmsg_tty_audit"),
1019 /// Permission to update the audit service configuration.
1020 NlmsgWrite("nlmsg_write"),
1021 // keep-sorted end
1022 }
1023}
1024
1025class_permission_enum! {
1026 /// A well-known "netlink_fib_lookup_socket" class permission in SELinux policy that has a particular meaning in
1027 /// policy enforcement hooks.
1028 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1029 NetlinkFibLookupSocketPermission extends CommonSocketPermission {
1030 }
1031}
1032
1033class_permission_enum! {
1034 /// A well-known "netlink_connector_socket" class permission in SELinux policy that has a particular meaning in
1035 /// policy enforcement hooks.
1036 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1037 NetlinkConnectorSocketPermission extends CommonSocketPermission {
1038 }
1039}
1040
1041class_permission_enum! {
1042 /// A well-known "netlink_netfilter_socket" class permission in SELinux policy that has a particular meaning in
1043 /// policy enforcement hooks.
1044 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1045 NetlinkNetfilterSocketPermission extends CommonSocketPermission {
1046 }
1047}
1048
1049class_permission_enum! {
1050 /// A well-known "netlink_ip6fw_socket" class permission in SELinux policy that has a particular meaning in
1051 /// policy enforcement hooks.
1052 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1053 NetlinkIp6FwSocketPermission extends CommonSocketPermission {
1054 }
1055}
1056
1057class_permission_enum! {
1058 /// A well-known "netlink_dnrt_socket" class permission in SELinux policy that has a particular meaning in
1059 /// policy enforcement hooks.
1060 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1061 NetlinkDnrtSocketPermission extends CommonSocketPermission {
1062 }
1063}
1064
1065class_permission_enum! {
1066 /// A well-known "netlink_kobject_uevent_socket" class permission in SELinux policy that has a particular meaning in
1067 /// policy enforcement hooks.
1068 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1069 NetlinkKobjectUeventSocketPermission extends CommonSocketPermission {
1070 }
1071}
1072
1073class_permission_enum! {
1074 /// A well-known "netlink_generic_socket" class permission in SELinux policy that has a particular meaning in
1075 /// policy enforcement hooks.
1076 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1077 NetlinkGenericSocketPermission extends CommonSocketPermission {
1078 }
1079}
1080
1081class_permission_enum! {
1082 /// A well-known "netlink_scsitransport_socket" class permission in SELinux policy that has a particular meaning in
1083 /// policy enforcement hooks.
1084 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1085 NetlinkScsitransportSocketPermission extends CommonSocketPermission {
1086 }
1087}
1088
1089class_permission_enum! {
1090 /// A well-known "netlink_rdma_socket" class permission in SELinux policy that has a particular meaning in
1091 /// policy enforcement hooks.
1092 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1093 NetlinkRdmaSocketPermission extends CommonSocketPermission {
1094 }
1095}
1096
1097class_permission_enum! {
1098 /// A well-known "netlink_crypto_socket" class permission in SELinux policy that has a particular meaning in
1099 /// policy enforcement hooks.
1100 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1101 NetlinkCryptoSocketPermission extends CommonSocketPermission {
1102 }
1103}
1104
1105class_permission_enum! {
1106 /// A well-known "packet_socket" class permission in SELinux policy that has a particular meaning in
1107 /// policy enforcement hooks.
1108 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1109 PacketSocketPermission extends CommonSocketPermission {
1110 }
1111}
1112
1113class_permission_enum! {
1114 /// A well-known "qipcrtr_socket" class permission in SELinux policy that has a particular meaning in
1115 /// policy enforcement hooks.
1116 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1117 QipcrtrSocketPermission extends CommonSocketPermission {
1118 }
1119}
1120
1121class_permission_enum! {
1122 /// A well-known "rawip_socket" class permission in SELinux policy that has a particular meaning in
1123 /// policy enforcement hooks.
1124 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1125 RawIpSocketPermission extends CommonSocketPermission {
1126 }
1127}
1128
1129class_permission_enum! {
1130 /// A well-known "socket" class permission in SELinux policy that has a particular meaning in
1131 /// policy enforcement hooks.
1132 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1133 SocketPermission extends CommonSocketPermission {
1134 }
1135}
1136
1137class_permission_enum! {
1138 /// A well-known "tcp_socket" class permission in SELinux policy that has a particular meaning in
1139 /// policy enforcement hooks.
1140 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1141 TcpSocketPermission extends CommonSocketPermission {
1142 }
1143}
1144
1145class_permission_enum! {
1146 /// A well-known "tun_socket" class permission in SELinux policy that has a particular meaning in
1147 /// policy enforcement hooks.
1148 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1149 TunSocketPermission extends CommonSocketPermission {
1150 }
1151}
1152
1153class_permission_enum! {
1154 /// A well-known "udp_socket" class permission in SELinux policy that has a particular meaning in
1155 /// policy enforcement hooks.
1156 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1157 UdpSocketPermission extends CommonSocketPermission {
1158 }
1159}
1160
1161class_permission_enum! {
1162 /// A well-known "unix_stream_socket" class permission in SELinux policy that has a particular meaning in
1163 /// policy enforcement hooks.
1164 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1165 UnixStreamSocketPermission extends CommonSocketPermission {
1166 // keep-sorted start
1167 /// Permission to connect a streaming Unix-domain socket.
1168 ConnectTo("connectto"),
1169 // keep-sorted end
1170 }
1171}
1172
1173class_permission_enum! {
1174 /// A well-known "unix_dgram_socket" class permission in SELinux policy that has a particular meaning in
1175 /// policy enforcement hooks.
1176 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1177 UnixDgramSocketPermission extends CommonSocketPermission {
1178 }
1179}
1180
1181class_permission_enum! {
1182 /// A well-known "vsock_socket" class permission in SELinux policy that has a particular meaning in
1183 /// policy enforcement hooks.
1184 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1185 VsockSocketPermission extends CommonSocketPermission {
1186 }
1187}
1188
1189common_permission_enum! {
1190 /// Permissions common to all file-like object classes (e.g. "lnk_file", "dir"). These are
1191 /// combined with a specific `FileClass` by policy enforcement hooks, to obtain class-affine
1192 /// permission values to check.
1193 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1194 CommonFilePermission extends CommonFsNodePermission {
1195 // keep-sorted start
1196 /// Permission to execute a file with domain transition.
1197 Execute("execute"),
1198 /// Permissions to create hard link.
1199 Link("link"),
1200 /// Permission to use as mount point; only useful for directories and files.
1201 MountOn("mounton"),
1202 /// Permission to open a file.
1203 Open("open"),
1204 /// Permission to rename a file.
1205 Rename("rename"),
1206 /// Permission to delete a file or remove a hard link.
1207 Unlink("unlink"),
1208 // keep-sorted end
1209 }
1210}
1211
1212impl ForClass<FileClass> for CommonFilePermission {
1213 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
1214 /// This is used to allow hooks to resolve e.g. common "read" permission access based on the
1215 /// "allow" rules for the correct target object class.
1216 fn for_class(&self, class: FileClass) -> KernelPermission {
1217 match class {
1218 FileClass::AnonFsNode => AnonFsNodePermission::Common(self.clone()).into(),
1219 FileClass::Block => BlockFilePermission::Common(self.clone()).into(),
1220 FileClass::Character => CharacterFilePermission::Common(self.clone()).into(),
1221 FileClass::Dir => DirPermission::Common(self.clone()).into(),
1222 FileClass::Fifo => FifoFilePermission::Common(self.clone()).into(),
1223 FileClass::File => FilePermission::Common(self.clone()).into(),
1224 FileClass::Link => LinkFilePermission::Common(self.clone()).into(),
1225 FileClass::SockFile => SockFilePermission::Common(self.clone()).into(),
1226 FileClass::MemFdFile => MemFdFilePermission::Common(self.clone()).into(),
1227 }
1228 }
1229}
1230
1231class_permission_enum! {
1232 /// A well-known "anon_file" class permission used to manage special file-like nodes not linked
1233 /// into any directory structures.
1234 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1235 AnonFsNodePermission extends CommonFilePermission {
1236 }
1237}
1238
1239class_permission_enum! {
1240 /// A well-known "binder" class permission in SELinux policy that has a particular meaning in
1241 /// policy enforcement hooks.
1242 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1243 BinderPermission {
1244 // keep-sorted start
1245 /// Permission to perform a binder IPC to a given target process.
1246 Call("call"),
1247 /// Permission to use a Binder connection created with a different security context.
1248 Impersonate("impersonate"),
1249 /// Permission to set oneself as a context manager.
1250 SetContextMgr("set_context_mgr"),
1251 /// Permission to transfer Binder objects as part of a Binder transaction.
1252 Transfer("transfer"),
1253 // keep-sorted end
1254 }
1255}
1256
1257class_permission_enum! {
1258 /// A well-known "blk_file" class permission in SELinux policy that has a particular meaning in
1259 /// policy enforcement hooks.
1260 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1261 BlockFilePermission extends CommonFilePermission {
1262 }
1263}
1264
1265class_permission_enum! {
1266 /// A well-known "chr_file" class permission in SELinux policy that has a particular meaning in
1267 /// policy enforcement hooks.
1268 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1269 CharacterFilePermission extends CommonFilePermission {
1270 }
1271}
1272
1273class_permission_enum! {
1274 /// A well-known "dir" class permission in SELinux policy that has a particular meaning in
1275 /// policy enforcement hooks.
1276 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1277 DirPermission extends CommonFilePermission {
1278 // keep-sorted start
1279 /// Permission to add a file to the directory.
1280 AddName("add_name"),
1281 /// Permission to remove a directory.
1282 RemoveDir("rmdir"),
1283 /// Permission to remove an entry from a directory.
1284 RemoveName("remove_name"),
1285 /// Permission to change parent directory.
1286 Reparent("reparent"),
1287 /// Search access to the directory.
1288 Search("search"),
1289 // keep-sorted end
1290 }
1291}
1292
1293class_permission_enum! {
1294 /// A well-known "fd" class permission in SELinux policy that has a particular meaning in policy
1295 /// enforcement hooks.
1296 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1297 FdPermission {
1298 // keep-sorted start
1299 /// Permission to use file descriptors copied/retained/inherited from another security
1300 /// context. This permission is generally used to control whether an `exec*()` call from a
1301 /// cloned process that retained a copy of the file descriptor table should succeed.
1302 Use("use"),
1303 // keep-sorted end
1304 }
1305}
1306
1307class_permission_enum! {
1308 /// A well-known "bpf" class permission in SELinux policy that has a particular meaning in
1309 /// policy enforcement hooks.
1310 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1311 BpfPermission {
1312 // keep-sorted start
1313 /// Permission to create a map.
1314 MapCreate("map_create"),
1315 /// Permission to read from a map.
1316 MapRead("map_read"),
1317 /// Permission to write on a map.
1318 MapWrite("map_write"),
1319 /// Permission to load a program.
1320 ProgLoad("prog_load"),
1321 /// Permission to run a program.
1322 ProgRun("prog_run"),
1323 // keep-sorted end
1324 }
1325}
1326
1327class_permission_enum! {
1328 /// A well-known "perf_event" class permission in SELinux policy that has a particular meaning
1329 /// in policy hooks.
1330 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1331 PerfEventPermission {
1332 // keep-sorted start
1333 /// Permission to monitor the cpu.
1334 Cpu("cpu"),
1335 /// Permission to monitor the kernel.
1336 Kernel("kernel"),
1337 /// Permission to open a perf event.
1338 Open("open"),
1339 /// Permission to read a perf event.
1340 Read("read"),
1341 /// Permission to set tracepoints.
1342 Tracepoint("tracepoint"),
1343 /// Permission to write a perf event.
1344 Write("write"),
1345 // keep-sorted end
1346 }
1347}
1348
1349class_permission_enum! {
1350 /// A well-known "fifo_file" class permission in SELinux policy that has a particular meaning in
1351 /// policy enforcement hooks.
1352 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1353 FifoFilePermission extends CommonFilePermission {
1354 }
1355}
1356
1357class_permission_enum! {
1358 /// A well-known "file" class permission in SELinux policy that has a particular meaning in
1359 /// policy enforcement hooks.
1360 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1361 FilePermission extends CommonFilePermission {
1362 // keep-sorted start
1363 /// Permission to use a file as an entry point into the new domain on transition.
1364 Entrypoint("entrypoint"),
1365 /// Permission to use a file as an entry point to the calling domain without performing a
1366 /// transition.
1367 ExecuteNoTrans("execute_no_trans"),
1368 // keep-sorted end
1369 }
1370}
1371
1372class_permission_enum! {
1373 /// A well-known "filesystem" class permission in SELinux policy that has a particular meaning in
1374 /// policy enforcement hooks.
1375 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1376 FileSystemPermission {
1377 // keep-sorted start
1378 /// Permission to associate a file to the filesystem.
1379 Associate("associate"),
1380 /// Permission to get filesystem attributes.
1381 GetAttr("getattr"),
1382 /// Permission mount a filesystem.
1383 Mount("mount"),
1384 /// Permission to remount a filesystem with different flags.
1385 Remount("remount"),
1386 /// Permission to unmount a filesystem.
1387 Unmount("unmount"),
1388 // keep-sorted end
1389 }
1390}
1391
1392class_permission_enum! {
1393 /// A well-known "lnk_file" class permission in SELinux policy that has a particular meaning in
1394 /// policy enforcement hooks.
1395 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1396 LinkFilePermission extends CommonFilePermission {
1397 }
1398}
1399
1400class_permission_enum! {
1401 /// A well-known "mem_file" class permission in SELinux policy that has a particular meaning in
1402 /// policy enforcement hooks.
1403 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1404 MemFdFilePermission extends CommonFilePermission {
1405 }
1406}
1407
1408class_permission_enum! {
1409 /// A well-known "sock_file" class permission in SELinux policy that has a particular meaning in
1410 /// policy enforcement hooks.
1411 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1412 SockFilePermission extends CommonFilePermission {
1413 }
1414}
1415
1416class_permission_enum! {
1417 /// A well-known "process" class permission in SELinux policy that has a particular meaning in
1418 /// policy enforcement hooks.
1419 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1420 ProcessPermission {
1421 // keep-sorted start
1422 /// Permission to dynamically transition a process to a different security domain.
1423 DynTransition("dyntransition"),
1424 /// Permission to execute arbitrary code from the heap.
1425 ExecHeap("execheap"),
1426 /// Permission to execute arbitrary code from memory.
1427 ExecMem("execmem"),
1428 /// Permission to execute arbitrary code from the stack.
1429 ExecStack("execstack"),
1430 /// Permission to fork the current running process.
1431 Fork("fork"),
1432 /// Permission to get Linux capabilities of a process.
1433 GetCap("getcap"),
1434 /// Permission to get the process group ID.
1435 GetPgid("getpgid"),
1436 /// Permission to get the resource limits on a process.
1437 GetRlimit("getrlimit"),
1438 /// Permission to get scheduling policy currently applied to a process.
1439 GetSched("getsched"),
1440 /// Permission to get the session ID.
1441 GetSession("getsession"),
1442 /// Permission to exec into a new security domain without setting the AT_SECURE entry in the
1443 /// executable's auxiliary vector.
1444 NoAtSecure("noatsecure"),
1445 /// Permission to trace a process.
1446 Ptrace("ptrace"),
1447 /// Permission to inherit the parent process's resource limits on exec.
1448 RlimitInh("rlimitinh"),
1449 /// Permission to set Linux capabilities of a process.
1450 SetCap("setcap"),
1451 /// Permission to set the calling task's current Security Context.
1452 /// The "dyntransition" permission separately limits which Contexts "setcurrent" may be used to transition to.
1453 SetCurrent("setcurrent"),
1454 /// Permission to set the Security Context used by `exec()`.
1455 SetExec("setexec"),
1456 /// Permission to set the Security Context used when creating filesystem objects.
1457 SetFsCreate("setfscreate"),
1458 /// Permission to set the Security Context used when creating kernel keyrings.
1459 SetKeyCreate("setkeycreate"),
1460 /// Permission to set the process group ID.
1461 SetPgid("setpgid"),
1462 /// Permission to set the resource limits on a process.
1463 SetRlimit("setrlimit"),
1464 /// Permission to set scheduling policy for a process.
1465 SetSched("setsched"),
1466 /// Permission to set the Security Context used when creating new labeled sockets.
1467 SetSockCreate("setsockcreate"),
1468 /// Permission to share resources (e.g. FD table, address-space, etc) with a process.
1469 Share("share"),
1470 /// Permission to send SIGCHLD to a process.
1471 SigChld("sigchld"),
1472 /// Permission to inherit the parent process's signal state.
1473 SigInh("siginh"),
1474 /// Permission to send SIGKILL to a process.
1475 SigKill("sigkill"),
1476 /// Permission to send SIGSTOP to a process.
1477 SigStop("sigstop"),
1478 /// Permission to send a signal other than SIGKILL, SIGSTOP, or SIGCHLD to a process.
1479 Signal("signal"),
1480 /// Permission to transition to a different security domain.
1481 Transition("transition"),
1482 // keep-sorted end
1483 }
1484}
1485
1486class_permission_enum! {
1487 /// A well-known "process2" class permission in SELinux policy that has a particular meaning in
1488 /// policy enforcement hooks.
1489 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1490 Process2Permission {
1491 // keep-sorted start
1492 /// Permission to transition to an unbounded domain when no-new-privileges is set.
1493 NnpTransition("nnp_transition"),
1494 /// Permission to transition domain when executing from a no-SUID mounted filesystem.
1495 NosuidTransition("nosuid_transition"),
1496 // keep-sorted end
1497 }
1498}
1499
1500class_permission_enum! {
1501 /// A well-known "security" class permission in SELinux policy, used to control access to
1502 /// sensitive administrative and query API surfaces in the "selinuxfs".
1503 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1504 SecurityPermission {
1505 // keep-sorted start
1506 /// Permission to validate Security Context using the "context" API.
1507 CheckContext("check_context"),
1508 /// Permission to compute access vectors via the "access" API.
1509 ComputeAv("compute_av"),
1510 /// Permission to compute security contexts based on `type_transition` rules via "create".
1511 ComputeCreate("compute_create"),
1512 /// Permission to compute security contexts based on `type_member` rules via "member".
1513 ComputeMember("compute_member"),
1514 /// Permission to compute security contexts based on `type_change` rules via "relabel".
1515 ComputeRelabel("compute_relabel"),
1516 /// Permission to compute user decisions via "user".
1517 ComputeUser("compute_user"),
1518 /// Permission to load a new binary policy into the kernel via the "load" API.
1519 LoadPolicy("load_policy"),
1520 /// Permission to commit booleans to control conditional elements of the policy.
1521 SetBool("setbool"),
1522 /// Permission to change the way permissions are validated for `mmap()` operations.
1523 SetCheckReqProt("setcheckreqprot"),
1524 /// Permission to switch the system between permissive and enforcing modes, via "enforce".
1525 SetEnforce("setenforce"),
1526 // keep-sorted end
1527 }
1528}
1529
1530class_permission_enum! {
1531 /// A well-known "system" class permission in SELinux policy, used to control access to
1532 /// sensitive administrative and query API surfaces in the "selinuxfs".
1533 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1534 SystemPermission {
1535 // keep-sorted start
1536 /// Permission to use the syslog(2) CONSOLE action types.
1537 SyslogConsole("syslog_console"),
1538 /// Permission to use other syslog(2) action types.
1539 SyslogMod("syslog_mod"),
1540 /// Permission to use the syslog(2) READ_ALL related action types.
1541 SyslogRead("syslog_read"),
1542 // keep-sorted end
1543 }
1544}
1545
1546/// Initial Security Identifier (SID) values defined by the SELinux Reference Policy.
1547/// Where the SELinux Reference Policy retains definitions for some deprecated initial SIDs, this
1548/// enum omits deprecated entries for clarity.
1549#[repr(u64)]
1550enum ReferenceInitialSid {
1551 Kernel = 1,
1552 Security = 2,
1553 Unlabeled = 3,
1554 _Fs = 4,
1555 File = 5,
1556 _Port = 9,
1557 _Netif = 10,
1558 _Netmsg = 11,
1559 _Node = 12,
1560 _Sysctl = 17,
1561 Devnull = 27,
1562
1563 FirstUnused,
1564}
1565
1566/// Lowest Security Identifier value guaranteed not to be used by this
1567/// implementation to refer to an initial Security Context.
1568pub const FIRST_UNUSED_SID: u32 = ReferenceInitialSid::FirstUnused as u32;
1569
1570macro_rules! initial_sid_enum {
1571 ($(#[$meta:meta])* $name:ident {
1572 $($(#[$variant_meta:meta])* $variant:ident ($variant_name: literal)),*,
1573 }) => {
1574 $(#[$meta])*
1575 pub enum $name {
1576 $($(#[$variant_meta])* $variant = ReferenceInitialSid::$variant as isize),*
1577 }
1578
1579 impl $name {
1580 pub fn all_variants() -> &'static [Self] {
1581 &[
1582 $($name::$variant),*
1583 ]
1584 }
1585
1586 pub fn name(&self) -> &'static str {
1587 match self {
1588 $($name::$variant => $variant_name),*
1589 }
1590 }
1591 }
1592 }
1593}
1594
1595initial_sid_enum! {
1596/// Initial Security Identifier (SID) values actually used by this implementation.
1597/// These must be present in the policy, for it to be valid.
1598#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
1599 InitialSid {
1600 // keep-sorted start
1601 Devnull("devnull"),
1602 File("file"),
1603 Kernel("kernel"),
1604 Security("security"),
1605 Unlabeled("unlabeled"),
1606 // keep-sorted end
1607 }
1608}
1609
1610/// A borrowed byte slice that contains no `NUL` characters by truncating the input slice at the
1611/// first `NUL` (if any) upon construction.
1612#[derive(Clone, Copy, Debug, PartialEq)]
1613pub struct NullessByteStr<'a>(&'a [u8]);
1614
1615impl<'a> NullessByteStr<'a> {
1616 /// Returns a non-null-terminated representation of the security context string.
1617 pub fn as_bytes(&self) -> &[u8] {
1618 &self.0
1619 }
1620}
1621
1622impl<'a, S: AsRef<[u8]> + ?Sized> From<&'a S> for NullessByteStr<'a> {
1623 /// Any `AsRef<[u8]>` can be processed into a [`NullessByteStr`]. The [`NullessByteStr`] will
1624 /// retain everything up to (but not including) a null character, or else the complete byte
1625 /// string.
1626 fn from(s: &'a S) -> Self {
1627 let value = s.as_ref();
1628 match value.iter().position(|c| *c == 0) {
1629 Some(end) => Self(&value[..end]),
1630 None => Self(value),
1631 }
1632 }
1633}
1634
1635#[derive(Clone, Debug, PartialEq)]
1636pub struct FileSystemMountSids {
1637 pub context: Option<SecurityId>,
1638 pub fs_context: Option<SecurityId>,
1639 pub def_context: Option<SecurityId>,
1640 pub root_context: Option<SecurityId>,
1641}
1642
1643#[derive(Clone, Debug, PartialEq)]
1644pub struct FileSystemLabel {
1645 pub sid: SecurityId,
1646 pub scheme: FileSystemLabelingScheme,
1647 // Sids obtained by parsing the mount options of the FileSystem.
1648 pub mount_sids: FileSystemMountSids,
1649}
1650
1651#[derive(Clone, Debug, PartialEq)]
1652pub enum FileSystemLabelingScheme {
1653 /// This filesystem was mounted with "context=".
1654 Mountpoint { sid: SecurityId },
1655 /// This filesystem has an "fs_use_xattr", "fs_use_task", or "fs_use_trans" entry in the
1656 /// policy. If the `fs_use_type` is "fs_use_xattr" then the `default_sid` specifies the SID
1657 /// with which to label `FsNode`s of files that do not have the "security.selinux" xattr.
1658 FsUse { fs_use_type: FsUseType, default_sid: SecurityId },
1659 /// This filesystem has one or more "genfscon" statements associated with it in the policy.
1660 GenFsCon,
1661}
1662
1663/// SELinux security context-related filesystem mount options. These options are documented in the
1664/// `context=context, fscontext=context, defcontext=context, and rootcontext=context` section of
1665/// the `mount(8)` manpage.
1666#[derive(Clone, Debug, Default, PartialEq)]
1667pub struct FileSystemMountOptions {
1668 /// Specifies the effective security context to use for all nodes in the filesystem, and the
1669 /// filesystem itself. If the filesystem already contains security attributes then these are
1670 /// ignored. May not be combined with any of the other options.
1671 pub context: Option<Vec<u8>>,
1672 /// Specifies an effective security context to use for un-labeled nodes in the filesystem,
1673 /// rather than falling-back to the policy-defined "file" context.
1674 pub def_context: Option<Vec<u8>>,
1675 /// The value of the `fscontext=[security-context]` mount option. This option is used to
1676 /// label the filesystem (superblock) itself.
1677 pub fs_context: Option<Vec<u8>>,
1678 /// The value of the `rootcontext=[security-context]` mount option. This option is used to
1679 /// (re)label the inode located at the filesystem mountpoint.
1680 pub root_context: Option<Vec<u8>>,
1681}
1682
1683/// Status information parameter for the [`SeLinuxStatusPublisher`] interface.
1684pub struct SeLinuxStatus {
1685 /// SELinux-wide enforcing vs. permissive mode bit.
1686 pub is_enforcing: bool,
1687 /// Number of times the policy has been changed since SELinux started.
1688 pub change_count: u32,
1689 /// Bit indicating whether operations unknown SELinux abstractions will be denied.
1690 pub deny_unknown: bool,
1691}
1692
1693/// Interface for security server to interact with selinuxfs status file.
1694pub trait SeLinuxStatusPublisher: Send + Sync {
1695 /// Sets the value part of the associated selinuxfs status file.
1696 fn set_status(&mut self, policy_status: SeLinuxStatus);
1697}
1698
1699/// Reference policy capability Ids.
1700#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1701pub enum PolicyCap {
1702 NetworkPeerControls = 0,
1703 OpenPerms = 1,
1704 ExtendedSocketClass = 2,
1705 AlwaysCheckNetwork = 3,
1706 CgroupSeclabel = 4,
1707 NnpNosuidTransition = 5,
1708 GenfsSeclabelSymlinks = 6,
1709 IoctlSkipCloexec = 7,
1710 UserspaceInitialContext = 8,
1711 NetlinkXperm = 9,
1712 NetifWildcard = 10,
1713 GenfsSeclabelWildcard = 11,
1714 FunctionfsSeclabel = 12,
1715 MemfdClass = 13,
1716}
1717
1718impl PolicyCap {
1719 pub fn all_values() -> &'static [Self] {
1720 &[
1721 Self::NetworkPeerControls,
1722 Self::OpenPerms,
1723 Self::ExtendedSocketClass,
1724 Self::AlwaysCheckNetwork,
1725 Self::CgroupSeclabel,
1726 Self::NnpNosuidTransition,
1727 Self::GenfsSeclabelSymlinks,
1728 Self::IoctlSkipCloexec,
1729 Self::UserspaceInitialContext,
1730 Self::NetlinkXperm,
1731 Self::NetifWildcard,
1732 Self::GenfsSeclabelWildcard,
1733 Self::FunctionfsSeclabel,
1734 Self::MemfdClass,
1735 ]
1736 }
1737
1738 pub fn name(&self) -> &str {
1739 match self {
1740 Self::NetworkPeerControls => "network_peer_controls",
1741 Self::OpenPerms => "open_perms",
1742 Self::ExtendedSocketClass => "extended_socket_class",
1743 Self::AlwaysCheckNetwork => "always_check_network",
1744 Self::CgroupSeclabel => "cgroup_seclabel",
1745 Self::NnpNosuidTransition => "nnp_nosuid_transition",
1746 Self::GenfsSeclabelSymlinks => "genfs_seclabel_symlinks",
1747 Self::IoctlSkipCloexec => "ioctl_skip_cloexec",
1748 Self::UserspaceInitialContext => "userspace_initial_context",
1749 Self::NetlinkXperm => "netlink_xperm",
1750 Self::NetifWildcard => "netif_wildcard",
1751 Self::GenfsSeclabelWildcard => "genfs_seclabel_wildcard",
1752 Self::FunctionfsSeclabel => "functionfs_seclabel",
1753 Self::MemfdClass => "memfd_class",
1754 }
1755 }
1756
1757 pub fn by_name(name: &str) -> Option<Self> {
1758 Self::all_values().iter().find(|x| x.name() == name).copied()
1759 }
1760}
1761
1762#[cfg(test)]
1763mod tests {
1764 use super::*;
1765
1766 #[test]
1767 fn object_class_permissions() {
1768 let test_class_id = ClassId::new(NonZeroU32::new(20).unwrap());
1769 assert_eq!(ObjectClass::ClassId(test_class_id), test_class_id.into());
1770 for variant in ProcessPermission::all_variants() {
1771 assert_eq!(KernelClass::Process, variant.class());
1772 assert_eq!("process", variant.class().name());
1773 let permission: KernelPermission = variant.clone().into();
1774 assert_eq!(KernelPermission::Process(variant.clone()), permission);
1775 assert_eq!(ObjectClass::Kernel(KernelClass::Process), variant.class().into());
1776 }
1777 }
1778
1779 #[test]
1780 fn policy_capabilities() {
1781 for capability in PolicyCap::all_values() {
1782 assert_eq!(Some(*capability), PolicyCap::by_name(capability.name()));
1783 }
1784 }
1785
1786 #[test]
1787 fn nulless_byte_str_equivalence() {
1788 let unterminated: NullessByteStr<'_> = b"u:object_r:test_valid_t:s0".into();
1789 let nul_terminated: NullessByteStr<'_> = b"u:object_r:test_valid_t:s0\0".into();
1790 let nul_containing: NullessByteStr<'_> =
1791 b"u:object_r:test_valid_t:s0\0IGNORE THIS\0!\0".into();
1792
1793 for context in [nul_terminated, nul_containing] {
1794 assert_eq!(unterminated, context);
1795 assert_eq!(unterminated.as_bytes(), context.as_bytes());
1796 }
1797 }
1798}