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