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