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 neighbor table.
752 NlmsgGetNeigh("nlmsg_getneigh"),
753 /// Permission to read the kernel routing table.
754 NlmsgRead("nlmsg_read"),
755 /// Permission to read privileged netlink messages.
756 NlmsgReadPriv("nlmsg_readpriv"),
757 /// Permission to write to the kernel routing table.
758 NlmsgWrite("nlmsg_write"),
759 // keep-sorted end
760 }
761}
762
763socket_class_permission_enum! {
764 NetlinkFirewallSocketPermission for NetlinkFirewallSocket {
765 }
766}
767
768socket_class_permission_enum! {
769 NetlinkTcpDiagSocketPermission for NetlinkTcpDiagSocket {
770 // keep-sorted start
771 /// Permission for nlmsg xperms.
772 Nlmsg("nlmsg"),
773 /// Permission to request information about a protocol.
774 NlmsgRead("nlmsg_read"),
775 /// Permission to write netlink message.
776 NlmsgWrite("nlmsg_write"),
777 // keep-sorted end
778 }
779}
780
781socket_class_permission_enum! {
782 NetlinkNflogSocketPermission for NetlinkNflogSocket {
783 }
784}
785
786socket_class_permission_enum! {
787 NetlinkXfrmSocketPermission for NetlinkXfrmSocket {
788 // keep-sorted start
789 /// Permission for nlmsg xperms.
790 Nlmsg("nlmsg"),
791 /// Permission to get IPSec configuration information.
792 NlmsgRead("nlmsg_read"),
793 /// Permission to set IPSec configuration information.
794 NlmsgWrite("nlmsg_write"),
795 // keep-sorted end
796 }
797}
798
799socket_class_permission_enum! {
800 NetlinkSelinuxSocketPermission for NetlinkSelinuxSocket {
801 }
802}
803
804socket_class_permission_enum! {
805 NetlinkIscsiSocketPermission for NetlinkIscsiSocket {
806 }
807}
808
809socket_class_permission_enum! {
810 NetlinkAuditSocketPermission for NetlinkAuditSocket {
811 // keep-sorted start
812 /// Permission for nlmsg xperms.
813 Nlmsg("nlmsg"),
814 /// Permission to query status of audit service.
815 NlmsgRead("nlmsg_read"),
816 /// Permission to list auditing configuration rules.
817 NlmsgReadPriv("nlmsg_readpriv"),
818 /// Permission to send userspace audit messages to the audit service.
819 NlmsgRelay("nlmsg_relay"),
820 /// Permission to control TTY auditing.
821 NlmsgTtyAudit("nlmsg_tty_audit"),
822 /// Permission to update the audit service configuration.
823 NlmsgWrite("nlmsg_write"),
824 // keep-sorted end
825 }
826}
827
828socket_class_permission_enum! {
829 NetlinkFibLookupSocketPermission for NetlinkFibLookupSocket {
830 }
831}
832
833socket_class_permission_enum! {
834 NetlinkConnectorSocketPermission for NetlinkConnectorSocket {
835 }
836}
837
838socket_class_permission_enum! {
839 NetlinkNetfilterSocketPermission for NetlinkNetfilterSocket {
840 }
841}
842
843socket_class_permission_enum! {
844 NetlinkIp6FwSocketPermission for NetlinkIp6FwSocket {
845 }
846}
847
848socket_class_permission_enum! {
849 NetlinkDnrtSocketPermission for NetlinkDnrtSocket {
850 }
851}
852
853socket_class_permission_enum! {
854 NetlinkKobjectUeventSocketPermission for NetlinkKobjectUeventSocket {
855 }
856}
857
858socket_class_permission_enum! {
859 NetlinkGenericSocketPermission for NetlinkGenericSocket {
860 }
861}
862
863socket_class_permission_enum! {
864 NetlinkScsitransportSocketPermission for NetlinkScsitransportSocket {
865 }
866}
867
868socket_class_permission_enum! {
869 NetlinkRdmaSocketPermission for NetlinkRdmaSocket {
870 }
871}
872
873socket_class_permission_enum! {
874 NetlinkCryptoSocketPermission for NetlinkCryptoSocket {
875 }
876}
877
878socket_class_permission_enum! {
879 PacketSocketPermission for PacketSocket {
880 }
881}
882
883socket_class_permission_enum! {
884 QipcrtrSocketPermission for QipcrtrSocket {
885 }
886}
887
888socket_class_permission_enum! {
889 RawIpSocketPermission for RawIpSocket {
890 }
891}
892
893socket_class_permission_enum! {
894 SctpSocketPermission for SctpSocket {
895 // keep-sorted start
896 /// Permission to create an SCTP association.
897 Associate("associate"),
898 /// Permission to `connect()` or `connectx()` an SCTP socket.
899 NameConnect("name_connect"),
900 /// Permission to `bind()` or `bindx()` an SCTP socket.
901 NodeBind("node_bind"),
902 // keep-sorted end
903 }
904}
905
906socket_class_permission_enum! {
907 SocketPermission for Socket {
908 }
909}
910
911socket_class_permission_enum! {
912 TcpSocketPermission for TcpSocket {
913 }
914}
915
916socket_class_permission_enum! {
917 TunSocketPermission for TunSocket {
918 }
919}
920
921socket_class_permission_enum! {
922 UdpSocketPermission for UdpSocket {
923 }
924}
925
926socket_class_permission_enum! {
927 UnixStreamSocketPermission for UnixStreamSocket {
928 // keep-sorted start
929 /// Permission to connect a streaming Unix-domain socket.
930 ConnectTo("connectto"),
931 // keep-sorted end
932 }
933}
934
935socket_class_permission_enum! {
936 UnixDgramSocketPermission for UnixDgramSocket {
937 }
938}
939
940socket_class_permission_enum! {
941 VsockSocketPermission for VsockSocket {
942 }
943}
944
945socket_class_permission_enum! {
946 IcmpSocketPermission for IcmpSocket {
947 // keep-sorted start
948 /// Permission to `bind()` an ICMP socket.
949 NodeBind("node_bind"),
950 // keep-sorted end
951 }
952}
953
954/// Permissions common to all file-like object classes (e.g. "lnk_file", "dir"). These are
955/// combined with a specific `FileClass` by policy enforcement hooks, to obtain class-affine
956/// permission values to check.
957macro_rules! file_class_permission_enum {
958 ($(#[$meta:meta])* $name:ident $(for $kernel_class:ident)? {
959 $($(#[$variant_meta:meta])* $variant:ident ($variant_name:literal),)*
960 }) => {
961 fs_node_class_permission_enum! {
962 $(#[$meta])* $name $(for $kernel_class)? {
963 // keep-sorted start
964
965 /// Permission to execute a file with domain transition.
966 Execute("execute"),
967 /// Permissions to create hard link.
968 Link("link"),
969 /// Permission to use as mount point; only useful for directories and files.
970 MountOn("mounton"),
971 /// Permission to open a file.
972 Open("open"),
973 /// Permission to rename a file.
974 Rename("rename"),
975 /// Permission to delete a file or remove a hard link.
976 Unlink("unlink"),
977 // keep-sorted end
978
979 // Additional permissions specific to the derived class.
980 $($(#[$variant_meta])* $variant ($variant_name),)*
981 }}
982
983 $(impl From<CommonFilePermission> for $name {
984 fn from(other: CommonFilePermission) -> Self {
985 // SAFETY: $name's values include all of CommonFilePermission.
986 let result: $name = unsafe { std::mem::transmute(other) };
987 debug_assert_eq!(result.class(), KernelClass::$kernel_class);
988 result
989 }
990 })?
991 }
992}
993
994file_class_permission_enum! {
995 CommonFilePermission {}
996}
997
998impl ForClass<FileClass> for CommonFilePermission {
999 /// Returns the `class`-affine `KernelPermission` value corresponding to this common permission.
1000 /// This is used to allow hooks to resolve e.g. common "read" permission access based on the
1001 /// "allow" rules for the correct target object class.
1002 fn for_class(&self, class: FileClass) -> KernelPermission {
1003 match class {
1004 FileClass::AnonFsNode => AnonFsNodePermission::from(*self).into(),
1005 FileClass::BlkFile => BlkFilePermission::from(*self).into(),
1006 FileClass::ChrFile => ChrFilePermission::from(*self).into(),
1007 FileClass::Dir => DirPermission::from(*self).into(),
1008 FileClass::FifoFile => FifoFilePermission::from(*self).into(),
1009 FileClass::File => FilePermission::from(*self).into(),
1010 FileClass::LnkFile => LnkFilePermission::from(*self).into(),
1011 FileClass::SockFile => SockFilePermission::from(*self).into(),
1012 FileClass::MemFdFile => MemFdFilePermission::from(*self).into(),
1013 }
1014 }
1015}
1016
1017file_class_permission_enum! {
1018 AnonFsNodePermission for AnonFsNode {
1019 }
1020}
1021
1022class_permission_enum! {
1023 BinderPermission for Binder {
1024 // keep-sorted start
1025 /// Permission to perform a binder IPC to a given target process.
1026 Call("call"),
1027 /// Permission to use a Binder connection created with a different security context.
1028 Impersonate("impersonate"),
1029 /// Permission to set oneself as a context manager.
1030 SetContextMgr("set_context_mgr"),
1031 /// Permission to transfer Binder objects as part of a Binder transaction.
1032 Transfer("transfer"),
1033 // keep-sorted end
1034 }
1035}
1036
1037file_class_permission_enum! {
1038 BlkFilePermission for BlkFile {
1039 }
1040}
1041
1042file_class_permission_enum! {
1043 ChrFilePermission for ChrFile {
1044 }
1045}
1046
1047file_class_permission_enum! {
1048 DirPermission for Dir {
1049 // keep-sorted start
1050 /// Permission to add a file to the directory.
1051 AddName("add_name"),
1052 /// Permission to remove a directory.
1053 RemoveDir("rmdir"),
1054 /// Permission to remove an entry from a directory.
1055 RemoveName("remove_name"),
1056 /// Permission to change parent directory.
1057 Reparent("reparent"),
1058 /// Search access to the directory.
1059 Search("search"),
1060 // keep-sorted end
1061 }
1062}
1063
1064class_permission_enum! {
1065 FdPermission for Fd {
1066 // keep-sorted start
1067 /// Permission to use file descriptors copied/retained/inherited from another security
1068 /// context. This permission is generally used to control whether an `exec*()` call from a
1069 /// cloned process that retained a copy of the file descriptor table should succeed.
1070 Use("use"),
1071 // keep-sorted end
1072 }
1073}
1074
1075class_permission_enum! {
1076 BpfPermission for Bpf {
1077 // keep-sorted start
1078 /// Permission to create a map.
1079 MapCreate("map_create"),
1080 /// Permission to read from a map.
1081 MapRead("map_read"),
1082 /// Permission to write on a map.
1083 MapWrite("map_write"),
1084 /// Permission to load a program.
1085 ProgLoad("prog_load"),
1086 /// Permission to run a program.
1087 ProgRun("prog_run"),
1088 // keep-sorted end
1089 }
1090}
1091
1092class_permission_enum! {
1093 PerfEventPermission for PerfEvent {
1094 // keep-sorted start
1095 /// Permission to monitor the cpu.
1096 Cpu("cpu"),
1097 /// Permission to monitor the kernel.
1098 Kernel("kernel"),
1099 /// Permission to open a perf event.
1100 Open("open"),
1101 /// Permission to read a perf event.
1102 Read("read"),
1103 /// Permission to set tracepoints.
1104 Tracepoint("tracepoint"),
1105 /// Permission to write a perf event.
1106 Write("write"),
1107 // keep-sorted end
1108 }
1109}
1110
1111file_class_permission_enum! {
1112 FifoFilePermission for FifoFile {
1113 }
1114}
1115
1116file_class_permission_enum! {
1117 FilePermission for File {
1118 // keep-sorted start
1119 /// Permission to use a file as an entry point into the new domain on transition.
1120 Entrypoint("entrypoint"),
1121 /// Permission to use a file as an entry point to the calling domain without performing a
1122 /// transition.
1123 ExecuteNoTrans("execute_no_trans"),
1124 // keep-sorted end
1125 }
1126}
1127
1128class_permission_enum! {
1129 FileSystemPermission for FileSystem {
1130 // keep-sorted start
1131 /// Permission to associate a file to the filesystem.
1132 Associate("associate"),
1133 /// Permission to get filesystem attributes.
1134 GetAttr("getattr"),
1135 /// Permission mount a filesystem.
1136 Mount("mount"),
1137 /// Permission to remount a filesystem with different flags.
1138 Remount("remount"),
1139 /// Permission to unmount a filesystem.
1140 Unmount("unmount"),
1141 // keep-sorted end
1142 }
1143}
1144
1145file_class_permission_enum! {
1146 LnkFilePermission for LnkFile {
1147 }
1148}
1149
1150file_class_permission_enum! {
1151 MemFdFilePermission for MemFdFile {
1152 }
1153}
1154
1155file_class_permission_enum! {
1156 SockFilePermission for SockFile {
1157 }
1158}
1159
1160class_permission_enum! {
1161 ProcessPermission for Process {
1162 // keep-sorted start
1163 /// Permission to dynamically transition a process to a different security domain.
1164 DynTransition("dyntransition"),
1165 /// Permission to execute arbitrary code from the heap.
1166 ExecHeap("execheap"),
1167 /// Permission to execute arbitrary code from memory.
1168 ExecMem("execmem"),
1169 /// Permission to execute arbitrary code from the stack.
1170 ExecStack("execstack"),
1171 /// Permission to fork the current running process.
1172 Fork("fork"),
1173 /// Permission to get Linux capabilities of a process.
1174 GetCap("getcap"),
1175 /// Permission to get the process group ID.
1176 GetPgid("getpgid"),
1177 /// Permission to get the resource limits on a process.
1178 GetRlimit("getrlimit"),
1179 /// Permission to get scheduling policy currently applied to a process.
1180 GetSched("getsched"),
1181 /// Permission to get the session ID.
1182 GetSession("getsession"),
1183 /// Permission to exec into a new security domain without setting the AT_SECURE entry in the
1184 /// executable's auxiliary vector.
1185 NoAtSecure("noatsecure"),
1186 /// Permission to trace a process.
1187 Ptrace("ptrace"),
1188 /// Permission to inherit the parent process's resource limits on exec.
1189 RlimitInh("rlimitinh"),
1190 /// Permission to set Linux capabilities of a process.
1191 SetCap("setcap"),
1192 /// Permission to set the calling task's current Security Context.
1193 /// The "dyntransition" permission separately limits which Contexts "setcurrent" may be used to transition to.
1194 SetCurrent("setcurrent"),
1195 /// Permission to set the Security Context used by `exec()`.
1196 SetExec("setexec"),
1197 /// Permission to set the Security Context used when creating filesystem objects.
1198 SetFsCreate("setfscreate"),
1199 /// Permission to set the Security Context used when creating kernel keyrings.
1200 SetKeyCreate("setkeycreate"),
1201 /// Permission to set the process group ID.
1202 SetPgid("setpgid"),
1203 /// Permission to set the resource limits on a process.
1204 SetRlimit("setrlimit"),
1205 /// Permission to set scheduling policy for a process.
1206 SetSched("setsched"),
1207 /// Permission to set the Security Context used when creating new labeled sockets.
1208 SetSockCreate("setsockcreate"),
1209 /// Permission to share resources (e.g. FD table, address-space, etc) with a process.
1210 Share("share"),
1211 /// Permission to send SIGCHLD to a process.
1212 SigChld("sigchld"),
1213 /// Permission to inherit the parent process's signal state.
1214 SigInh("siginh"),
1215 /// Permission to send SIGKILL to a process.
1216 SigKill("sigkill"),
1217 /// Permission to send SIGSTOP to a process.
1218 SigStop("sigstop"),
1219 /// Permission to send a signal other than SIGKILL, SIGSTOP, or SIGCHLD to a process.
1220 Signal("signal"),
1221 /// Permission to transition to a different security domain.
1222 Transition("transition"),
1223 // keep-sorted end
1224 }
1225}
1226
1227class_permission_enum! {
1228 Process2Permission for Process2 {
1229 // keep-sorted start
1230 /// Permission to transition to an unbounded domain when no-new-privileges is set.
1231 NnpTransition("nnp_transition"),
1232 /// Permission to transition domain when executing from a no-SUID mounted filesystem.
1233 NosuidTransition("nosuid_transition"),
1234 // keep-sorted end
1235 }
1236}
1237
1238class_permission_enum! {
1239 SecurityPermission for Security {
1240 // keep-sorted start
1241 /// Permission to validate Security Context using the "context" API.
1242 CheckContext("check_context"),
1243 /// Permission to compute access vectors via the "access" API.
1244 ComputeAv("compute_av"),
1245 /// Permission to compute security contexts based on `type_transition` rules via "create".
1246 ComputeCreate("compute_create"),
1247 /// Permission to compute security contexts based on `type_member` rules via "member".
1248 ComputeMember("compute_member"),
1249 /// Permission to compute security contexts based on `type_change` rules via "relabel".
1250 ComputeRelabel("compute_relabel"),
1251 /// Permission to compute user decisions via "user".
1252 ComputeUser("compute_user"),
1253 /// Permission to load a new binary policy into the kernel via the "load" API.
1254 LoadPolicy("load_policy"),
1255 /// Permission to commit booleans to control conditional elements of the policy.
1256 SetBool("setbool"),
1257 /// Permission to change the way permissions are validated for `mmap()` operations.
1258 SetCheckReqProt("setcheckreqprot"),
1259 /// Permission to switch the system between permissive and enforcing modes, via "enforce".
1260 SetEnforce("setenforce"),
1261 // keep-sorted end
1262 }
1263}
1264
1265class_permission_enum! {
1266 SystemPermission for System {
1267 // keep-sorted start
1268 /// Permission to use the syslog(2) CONSOLE action types.
1269 SyslogConsole("syslog_console"),
1270 /// Permission to use other syslog(2) action types.
1271 SyslogMod("syslog_mod"),
1272 /// Permission to use the syslog(2) READ_ALL related action types.
1273 SyslogRead("syslog_read"),
1274 // keep-sorted end
1275 }
1276}