Skip to main content

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