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