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