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