selinux/kernel_permissions.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
5use crate::policy::AccessVector;
6use paste::paste;
7use strum_macros::VariantArray;
8
9/// Declares an `enum` with a `name()` method that returns the name for the given variant.
10macro_rules! named_enum {
11 ($(#[$meta:meta])* $name:ident {
12 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
13 }) => {
14 $(#[$meta])*
15 pub enum $name {
16 $($(#[$variant_meta])* $variant,)*
17 }
18
19 impl $name {
20 pub fn name(&self) -> &'static str {
21 match self {
22 $($name::$variant => $variant_name,)*
23 }
24 }
25 }
26 }
27}
28
29/// Declares an `enum` with the specified subset of values from an existing enum.
30macro_rules! subset_enum {
31 ($(#[$meta:meta])* $name:ident from $existing_enum:ident {
32 $($(#[$variant_meta:meta])* $variant:ident,)*
33 }) => {
34 $(#[$meta])*
35 pub enum $name {
36 $($(#[$variant_meta])* $variant = $existing_enum::$variant as isize,)*
37 }
38
39 impl From<$name> for $existing_enum {
40 fn from(other: $name) -> Self {
41 match other {
42 $($name::$variant => Self::$variant,)*
43 }
44 }
45 }
46 }
47}
48
49macro_rules! declare_kernel_classes {
50 ($(#[$meta:meta])* {
51 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
52 }) => {
53 named_enum! {
54 #[derive(VariantArray, zerocopy::IntoBytes, zerocopy::Immutable)]
55 $(#[$meta])* KernelClass {
56 $($(#[$variant_meta])* $variant ($variant_name),)*
57 }
58 }
59
60 paste! {
61 $(#[$meta])*
62 pub enum KernelPermission {
63 $($(#[$variant_meta])* $variant([<$variant Permission>]),)*
64 }
65
66 $(impl From<[<$variant Permission>]> for KernelPermission {
67 fn from(v: [<$variant Permission>]) -> Self {
68 Self::$variant(v)
69 }
70 }
71 )*
72
73 impl ClassPermission for KernelPermission {
74 fn class(&self) -> KernelClass {
75 match self {
76 $(KernelPermission::$variant(_) => KernelClass::$variant),*
77 }
78 }
79 fn id(&self) -> u8 {
80 match self {
81 $(KernelPermission::$variant(v) => v.id()),*
82 }
83 }
84 }
85
86 impl KernelPermission {
87 pub fn name(&self) -> &'static str {
88 match self {
89 $(KernelPermission::$variant(v) => v.name()),*
90 }
91 }
92
93 pub fn all_variants() -> impl Iterator<Item = Self> {
94 let iter = [].iter().map(Clone::clone);
95 $(
96 let iter = iter.chain([<$variant Permission>]::PERMISSIONS.iter().map(Clone::clone));
97 )*
98 iter
99 }
100 }
101
102 impl KernelClass {
103 pub const fn permissions(&self) -> &'static [KernelPermission] {
104 match *self {
105 $(KernelClass::$variant => [<$variant Permission>]::PERMISSIONS,)*
106 }
107 }
108 }
109 }
110 }
111}
112
113declare_kernel_classes! {
114 /// A well-known class in SELinux policy that has a particular meaning in policy enforcement
115 /// hooks.
116 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
117 #[repr(u32)]
118 {
119 // keep-sorted start
120 /// The SELinux "anon_inode" object class.
121 AnonFsNode("anon_inode"),
122 /// The SELinux "binder" object class.
123 Binder("binder"),
124 /// The SELinux "blk_file" object class.
125 BlkFile("blk_file"),
126 /// The SELinux "bpf" object class.
127 Bpf("bpf"),
128 /// The SELinux "capability" object class.
129 Capability("capability"),
130 /// The SELinux "capability2" object class.
131 Capability2("capability2"),
132 /// The SELinux "chr_file" object class.
133 ChrFile("chr_file"),
134 /// The SELinux "dir" object class.
135 Dir("dir"),
136 /// The SELinux "fd" object class.
137 Fd("fd"),
138 /// The SELinux "fifo_file" object class.
139 FifoFile("fifo_file"),
140 /// The SELinux "file" object class.
141 File("file"),
142 /// The SELinux "filesystem" object class.
143 FileSystem("filesystem"),
144 /// "icmp_socket" class enabled via the "extended_socket_class" policy capability.
145 IcmpSocket("icmp_socket"),
146 /// The SELinux "key_socket" object class.
147 KeySocket("key_socket"),
148 /// The SELinux "lnk_file" object class.
149 LnkFile("lnk_file"),
150 /// The SELinux "memfd_file" object class.
151 MemFdFile("memfd_file"),
152 /// The SELinux "netlink_audit_socket" object class.
153 NetlinkAuditSocket("netlink_audit_socket"),
154 /// The SELinux "netlink_connector_socket" object class.
155 NetlinkConnectorSocket("netlink_connector_socket"),
156 /// The SELinux "netlink_crypto_socket" object class.
157 NetlinkCryptoSocket("netlink_crypto_socket"),
158 /// The SELinux "netlink_dnrt_socket" object class.
159 NetlinkDnrtSocket("netlink_dnrt_socket"),
160 /// The SELinux "netlink_fib_lookup_socket" object class.
161 NetlinkFibLookupSocket("netlink_fib_lookup_socket"),
162 /// The SELinux "netlink_firewall_socket" object class.
163 NetlinkFirewallSocket("netlink_firewall_socket"),
164 /// The SELinux "netlink_generic_socket" object class.
165 NetlinkGenericSocket("netlink_generic_socket"),
166 /// The SELinux "netlink_ip6fw_socket" object class.
167 NetlinkIp6FwSocket("netlink_ip6fw_socket"),
168 /// The SELinux "netlink_iscsi_socket" object class.
169 NetlinkIscsiSocket("netlink_iscsi_socket"),
170 /// The SELinux "netlink_kobject_uevent_socket" object class.
171 NetlinkKobjectUeventSocket("netlink_kobject_uevent_socket"),
172 /// The SELinux "netlink_netfilter_socket" object class.
173 NetlinkNetfilterSocket("netlink_netfilter_socket"),
174 /// The SELinux "netlink_nflog_socket" object class.
175 NetlinkNflogSocket("netlink_nflog_socket"),
176 /// The SELinux "netlink_rdma_socket" object class.
177 NetlinkRdmaSocket("netlink_rdma_socket"),
178 /// The SELinux "netlink_route_socket" object class.
179 NetlinkRouteSocket("netlink_route_socket"),
180 /// The SELinux "netlink_scsitransport_socket" object class.
181 NetlinkScsitransportSocket("netlink_scsitransport_socket"),
182 /// The SELinux "netlink_selinux_socket" object class.
183 NetlinkSelinuxSocket("netlink_selinux_socket"),
184 /// The SELinux "netlink_socket" object class.
185 NetlinkSocket("netlink_socket"),
186 /// The SELinux "netlink_tcpdiag_socket" object class.
187 NetlinkTcpDiagSocket("netlink_tcpdiag_socket"),
188 /// The SELinux "netlink_xfrm_socket" object class.
189 NetlinkXfrmSocket("netlink_xfrm_socket"),
190 /// The SELinux "packet_socket" object class.
191 PacketSocket("packet_socket"),
192 /// The SELinux "perf_event" object class.
193 PerfEvent("perf_event"),
194 /// The SELinux "process" object class.
195 Process("process"),
196 /// The SELinux "process2" object class.
197 Process2("process2"),
198 /// The SELinux "qipcrtr_socket" object class.
199 QipcrtrSocket("qipcrtr_socket"),
200 /// The SELinux "rawip_socket" object class.
201 RawIpSocket("rawip_socket"),
202 /// "sctp_socket" class enabled via the "extended_socket_class" policy capability.
203 SctpSocket("sctp_socket"),
204 /// The SELinux "security" object class.
205 Security("security"),
206 /// The SELinux "sock_file" object class.
207 SockFile("sock_file"),
208 /// The SELinux "socket" object class.
209 Socket("socket"),
210 /// The SELinux "system" object class.
211 System("system"),
212 /// The SELinux "tcp_socket" object class.
213 TcpSocket("tcp_socket"),
214 /// The SELinux "tun_socket" object class.
215 TunSocket("tun_socket"),
216 /// The SELinux "udp_socket" object class.
217 UdpSocket("udp_socket"),
218 /// The SELinux "unix_dgram_socket" object class.
219 UnixDgramSocket("unix_dgram_socket"),
220 /// The SELinux "unix_stream_socket" object class.
221 UnixStreamSocket("unix_stream_socket"),
222 /// "vsock_socket" class enabled via the "extended_socket_class" policy capability.
223 VsockSocket("vsock_socket"),
224 // keep-sorted end
225 }
226}
227
228impl From<FsNodeClass> for KernelClass {
229 fn from(class: FsNodeClass) -> Self {
230 match class {
231 FsNodeClass::File(file_class) => file_class.into(),
232 FsNodeClass::Socket(sock_class) => sock_class.into(),
233 }
234 }
235}
236pub trait ForClass<T> {
237 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
238 /// This is used to allow hooks to resolve e.g. common "sys_nice" permission access based on the
239 /// "allow" rules for the correct target object class.
240 fn for_class(&self, class: T) -> KernelPermission;
241}
242
243subset_enum! {
244 /// Covers the set of classes that inherit from the common "cap" symbol (e.g. "capability" for
245 /// now and "cap_userns" after Starnix gains user namespacing support).
246 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
247 CapClass from KernelClass {
248 // keep-sorted start
249 /// The SELinux "capability" object class.
250 Capability,
251 // keep-sorted end
252 }
253}
254
255subset_enum! {
256 /// Covers the set of classes that inherit from the common "cap2" symbol (e.g. "capability2" for
257 /// now and "cap2_userns" after Starnix gains user namespacing support).
258 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
259 Cap2Class from KernelClass {
260 // keep-sorted start
261 /// The SELinux "capability2" object class.
262 Capability2,
263 // keep-sorted end
264 }
265}
266
267subset_enum! {
268 /// A well-known file-like class in SELinux policy that has a particular meaning in policy
269 /// enforcement hooks.
270 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
271 FileClass from KernelClass {
272 // keep-sorted start
273 /// The SELinux "anon_inode" object class.
274 AnonFsNode,
275 /// The SELinux "blk_file" object class.
276 BlkFile,
277 /// The SELinux "chr_file" object class.
278 ChrFile,
279 /// The SELinux "dir" object class.
280 Dir,
281 /// The SELinux "fifo_file" object class.
282 FifoFile,
283 /// The SELinux "file" object class.
284 File,
285 /// The SELinux "lnk_file" object class.
286 LnkFile,
287 /// The SELinux "memfd_file" object class.
288 MemFdFile,
289 /// The SELinux "sock_file" object class.
290 SockFile,
291 // keep-sorted end
292 }
293}
294
295subset_enum! {
296 /// Distinguishes socket-like kernel object classes defined in SELinux policy.
297 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
298 SocketClass from KernelClass {
299 // keep-sorted start
300 IcmpSocket,
301 KeySocket,
302 NetlinkAuditSocket,
303 NetlinkConnectorSocket,
304 NetlinkCryptoSocket,
305 NetlinkDnrtSocket,
306 NetlinkFibLookupSocket,
307 NetlinkFirewallSocket,
308 NetlinkGenericSocket,
309 NetlinkIp6FwSocket,
310 NetlinkIscsiSocket,
311 NetlinkKobjectUeventSocket,
312 NetlinkNetfilterSocket,
313 NetlinkNflogSocket,
314 NetlinkRdmaSocket,
315 NetlinkRouteSocket,
316 NetlinkScsitransportSocket,
317 NetlinkSelinuxSocket,
318 NetlinkSocket,
319 NetlinkTcpDiagSocket,
320 NetlinkXfrmSocket,
321 PacketSocket,
322 QipcrtrSocket,
323 RawIpSocket,
324 SctpSocket,
325 /// Generic socket class applied to all socket-like objects for which no more specific
326 /// class is defined.
327 Socket,
328 TcpSocket,
329 TunSocket,
330 UdpSocket,
331 UnixDgramSocket,
332 UnixStreamSocket,
333 VsockSocket,
334 // keep-sorted end
335 }
336}
337
338/// Container for a security class that could be associated with a [`crate::vfs::FsNode`], to allow
339/// permissions common to both file-like and socket-like classes to be generated easily by hooks.
340#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
341pub enum FsNodeClass {
342 File(FileClass),
343 Socket(SocketClass),
344}
345
346impl From<FileClass> for FsNodeClass {
347 fn from(file_class: FileClass) -> Self {
348 FsNodeClass::File(file_class)
349 }
350}
351
352impl From<SocketClass> for FsNodeClass {
353 fn from(sock_class: SocketClass) -> Self {
354 FsNodeClass::Socket(sock_class)
355 }
356}
357
358pub trait ClassPermission {
359 fn class(&self) -> KernelClass;
360 fn id(&self) -> u8;
361 fn as_access_vector(&self) -> AccessVector {
362 AccessVector::from(1u32 << self.id())
363 }
364}
365
366impl<T: Into<KernelClass>> ForClass<T> for KernelPermission {
367 fn for_class(&self, class: T) -> KernelPermission {
368 assert_eq!(self.class(), class.into());
369 *self
370 }
371}
372
373/// Helper used to declare the set of named permissions associated with an SELinux class.
374/// The `ClassType` trait is implemented on the declared `enum`, enabling values to be wrapped into
375/// the generic `KernelPermission` container.
376/// If an "extends" type is specified then a `Common` enum case is added, encapsulating the values
377/// of that underlying permission type. This is used to represent e.g. SELinux "dir" class deriving
378/// a basic set of permissions from the common "file" symbol.
379macro_rules! class_permission_enum {
380 ($(#[$meta:meta])* $name:ident for $kernel_class:ident {
381 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
382 }) => {
383 named_enum! {
384 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
385 #[repr(u8)]
386 $(#[$meta])* $name {
387 $($(#[$variant_meta])* $variant ($variant_name),)*
388 }
389 }
390
391
392 impl ClassPermission for $name {
393 fn class(&self) -> KernelClass {
394 KernelClass::$kernel_class
395 }
396 fn id(&self) -> u8 {
397 *self as u8
398 }
399 }
400
401 impl $name {
402 pub const PERMISSIONS: &[KernelPermission] = &[$(KernelPermission::$kernel_class(Self::$variant)),*];
403 }
404 };
405 ($(#[$meta:meta])* $name:ident {
406 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
407 }) => {
408 named_enum! {
409 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
410 #[repr(u8)]
411 $(#[$meta])* $name {
412 $($(#[$variant_meta])* $variant ($variant_name),)*
413 }
414 }
415 }
416}
417
418/// Permissions common to all cap-like object classes (e.g. "capability" for now and
419/// "cap_userns" after Starnix gains user namespacing support). These are combined with a
420/// specific `CapabilityClass` by policy enforcement hooks, to obtain class-affine permission
421/// values to check.
422macro_rules! cap_class_permission_enum {
423 ($(#[$meta:meta])* $name:ident $(for $kernel_class:ident)? {
424 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
425 }) => {
426 class_permission_enum! {
427 $(#[$meta])* $name $(for $kernel_class)? {
428 // keep-sorted start
429
430 AuditControl("audit_control"),
431 AuditWrite("audit_write"),
432 Chown("chown"),
433 DacOverride("dac_override"),
434 DacReadSearch("dac_read_search"),
435 Fowner("fowner"),
436 Fsetid("fsetid"),
437 IpcLock("ipc_lock"),
438 IpcOwner("ipc_owner"),
439 Kill("kill"),
440 Lease("lease"),
441 LinuxImmutable("linux_immutable"),
442 Mknod("mknod"),
443 NetAdmin("net_admin"),
444 NetBindService("net_bind_service"),
445 NetBroadcast("net_broadcast"),
446 NetRaw("net_raw"),
447 Setfcap("setfcap"),
448 Setgid("setgid"),
449 Setpcap("setpcap"),
450 Setuid("setuid"),
451 SysAdmin("sys_admin"),
452 SysBoot("sys_boot"),
453 SysChroot("sys_chroot"),
454 SysModule("sys_module"),
455 SysNice("sys_nice"),
456 SysPacct("sys_pacct"),
457 SysPtrace("sys_ptrace"),
458 SysRawio("sys_rawio"),
459 SysResource("sys_resource"),
460 SysTime("sys_time"),
461 SysTtyConfig("sys_tty_config"),
462
463 // keep-sorted end
464
465 // Additional permissions specific to the derived class.
466 $($(#[$variant_meta])* $variant ($variant_name),)*
467 }
468 }
469 }
470}
471
472cap_class_permission_enum! {
473 CapabilityPermission for Capability {}
474}
475
476cap_class_permission_enum! {
477 CommonCapPermission {}
478}
479
480impl ForClass<CapClass> for CommonCapPermission {
481 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
482 /// This is used to allow hooks to resolve e.g. common "sys_nice" permission access based on the
483 /// "allow" rules for the correct target object class.
484 fn for_class(&self, class: CapClass) -> KernelPermission {
485 match class {
486 CapClass::Capability => CapabilityPermission::from(*self).into(),
487 }
488 }
489}
490
491impl From<CommonCapPermission> for CapabilityPermission {
492 fn from(other: CommonCapPermission) -> Self {
493 // SAFETY: CapabilityPermission's values include all of CommonCapPermission.
494 unsafe { std::mem::transmute(other) }
495 }
496}
497
498/// Permissions common to all cap2-like object classes (e.g. "capability2" for now and
499/// "cap2_userns" after Starnix gains user namespacing support). These are combined with a
500/// specific `Capability2Class` by policy enforcement hooks, to obtain class-affine permission
501/// values to check.
502macro_rules! cap2_class_permission_enum {
503 ($(#[$meta:meta])* $name:ident $(for $kernel_class:ident)? {
504 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
505 }) => {
506 class_permission_enum! {
507 $(#[$meta])* $ name $(for $kernel_class)? {
508 // keep-sorted start
509
510 AuditRead("audit_read"),
511 BlockSuspend("block_suspend"),
512 Bpf("bpf"),
513 MacAdmin("mac_admin"),
514 MacOverride("mac_override"),
515 Perfmon("perfmon"),
516 Syslog("syslog"),
517 WakeAlarm("wake_alarm"),
518
519 // keep-sorted end
520
521 // Additional permissions specific to the derived class.
522 $($(#[$variant_meta])* $variant ($variant_name),)*
523 }
524 }
525 }
526}
527
528cap2_class_permission_enum! {
529 /// Permissions for the kernel "capability" class.
530 Capability2Permission for Capability2 {}
531}
532
533cap2_class_permission_enum! {
534 /// Common symbol inherited by "capability2" and "capuser2" classes.
535 CommonCap2Permission {}
536}
537
538impl ForClass<Cap2Class> for CommonCap2Permission {
539 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
540 /// This is used to allow hooks to resolve e.g. common "mac_admin" permission access based on
541 /// the "allow" rules for the correct target object class.
542 fn for_class(&self, class: Cap2Class) -> KernelPermission {
543 match class {
544 Cap2Class::Capability2 => Capability2Permission::from(*self).into(),
545 }
546 }
547}
548
549impl From<CommonCap2Permission> for Capability2Permission {
550 fn from(other: CommonCap2Permission) -> Self {
551 // SAFETY: Capability2Permission's values include all of CommonCap2Permission.
552 unsafe { std::mem::transmute(other) }
553 }
554}
555
556/// Permissions meaningful for all [`crate::vfs::FsNode`]s, whether file- or socket-like.
557///
558/// This extra layer of common permissions is not reflected in the hierarchy defined by the
559/// SELinux Reference Policy. Because even common permissions are mapped per-class, by name, to
560/// the policy equivalents, the implementation and policy notions of common permissions need not
561/// be identical.
562macro_rules! fs_node_class_permission_enum {
563 ($(#[$meta:meta])* $name:ident $(for $kernel_class:ident)? {
564 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
565 }) => {
566 class_permission_enum! {
567 $(#[$meta])* $name $(for $kernel_class)? {
568 // keep-sorted start
569 /// Permission to append to a file or socket.
570 Append("append"),
571 /// Pseudo-permission used in `dontaudit` access-rules to allow access checks to be made
572 /// between specific sources & targets without generating audit logs.
573 AuditAccess("audit_access"),
574 /// Permission to create a file or socket.
575 Create("create"),
576 /// Permission to query attributes, including uid, gid and extended attributes.
577 GetAttr("getattr"),
578 /// Permission to execute ioctls on the file or socket.
579 Ioctl("ioctl"),
580 /// Permission to set and unset file or socket locks.
581 Lock("lock"),
582 /// Permission to map a file.
583 Map("map"),
584 /// Permission to read content from a file or socket, as well as reading or following links.
585 Read("read"),
586 /// Permission checked against the existing label when updating a node's security label.
587 RelabelFrom("relabelfrom"),
588 /// Permission checked against the new label when updating a node's security label.
589 RelabelTo("relabelto"),
590 /// Permission to modify attributes, including uid, gid and extended attributes.
591 SetAttr("setattr"),
592 /// Permission to write contents to the file or socket.
593 Write("write"),
594 // keep-sorted end
595
596 // Additional permissions specific to the derived class.
597 $($(#[$variant_meta])* $variant ($variant_name),)*
598 }
599 }
600 }
601}
602
603fs_node_class_permission_enum! {
604 CommonFsNodePermission {}
605}
606
607impl<T: Into<FsNodeClass>> ForClass<T> for CommonFsNodePermission {
608 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
609 /// This is used to allow hooks to resolve e.g. common "read" permission access based on the
610 /// "allow" rules for the correct target object class.
611 fn for_class(&self, class: T) -> KernelPermission {
612 match class.into() {
613 FsNodeClass::File(file_class) => {
614 CommonFilePermission::from(*self).for_class(file_class)
615 }
616 FsNodeClass::Socket(sock_class) => {
617 CommonSocketPermission::from(*self).for_class(sock_class)
618 }
619 }
620 }
621}
622
623impl From<CommonFsNodePermission> for CommonFilePermission {
624 fn from(other: CommonFsNodePermission) -> Self {
625 // SAFETY: CommonFilePermission's values include all of CommonFsNodePermission.
626 unsafe { std::mem::transmute(other) }
627 }
628}
629
630impl From<CommonFsNodePermission> for CommonSocketPermission {
631 fn from(other: CommonFsNodePermission) -> Self {
632 // SAFETY: CommonSocketPermission's values include all of CommonFsNodePermission.
633 unsafe { std::mem::transmute(other) }
634 }
635}
636
637/// Permissions common to all socket-like object classes. These are combined with a specific
638/// `SocketClass` by policy enforcement hooks, to obtain class-affine permission values.
639macro_rules! socket_class_permission_enum {
640 ($(#[$meta:meta])* $name:ident $(for $kernel_class:ident)? {
641 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
642 }) => {
643 fs_node_class_permission_enum! {
644 $(#[$meta])* $name $(for $kernel_class)? {
645 // keep-sorted start
646 /// Permission to accept a connection.
647 Accept("accept"),
648 /// Permission to bind to a name.
649 Bind("bind"),
650 /// Permission to initiate a connection.
651 Connect("connect"),
652 /// Permission to get socket options.
653 GetOpt("getopt"),
654 /// Permission to listen for connections.
655 Listen("listen"),
656 /// Permission to send datagrams to the socket.
657 SendTo("sendto"),
658 /// Permission to set socket options.
659 SetOpt("setopt"),
660 /// Permission to terminate connection.
661 Shutdown("shutdown"),
662 // keep-sorted end
663
664 // Additional permissions specific to the derived class.
665 $($(#[$variant_meta])* $variant ($variant_name),)*
666 }
667 }
668
669 $(impl From<CommonSocketPermission> for $name {
670 fn from(other: CommonSocketPermission) -> Self {
671 // SAFETY: $name's values include all of CommonSocketPermission.
672 let result: $name = unsafe { std::mem::transmute(other) };
673 debug_assert_eq!(result.class(), KernelClass::$kernel_class);
674 result
675 }
676 })?
677 }
678}
679
680socket_class_permission_enum! {
681 CommonSocketPermission {}
682}
683
684impl ForClass<SocketClass> for CommonSocketPermission {
685 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
686 /// This is used to allow hooks to resolve e.g. common "read" permission access based on the
687 /// "allow" rules for the correct target object class.
688 fn for_class(&self, class: SocketClass) -> KernelPermission {
689 match class {
690 SocketClass::KeySocket => KeySocketPermission::from(*self).into(),
691 SocketClass::NetlinkSocket => NetlinkSocketPermission::from(*self).into(),
692 SocketClass::NetlinkAuditSocket => NetlinkAuditSocketPermission::from(*self).into(),
693 SocketClass::NetlinkConnectorSocket => {
694 NetlinkConnectorSocketPermission::from(*self).into()
695 }
696 SocketClass::NetlinkCryptoSocket => NetlinkCryptoSocketPermission::from(*self).into(),
697 SocketClass::NetlinkDnrtSocket => NetlinkDnrtSocketPermission::from(*self).into(),
698 SocketClass::NetlinkFibLookupSocket => {
699 NetlinkFibLookupSocketPermission::from(*self).into()
700 }
701 SocketClass::NetlinkFirewallSocket => {
702 NetlinkFirewallSocketPermission::from(*self).into()
703 }
704 SocketClass::NetlinkGenericSocket => NetlinkGenericSocketPermission::from(*self).into(),
705 SocketClass::NetlinkIp6FwSocket => NetlinkIp6FwSocketPermission::from(*self).into(),
706 SocketClass::NetlinkIscsiSocket => NetlinkIscsiSocketPermission::from(*self).into(),
707 SocketClass::NetlinkKobjectUeventSocket => {
708 NetlinkKobjectUeventSocketPermission::from(*self).into()
709 }
710 SocketClass::NetlinkNetfilterSocket => {
711 NetlinkNetfilterSocketPermission::from(*self).into()
712 }
713 SocketClass::NetlinkNflogSocket => NetlinkNflogSocketPermission::from(*self).into(),
714 SocketClass::NetlinkRdmaSocket => NetlinkRdmaSocketPermission::from(*self).into(),
715 SocketClass::NetlinkRouteSocket => NetlinkRouteSocketPermission::from(*self).into(),
716 SocketClass::NetlinkScsitransportSocket => {
717 NetlinkScsitransportSocketPermission::from(*self).into()
718 }
719 SocketClass::NetlinkSelinuxSocket => NetlinkSelinuxSocketPermission::from(*self).into(),
720 SocketClass::NetlinkTcpDiagSocket => NetlinkTcpDiagSocketPermission::from(*self).into(),
721 SocketClass::NetlinkXfrmSocket => NetlinkXfrmSocketPermission::from(*self).into(),
722 SocketClass::PacketSocket => PacketSocketPermission::from(*self).into(),
723 SocketClass::QipcrtrSocket => QipcrtrSocketPermission::from(*self).into(),
724 SocketClass::RawIpSocket => RawIpSocketPermission::from(*self).into(),
725 SocketClass::SctpSocket => SctpSocketPermission::from(*self).into(),
726 SocketClass::Socket => SocketPermission::from(*self).into(),
727 SocketClass::TcpSocket => TcpSocketPermission::from(*self).into(),
728 SocketClass::TunSocket => TunSocketPermission::from(*self).into(),
729 SocketClass::UdpSocket => UdpSocketPermission::from(*self).into(),
730 SocketClass::UnixDgramSocket => UnixDgramSocketPermission::from(*self).into(),
731 SocketClass::UnixStreamSocket => UnixStreamSocketPermission::from(*self).into(),
732 SocketClass::VsockSocket => VsockSocketPermission::from(*self).into(),
733 SocketClass::IcmpSocket => IcmpSocketPermission::from(*self).into(),
734 }
735 }
736}
737
738socket_class_permission_enum! {
739 KeySocketPermission for KeySocket {
740 }
741}
742
743socket_class_permission_enum! {
744 NetlinkSocketPermission for NetlinkSocket {}
745}
746
747socket_class_permission_enum! {
748 NetlinkRouteSocketPermission for NetlinkRouteSocket {
749 // keep-sorted start
750 /// Permission for nlmsg xperms.
751 Nlmsg("nlmsg"),
752 /// Permission to read the kernel neighbor table.
753 NlmsgGetNeigh("nlmsg_getneigh"),
754 /// Permission to read the kernel routing table.
755 NlmsgRead("nlmsg_read"),
756 /// Permission to read privileged netlink messages.
757 NlmsgReadPriv("nlmsg_readpriv"),
758 /// Permission to write to the kernel routing table.
759 NlmsgWrite("nlmsg_write"),
760 // keep-sorted end
761 }
762}
763
764socket_class_permission_enum! {
765 NetlinkFirewallSocketPermission for NetlinkFirewallSocket {
766 }
767}
768
769socket_class_permission_enum! {
770 NetlinkTcpDiagSocketPermission for NetlinkTcpDiagSocket {
771 // keep-sorted start
772 /// Permission for nlmsg xperms.
773 Nlmsg("nlmsg"),
774 /// Permission to request information about a protocol.
775 NlmsgRead("nlmsg_read"),
776 /// Permission to write netlink message.
777 NlmsgWrite("nlmsg_write"),
778 // keep-sorted end
779 }
780}
781
782socket_class_permission_enum! {
783 NetlinkNflogSocketPermission for NetlinkNflogSocket {
784 }
785}
786
787socket_class_permission_enum! {
788 NetlinkXfrmSocketPermission for NetlinkXfrmSocket {
789 // keep-sorted start
790 /// Permission for nlmsg xperms.
791 Nlmsg("nlmsg"),
792 /// Permission to get IPSec configuration information.
793 NlmsgRead("nlmsg_read"),
794 /// Permission to set IPSec configuration information.
795 NlmsgWrite("nlmsg_write"),
796 // keep-sorted end
797 }
798}
799
800socket_class_permission_enum! {
801 NetlinkSelinuxSocketPermission for NetlinkSelinuxSocket {
802 }
803}
804
805socket_class_permission_enum! {
806 NetlinkIscsiSocketPermission for NetlinkIscsiSocket {
807 }
808}
809
810socket_class_permission_enum! {
811 NetlinkAuditSocketPermission for NetlinkAuditSocket {
812 // keep-sorted start
813 /// Permission for nlmsg xperms.
814 Nlmsg("nlmsg"),
815 /// Permission to query status of audit service.
816 NlmsgRead("nlmsg_read"),
817 /// Permission to list auditing configuration rules.
818 NlmsgReadPriv("nlmsg_readpriv"),
819 /// Permission to send userspace audit messages to the audit service.
820 NlmsgRelay("nlmsg_relay"),
821 /// Permission to control TTY auditing.
822 NlmsgTtyAudit("nlmsg_tty_audit"),
823 /// Permission to update the audit service configuration.
824 NlmsgWrite("nlmsg_write"),
825 // keep-sorted end
826 }
827}
828
829socket_class_permission_enum! {
830 NetlinkFibLookupSocketPermission for NetlinkFibLookupSocket {
831 }
832}
833
834socket_class_permission_enum! {
835 NetlinkConnectorSocketPermission for NetlinkConnectorSocket {
836 }
837}
838
839socket_class_permission_enum! {
840 NetlinkNetfilterSocketPermission for NetlinkNetfilterSocket {
841 }
842}
843
844socket_class_permission_enum! {
845 NetlinkIp6FwSocketPermission for NetlinkIp6FwSocket {
846 }
847}
848
849socket_class_permission_enum! {
850 NetlinkDnrtSocketPermission for NetlinkDnrtSocket {
851 }
852}
853
854socket_class_permission_enum! {
855 NetlinkKobjectUeventSocketPermission for NetlinkKobjectUeventSocket {
856 }
857}
858
859socket_class_permission_enum! {
860 NetlinkGenericSocketPermission for NetlinkGenericSocket {
861 }
862}
863
864socket_class_permission_enum! {
865 NetlinkScsitransportSocketPermission for NetlinkScsitransportSocket {
866 }
867}
868
869socket_class_permission_enum! {
870 NetlinkRdmaSocketPermission for NetlinkRdmaSocket {
871 }
872}
873
874socket_class_permission_enum! {
875 NetlinkCryptoSocketPermission for NetlinkCryptoSocket {
876 }
877}
878
879socket_class_permission_enum! {
880 PacketSocketPermission for PacketSocket {
881 }
882}
883
884socket_class_permission_enum! {
885 QipcrtrSocketPermission for QipcrtrSocket {
886 }
887}
888
889socket_class_permission_enum! {
890 RawIpSocketPermission for RawIpSocket {
891 }
892}
893
894socket_class_permission_enum! {
895 SctpSocketPermission for SctpSocket {
896 // keep-sorted start
897 /// Permission to create an SCTP association.
898 Associate("associate"),
899 /// Permission to `connect()` or `connectx()` an SCTP socket.
900 NameConnect("name_connect"),
901 /// Permission to `bind()` or `bindx()` an SCTP socket.
902 NodeBind("node_bind"),
903 // keep-sorted end
904 }
905}
906
907socket_class_permission_enum! {
908 SocketPermission for Socket {
909 }
910}
911
912socket_class_permission_enum! {
913 TcpSocketPermission for TcpSocket {
914 }
915}
916
917socket_class_permission_enum! {
918 TunSocketPermission for TunSocket {
919 }
920}
921
922socket_class_permission_enum! {
923 UdpSocketPermission for UdpSocket {
924 }
925}
926
927socket_class_permission_enum! {
928 UnixStreamSocketPermission for UnixStreamSocket {
929 // keep-sorted start
930 /// Permission to connect a streaming Unix-domain socket.
931 ConnectTo("connectto"),
932 // keep-sorted end
933 }
934}
935
936socket_class_permission_enum! {
937 UnixDgramSocketPermission for UnixDgramSocket {
938 }
939}
940
941socket_class_permission_enum! {
942 VsockSocketPermission for VsockSocket {
943 }
944}
945
946socket_class_permission_enum! {
947 IcmpSocketPermission for IcmpSocket {
948 // keep-sorted start
949 /// Permission to `bind()` an ICMP socket.
950 NodeBind("node_bind"),
951 // keep-sorted end
952 }
953}
954
955/// Permissions common to all file-like object classes (e.g. "lnk_file", "dir"). These are
956/// combined with a specific `FileClass` by policy enforcement hooks, to obtain class-affine
957/// permission values to check.
958macro_rules! file_class_permission_enum {
959 ($(#[$meta:meta])* $name:ident $(for $kernel_class:ident)? {
960 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
961 }) => {
962 fs_node_class_permission_enum! {
963 $(#[$meta])* $name $(for $kernel_class)? {
964 // keep-sorted start
965
966 /// Permission to execute a file with domain transition.
967 Execute("execute"),
968 /// Permissions to create hard link.
969 Link("link"),
970 /// Permission to use as mount point; only useful for directories and files.
971 MountOn("mounton"),
972 /// Permission to open a file.
973 Open("open"),
974 /// Permission to rename a file.
975 Rename("rename"),
976 /// Permission to delete a file or remove a hard link.
977 Unlink("unlink"),
978 // keep-sorted end
979
980 // Additional permissions specific to the derived class.
981 $($(#[$variant_meta])* $variant ($variant_name),)*
982 }}
983
984 $(impl From<CommonFilePermission> for $name {
985 fn from(other: CommonFilePermission) -> Self {
986 // SAFETY: $name's values include all of CommonFilePermission.
987 let result: $name = unsafe { std::mem::transmute(other) };
988 debug_assert_eq!(result.class(), KernelClass::$kernel_class);
989 result
990 }
991 })?
992 }
993}
994
995file_class_permission_enum! {
996 CommonFilePermission {}
997}
998
999impl ForClass<FileClass> for CommonFilePermission {
1000 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
1001 /// This is used to allow hooks to resolve e.g. common "read" permission access based on the
1002 /// "allow" rules for the correct target object class.
1003 fn for_class(&self, class: FileClass) -> KernelPermission {
1004 match class {
1005 FileClass::AnonFsNode => AnonFsNodePermission::from(*self).into(),
1006 FileClass::BlkFile => BlkFilePermission::from(*self).into(),
1007 FileClass::ChrFile => ChrFilePermission::from(*self).into(),
1008 FileClass::Dir => DirPermission::from(*self).into(),
1009 FileClass::FifoFile => FifoFilePermission::from(*self).into(),
1010 FileClass::File => FilePermission::from(*self).into(),
1011 FileClass::LnkFile => LnkFilePermission::from(*self).into(),
1012 FileClass::SockFile => SockFilePermission::from(*self).into(),
1013 FileClass::MemFdFile => MemFdFilePermission::from(*self).into(),
1014 }
1015 }
1016}
1017
1018file_class_permission_enum! {
1019 AnonFsNodePermission for AnonFsNode {
1020 }
1021}
1022
1023class_permission_enum! {
1024 BinderPermission for Binder {
1025 // keep-sorted start
1026 /// Permission to perform a binder IPC to a given target process.
1027 Call("call"),
1028 /// Permission to use a Binder connection created with a different security context.
1029 Impersonate("impersonate"),
1030 /// Permission to set oneself as a context manager.
1031 SetContextMgr("set_context_mgr"),
1032 /// Permission to transfer Binder objects as part of a Binder transaction.
1033 Transfer("transfer"),
1034 // keep-sorted end
1035 }
1036}
1037
1038file_class_permission_enum! {
1039 BlkFilePermission for BlkFile {
1040 }
1041}
1042
1043file_class_permission_enum! {
1044 ChrFilePermission for ChrFile {
1045 }
1046}
1047
1048file_class_permission_enum! {
1049 DirPermission for Dir {
1050 // keep-sorted start
1051 /// Permission to add a file to the directory.
1052 AddName("add_name"),
1053 /// Permission to remove a directory.
1054 RemoveDir("rmdir"),
1055 /// Permission to remove an entry from a directory.
1056 RemoveName("remove_name"),
1057 /// Permission to change parent directory.
1058 Reparent("reparent"),
1059 /// Search access to the directory.
1060 Search("search"),
1061 // keep-sorted end
1062 }
1063}
1064
1065class_permission_enum! {
1066 FdPermission for Fd {
1067 // keep-sorted start
1068 /// Permission to use file descriptors copied/retained/inherited from another security
1069 /// context. This permission is generally used to control whether an `exec*()` call from a
1070 /// cloned process that retained a copy of the file descriptor table should succeed.
1071 Use("use"),
1072 // keep-sorted end
1073 }
1074}
1075
1076class_permission_enum! {
1077 BpfPermission for Bpf {
1078 // keep-sorted start
1079 /// Permission to create a map.
1080 MapCreate("map_create"),
1081 /// Permission to read from a map.
1082 MapRead("map_read"),
1083 /// Permission to write on a map.
1084 MapWrite("map_write"),
1085 /// Permission to load a program.
1086 ProgLoad("prog_load"),
1087 /// Permission to run a program.
1088 ProgRun("prog_run"),
1089 // keep-sorted end
1090 }
1091}
1092
1093class_permission_enum! {
1094 PerfEventPermission for PerfEvent {
1095 // keep-sorted start
1096 /// Permission to monitor the cpu.
1097 Cpu("cpu"),
1098 /// Permission to monitor the kernel.
1099 Kernel("kernel"),
1100 /// Permission to open a perf event.
1101 Open("open"),
1102 /// Permission to read a perf event.
1103 Read("read"),
1104 /// Permission to set tracepoints.
1105 Tracepoint("tracepoint"),
1106 /// Permission to write a perf event.
1107 Write("write"),
1108 // keep-sorted end
1109 }
1110}
1111
1112file_class_permission_enum! {
1113 FifoFilePermission for FifoFile {
1114 }
1115}
1116
1117file_class_permission_enum! {
1118 FilePermission for File {
1119 // keep-sorted start
1120 /// Permission to use a file as an entry point into the new domain on transition.
1121 Entrypoint("entrypoint"),
1122 /// Permission to use a file as an entry point to the calling domain without performing a
1123 /// transition.
1124 ExecuteNoTrans("execute_no_trans"),
1125 // keep-sorted end
1126 }
1127}
1128
1129class_permission_enum! {
1130 FileSystemPermission for FileSystem {
1131 // keep-sorted start
1132 /// Permission to associate a file to the filesystem.
1133 Associate("associate"),
1134 /// Permission to get filesystem attributes.
1135 GetAttr("getattr"),
1136 /// Permission mount a filesystem.
1137 Mount("mount"),
1138 /// Permission to remount a filesystem with different flags.
1139 Remount("remount"),
1140 /// Permission to unmount a filesystem.
1141 Unmount("unmount"),
1142 // keep-sorted end
1143 }
1144}
1145
1146file_class_permission_enum! {
1147 LnkFilePermission for LnkFile {
1148 }
1149}
1150
1151file_class_permission_enum! {
1152 MemFdFilePermission for MemFdFile {
1153 }
1154}
1155
1156file_class_permission_enum! {
1157 SockFilePermission for SockFile {
1158 }
1159}
1160
1161class_permission_enum! {
1162 ProcessPermission for Process {
1163 // keep-sorted start
1164 /// Permission to dynamically transition a process to a different security domain.
1165 DynTransition("dyntransition"),
1166 /// Permission to execute arbitrary code from the heap.
1167 ExecHeap("execheap"),
1168 /// Permission to execute arbitrary code from memory.
1169 ExecMem("execmem"),
1170 /// Permission to execute arbitrary code from the stack.
1171 ExecStack("execstack"),
1172 /// Permission to fork the current running process.
1173 Fork("fork"),
1174 /// Permission to get Linux capabilities of a process.
1175 GetCap("getcap"),
1176 /// Permission to get the process group ID.
1177 GetPgid("getpgid"),
1178 /// Permission to get the resource limits on a process.
1179 GetRlimit("getrlimit"),
1180 /// Permission to get scheduling policy currently applied to a process.
1181 GetSched("getsched"),
1182 /// Permission to get the session ID.
1183 GetSession("getsession"),
1184 /// Permission to exec into a new security domain without setting the AT_SECURE entry in the
1185 /// executable's auxiliary vector.
1186 NoAtSecure("noatsecure"),
1187 /// Permission to trace a process.
1188 Ptrace("ptrace"),
1189 /// Permission to inherit the parent process's resource limits on exec.
1190 RlimitInh("rlimitinh"),
1191 /// Permission to set Linux capabilities of a process.
1192 SetCap("setcap"),
1193 /// Permission to set the calling task's current Security Context.
1194 /// The "dyntransition" permission separately limits which Contexts "setcurrent" may be used to transition to.
1195 SetCurrent("setcurrent"),
1196 /// Permission to set the Security Context used by `exec()`.
1197 SetExec("setexec"),
1198 /// Permission to set the Security Context used when creating filesystem objects.
1199 SetFsCreate("setfscreate"),
1200 /// Permission to set the Security Context used when creating kernel keyrings.
1201 SetKeyCreate("setkeycreate"),
1202 /// Permission to set the process group ID.
1203 SetPgid("setpgid"),
1204 /// Permission to set the resource limits on a process.
1205 SetRlimit("setrlimit"),
1206 /// Permission to set scheduling policy for a process.
1207 SetSched("setsched"),
1208 /// Permission to set the Security Context used when creating new labeled sockets.
1209 SetSockCreate("setsockcreate"),
1210 /// Permission to share resources (e.g. FD table, address-space, etc) with a process.
1211 Share("share"),
1212 /// Permission to send SIGCHLD to a process.
1213 SigChld("sigchld"),
1214 /// Permission to inherit the parent process's signal state.
1215 SigInh("siginh"),
1216 /// Permission to send SIGKILL to a process.
1217 SigKill("sigkill"),
1218 /// Permission to send SIGSTOP to a process.
1219 SigStop("sigstop"),
1220 /// Permission to send a signal other than SIGKILL, SIGSTOP, or SIGCHLD to a process.
1221 Signal("signal"),
1222 /// Permission to transition to a different security domain.
1223 Transition("transition"),
1224 // keep-sorted end
1225 }
1226}
1227
1228class_permission_enum! {
1229 Process2Permission for Process2 {
1230 // keep-sorted start
1231 /// Permission to transition to an unbounded domain when no-new-privileges is set.
1232 NnpTransition("nnp_transition"),
1233 /// Permission to transition domain when executing from a no-SUID mounted filesystem.
1234 NosuidTransition("nosuid_transition"),
1235 // keep-sorted end
1236 }
1237}
1238
1239class_permission_enum! {
1240 SecurityPermission for Security {
1241 // keep-sorted start
1242 /// Permission to validate Security Context using the "context" API.
1243 CheckContext("check_context"),
1244 /// Permission to compute access vectors via the "access" API.
1245 ComputeAv("compute_av"),
1246 /// Permission to compute security contexts based on `type_transition` rules via "create".
1247 ComputeCreate("compute_create"),
1248 /// Permission to compute security contexts based on `type_member` rules via "member".
1249 ComputeMember("compute_member"),
1250 /// Permission to compute security contexts based on `type_change` rules via "relabel".
1251 ComputeRelabel("compute_relabel"),
1252 /// Permission to compute user decisions via "user".
1253 ComputeUser("compute_user"),
1254 /// Permission to load a new binary policy into the kernel via the "load" API.
1255 LoadPolicy("load_policy"),
1256 /// Permission to read the loaded binary policy via the "policy" file.
1257 ReadPolicy("read_policy"),
1258 /// Permission to commit booleans to control conditional elements of the policy.
1259 SetBool("setbool"),
1260 /// Permission to change the way permissions are validated for `mmap()` operations.
1261 SetCheckReqProt("setcheckreqprot"),
1262 /// Permission to switch the system between permissive and enforcing modes, via "enforce".
1263 SetEnforce("setenforce"),
1264 // keep-sorted end
1265 }
1266}
1267
1268class_permission_enum! {
1269 SystemPermission for System {
1270 // keep-sorted start
1271 /// Permission to use the syslog(2) CONSOLE action types.
1272 SyslogConsole("syslog_console"),
1273 /// Permission to use other syslog(2) action types.
1274 SyslogMod("syslog_mod"),
1275 /// Permission to use the syslog(2) READ_ALL related action types.
1276 SyslogRead("syslog_read"),
1277 // keep-sorted end
1278 }
1279}