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