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