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