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