1b8a62b91Sopenharmony_ci#![allow(unsafe_code)]
2b8a62b91Sopenharmony_ci
3b8a62b91Sopenharmony_ciuse core::convert::TryFrom;
4b8a62b91Sopenharmony_ciuse core::mem::MaybeUninit;
5b8a62b91Sopenharmony_ciuse core::num::NonZeroU64;
6b8a62b91Sopenharmony_ciuse core::ptr;
7b8a62b91Sopenharmony_ciuse core::ptr::NonNull;
8b8a62b91Sopenharmony_ciuse core::sync::atomic::AtomicU8;
9b8a62b91Sopenharmony_ci
10b8a62b91Sopenharmony_ciuse bitflags::bitflags;
11b8a62b91Sopenharmony_ci
12b8a62b91Sopenharmony_ciuse crate::backend::c::{c_int, c_uint, c_void};
13b8a62b91Sopenharmony_ciuse crate::backend::process::syscalls;
14b8a62b91Sopenharmony_ciuse crate::ffi::{CStr, CString};
15b8a62b91Sopenharmony_ciuse crate::io;
16b8a62b91Sopenharmony_ciuse crate::process::{
17b8a62b91Sopenharmony_ci    prctl_1arg, prctl_2args, prctl_3args, prctl_get_at_arg2_optional, Pid,
18b8a62b91Sopenharmony_ci    PointerAuthenticationKeys,
19b8a62b91Sopenharmony_ci};
20b8a62b91Sopenharmony_ci
21b8a62b91Sopenharmony_ci//
22b8a62b91Sopenharmony_ci// PR_GET_KEEPCAPS/PR_SET_KEEPCAPS
23b8a62b91Sopenharmony_ci//
24b8a62b91Sopenharmony_ci
25b8a62b91Sopenharmony_ciconst PR_GET_KEEPCAPS: c_int = 7;
26b8a62b91Sopenharmony_ci
27b8a62b91Sopenharmony_ci/// Get the current state of the calling thread's `keep capabilities` flag.
28b8a62b91Sopenharmony_ci///
29b8a62b91Sopenharmony_ci/// # References
30b8a62b91Sopenharmony_ci/// - [`prctl(PR_GET_KEEPCAPS,...)`]
31b8a62b91Sopenharmony_ci///
32b8a62b91Sopenharmony_ci/// [`prctl(PR_GET_KEEPCAPS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
33b8a62b91Sopenharmony_ci#[inline]
34b8a62b91Sopenharmony_cipub fn get_keep_capabilities() -> io::Result<bool> {
35b8a62b91Sopenharmony_ci    unsafe { prctl_1arg(PR_GET_KEEPCAPS) }.map(|r| r != 0)
36b8a62b91Sopenharmony_ci}
37b8a62b91Sopenharmony_ci
38b8a62b91Sopenharmony_ciconst PR_SET_KEEPCAPS: c_int = 8;
39b8a62b91Sopenharmony_ci
40b8a62b91Sopenharmony_ci/// Set the state of the calling thread's `keep capabilities` flag.
41b8a62b91Sopenharmony_ci///
42b8a62b91Sopenharmony_ci/// # References
43b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_KEEPCAPS,...)`]
44b8a62b91Sopenharmony_ci///
45b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_KEEPCAPS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
46b8a62b91Sopenharmony_ci#[inline]
47b8a62b91Sopenharmony_cipub fn set_keep_capabilities(enable: bool) -> io::Result<()> {
48b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_SET_KEEPCAPS, enable as usize as *mut _) }.map(|_r| ())
49b8a62b91Sopenharmony_ci}
50b8a62b91Sopenharmony_ci
51b8a62b91Sopenharmony_ci//
52b8a62b91Sopenharmony_ci// PR_GET_NAME/PR_SET_NAME
53b8a62b91Sopenharmony_ci//
54b8a62b91Sopenharmony_ci
55b8a62b91Sopenharmony_ciconst PR_GET_NAME: c_int = 16;
56b8a62b91Sopenharmony_ci
57b8a62b91Sopenharmony_ci/// Get the name of the calling thread.
58b8a62b91Sopenharmony_ci///
59b8a62b91Sopenharmony_ci/// # References
60b8a62b91Sopenharmony_ci/// - [`prctl(PR_GET_NAME,...)`]
61b8a62b91Sopenharmony_ci///
62b8a62b91Sopenharmony_ci/// [`prctl(PR_GET_NAME,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
63b8a62b91Sopenharmony_ci#[inline]
64b8a62b91Sopenharmony_cipub fn name() -> io::Result<CString> {
65b8a62b91Sopenharmony_ci    let mut buffer = [0_u8; 16];
66b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_GET_NAME, buffer.as_mut_ptr().cast())? };
67b8a62b91Sopenharmony_ci
68b8a62b91Sopenharmony_ci    let len = buffer.iter().position(|&x| x == 0_u8).unwrap_or(0);
69b8a62b91Sopenharmony_ci    CString::new(&buffer[..len]).map_err(|_r| io::Errno::ILSEQ)
70b8a62b91Sopenharmony_ci}
71b8a62b91Sopenharmony_ci
72b8a62b91Sopenharmony_ciconst PR_SET_NAME: c_int = 15;
73b8a62b91Sopenharmony_ci
74b8a62b91Sopenharmony_ci/// Set the name of the calling thread.
75b8a62b91Sopenharmony_ci///
76b8a62b91Sopenharmony_ci/// # References
77b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_NAME,...)`]
78b8a62b91Sopenharmony_ci///
79b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_NAME,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
80b8a62b91Sopenharmony_ci#[inline]
81b8a62b91Sopenharmony_cipub fn set_name(name: &CStr) -> io::Result<()> {
82b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_SET_NAME, name.as_ptr() as *mut _) }.map(|_r| ())
83b8a62b91Sopenharmony_ci}
84b8a62b91Sopenharmony_ci
85b8a62b91Sopenharmony_ci//
86b8a62b91Sopenharmony_ci// PR_GET_SECCOMP/PR_SET_SECCOMP
87b8a62b91Sopenharmony_ci//
88b8a62b91Sopenharmony_ci
89b8a62b91Sopenharmony_ci//const PR_GET_SECCOMP: c_int = 21;
90b8a62b91Sopenharmony_ci
91b8a62b91Sopenharmony_ciconst SECCOMP_MODE_DISABLED: i32 = 0;
92b8a62b91Sopenharmony_ciconst SECCOMP_MODE_STRICT: i32 = 1;
93b8a62b91Sopenharmony_ciconst SECCOMP_MODE_FILTER: i32 = 2;
94b8a62b91Sopenharmony_ci
95b8a62b91Sopenharmony_ci/// `SECCOMP_MODE_*`.
96b8a62b91Sopenharmony_ci#[derive(Copy, Clone, Debug, Eq, PartialEq)]
97b8a62b91Sopenharmony_ci#[repr(i32)]
98b8a62b91Sopenharmony_cipub enum SecureComputingMode {
99b8a62b91Sopenharmony_ci    /// Secure computing is not in use.
100b8a62b91Sopenharmony_ci    Disabled = SECCOMP_MODE_DISABLED,
101b8a62b91Sopenharmony_ci    /// Use hard-coded filter.
102b8a62b91Sopenharmony_ci    Strict = SECCOMP_MODE_STRICT,
103b8a62b91Sopenharmony_ci    /// Use user-supplied filter.
104b8a62b91Sopenharmony_ci    Filter = SECCOMP_MODE_FILTER,
105b8a62b91Sopenharmony_ci}
106b8a62b91Sopenharmony_ci
107b8a62b91Sopenharmony_ciimpl TryFrom<i32> for SecureComputingMode {
108b8a62b91Sopenharmony_ci    type Error = io::Errno;
109b8a62b91Sopenharmony_ci
110b8a62b91Sopenharmony_ci    fn try_from(value: i32) -> Result<Self, Self::Error> {
111b8a62b91Sopenharmony_ci        match value {
112b8a62b91Sopenharmony_ci            SECCOMP_MODE_DISABLED => Ok(Self::Disabled),
113b8a62b91Sopenharmony_ci            SECCOMP_MODE_STRICT => Ok(Self::Strict),
114b8a62b91Sopenharmony_ci            SECCOMP_MODE_FILTER => Ok(Self::Filter),
115b8a62b91Sopenharmony_ci            _ => Err(io::Errno::RANGE),
116b8a62b91Sopenharmony_ci        }
117b8a62b91Sopenharmony_ci    }
118b8a62b91Sopenharmony_ci}
119b8a62b91Sopenharmony_ci
120b8a62b91Sopenharmony_ci/*
121b8a62b91Sopenharmony_ci/// Get the secure computing mode of the calling thread.
122b8a62b91Sopenharmony_ci///
123b8a62b91Sopenharmony_ci/// If the caller is not in secure computing mode, this returns [`SecureComputingMode::Disabled`].
124b8a62b91Sopenharmony_ci/// If the caller is in strict secure computing mode, then this call will cause a `SIGKILL` signal
125b8a62b91Sopenharmony_ci/// to be sent to the process.
126b8a62b91Sopenharmony_ci/// If the caller is in filter mode, and this system call is allowed by the seccomp filters,
127b8a62b91Sopenharmony_ci/// it returns [`SecureComputingMode::Filter`]; otherwise, the process is killed with
128b8a62b91Sopenharmony_ci/// a `SIGKILL` signal.
129b8a62b91Sopenharmony_ci///
130b8a62b91Sopenharmony_ci/// Since Linux 3.8, the Seccomp field of the `/proc/[pid]/status` file provides a method
131b8a62b91Sopenharmony_ci/// of obtaining the same information, without the risk that the process is killed; see `proc(5)`.
132b8a62b91Sopenharmony_ci///
133b8a62b91Sopenharmony_ci/// # References
134b8a62b91Sopenharmony_ci/// - [`prctl(PR_GET_SECCOMP,...)`]
135b8a62b91Sopenharmony_ci///
136b8a62b91Sopenharmony_ci/// [`prctl(PR_GET_SECCOMP,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
137b8a62b91Sopenharmony_ci#[inline]
138b8a62b91Sopenharmony_cipub fn secure_computing_mode() -> io::Result<SecureComputingMode> {
139b8a62b91Sopenharmony_ci    unsafe { prctl_1arg(PR_GET_SECCOMP) }.and_then(TryInto::try_into)
140b8a62b91Sopenharmony_ci}
141b8a62b91Sopenharmony_ci*/
142b8a62b91Sopenharmony_ci
143b8a62b91Sopenharmony_ciconst PR_SET_SECCOMP: c_int = 22;
144b8a62b91Sopenharmony_ci
145b8a62b91Sopenharmony_ci/// Set the secure computing mode for the calling thread, to limit the available system calls.
146b8a62b91Sopenharmony_ci///
147b8a62b91Sopenharmony_ci/// # References
148b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_SECCOMP,...)`]
149b8a62b91Sopenharmony_ci///
150b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_SECCOMP,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
151b8a62b91Sopenharmony_ci#[inline]
152b8a62b91Sopenharmony_cipub fn set_secure_computing_mode(mode: SecureComputingMode) -> io::Result<()> {
153b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_SET_SECCOMP, mode as usize as *mut _) }.map(|_r| ())
154b8a62b91Sopenharmony_ci}
155b8a62b91Sopenharmony_ci
156b8a62b91Sopenharmony_ci//
157b8a62b91Sopenharmony_ci// PR_CAPBSET_READ/PR_CAPBSET_DROP
158b8a62b91Sopenharmony_ci//
159b8a62b91Sopenharmony_ci
160b8a62b91Sopenharmony_ciconst PR_CAPBSET_READ: c_int = 23;
161b8a62b91Sopenharmony_ci
162b8a62b91Sopenharmony_ciconst CAP_CHOWN: u32 = 0;
163b8a62b91Sopenharmony_ciconst CAP_DAC_OVERRIDE: u32 = 1;
164b8a62b91Sopenharmony_ciconst CAP_DAC_READ_SEARCH: u32 = 2;
165b8a62b91Sopenharmony_ciconst CAP_FOWNER: u32 = 3;
166b8a62b91Sopenharmony_ciconst CAP_FSETID: u32 = 4;
167b8a62b91Sopenharmony_ciconst CAP_KILL: u32 = 5;
168b8a62b91Sopenharmony_ciconst CAP_SETGID: u32 = 6;
169b8a62b91Sopenharmony_ciconst CAP_SETUID: u32 = 7;
170b8a62b91Sopenharmony_ciconst CAP_SETPCAP: u32 = 8;
171b8a62b91Sopenharmony_ciconst CAP_LINUX_IMMUTABLE: u32 = 9;
172b8a62b91Sopenharmony_ciconst CAP_NET_BIND_SERVICE: u32 = 10;
173b8a62b91Sopenharmony_ciconst CAP_NET_BROADCAST: u32 = 11;
174b8a62b91Sopenharmony_ciconst CAP_NET_ADMIN: u32 = 12;
175b8a62b91Sopenharmony_ciconst CAP_NET_RAW: u32 = 13;
176b8a62b91Sopenharmony_ciconst CAP_IPC_LOCK: u32 = 14;
177b8a62b91Sopenharmony_ciconst CAP_IPC_OWNER: u32 = 15;
178b8a62b91Sopenharmony_ciconst CAP_SYS_MODULE: u32 = 16;
179b8a62b91Sopenharmony_ciconst CAP_SYS_RAWIO: u32 = 17;
180b8a62b91Sopenharmony_ciconst CAP_SYS_CHROOT: u32 = 18;
181b8a62b91Sopenharmony_ciconst CAP_SYS_PTRACE: u32 = 19;
182b8a62b91Sopenharmony_ciconst CAP_SYS_PACCT: u32 = 20;
183b8a62b91Sopenharmony_ciconst CAP_SYS_ADMIN: u32 = 21;
184b8a62b91Sopenharmony_ciconst CAP_SYS_BOOT: u32 = 22;
185b8a62b91Sopenharmony_ciconst CAP_SYS_NICE: u32 = 23;
186b8a62b91Sopenharmony_ciconst CAP_SYS_RESOURCE: u32 = 24;
187b8a62b91Sopenharmony_ciconst CAP_SYS_TIME: u32 = 25;
188b8a62b91Sopenharmony_ciconst CAP_SYS_TTY_CONFIG: u32 = 26;
189b8a62b91Sopenharmony_ciconst CAP_MKNOD: u32 = 27;
190b8a62b91Sopenharmony_ciconst CAP_LEASE: u32 = 28;
191b8a62b91Sopenharmony_ciconst CAP_AUDIT_WRITE: u32 = 29;
192b8a62b91Sopenharmony_ciconst CAP_AUDIT_CONTROL: u32 = 30;
193b8a62b91Sopenharmony_ciconst CAP_SETFCAP: u32 = 31;
194b8a62b91Sopenharmony_ciconst CAP_MAC_OVERRIDE: u32 = 32;
195b8a62b91Sopenharmony_ciconst CAP_MAC_ADMIN: u32 = 33;
196b8a62b91Sopenharmony_ciconst CAP_SYSLOG: u32 = 34;
197b8a62b91Sopenharmony_ciconst CAP_WAKE_ALARM: u32 = 35;
198b8a62b91Sopenharmony_ciconst CAP_BLOCK_SUSPEND: u32 = 36;
199b8a62b91Sopenharmony_ciconst CAP_AUDIT_READ: u32 = 37;
200b8a62b91Sopenharmony_ciconst CAP_PERFMON: u32 = 38;
201b8a62b91Sopenharmony_ciconst CAP_BPF: u32 = 39;
202b8a62b91Sopenharmony_ciconst CAP_CHECKPOINT_RESTORE: u32 = 40;
203b8a62b91Sopenharmony_ci
204b8a62b91Sopenharmony_ci/// Linux per-thread capability.
205b8a62b91Sopenharmony_ci#[derive(Copy, Clone, Debug, Eq, PartialEq)]
206b8a62b91Sopenharmony_ci#[repr(u32)]
207b8a62b91Sopenharmony_cipub enum Capability {
208b8a62b91Sopenharmony_ci    /// In a system with the `_POSIX_CHOWN_RESTRICTED` option defined, this overrides
209b8a62b91Sopenharmony_ci    /// the restriction of changing file ownership and group ownership.
210b8a62b91Sopenharmony_ci    ChangeOwnership = CAP_CHOWN,
211b8a62b91Sopenharmony_ci    /// Override all DAC access, including ACL execute access if `_POSIX_ACL` is defined.
212b8a62b91Sopenharmony_ci    /// Excluding DAC access covered by [`Capability::LinuxImmutable`].
213b8a62b91Sopenharmony_ci    DACOverride = CAP_DAC_OVERRIDE,
214b8a62b91Sopenharmony_ci    /// Overrides all DAC restrictions regarding read and search on files and directories,
215b8a62b91Sopenharmony_ci    /// including ACL restrictions if `_POSIX_ACL` is defined. Excluding DAC access covered
216b8a62b91Sopenharmony_ci    /// by [`Capability::LinuxImmutable`].
217b8a62b91Sopenharmony_ci    DACReadSearch = CAP_DAC_READ_SEARCH,
218b8a62b91Sopenharmony_ci    /// Overrides all restrictions about allowed operations on files, where file owner ID must be
219b8a62b91Sopenharmony_ci    /// equal to the user ID, except where [`Capability::FileSetID`] is applicable.
220b8a62b91Sopenharmony_ci    /// It doesn't override MAC and DAC restrictions.
221b8a62b91Sopenharmony_ci    FileOwner = CAP_FOWNER,
222b8a62b91Sopenharmony_ci    /// Overrides the following restrictions that the effective user ID shall match the file owner
223b8a62b91Sopenharmony_ci    /// ID when setting the `S_ISUID` and `S_ISGID` bits on that file; that the effective group ID
224b8a62b91Sopenharmony_ci    /// (or one of the supplementary group IDs) shall match the file owner ID when setting the
225b8a62b91Sopenharmony_ci    /// `S_ISGID` bit on that file; that the `S_ISUID` and `S_ISGID` bits are cleared on successful
226b8a62b91Sopenharmony_ci    /// return from `chown` (not implemented).
227b8a62b91Sopenharmony_ci    FileSetID = CAP_FSETID,
228b8a62b91Sopenharmony_ci    /// Overrides the restriction that the real or effective user ID of a process sending a signal
229b8a62b91Sopenharmony_ci    /// must match the real or effective user ID of the process receiving the signal.
230b8a62b91Sopenharmony_ci    Kill = CAP_KILL,
231b8a62b91Sopenharmony_ci    /// Allows `setgid` manipulation. Allows `setgroups`. Allows forged gids on socket
232b8a62b91Sopenharmony_ci    /// credentials passing.
233b8a62b91Sopenharmony_ci    SetGroupID = CAP_SETGID,
234b8a62b91Sopenharmony_ci    /// Allows `set*uid` manipulation (including fsuid). Allows forged pids on socket
235b8a62b91Sopenharmony_ci    /// credentials passing.
236b8a62b91Sopenharmony_ci    SetUserID = CAP_SETUID,
237b8a62b91Sopenharmony_ci    /// Without VFS support for capabilities:
238b8a62b91Sopenharmony_ci    /// - Transfer any capability in your permitted set to any pid.
239b8a62b91Sopenharmony_ci    /// - remove any capability in your permitted set from any pid.
240b8a62b91Sopenharmony_ci    ///   With VFS support for capabilities (neither of above, but)
241b8a62b91Sopenharmony_ci    /// - Add any capability from current's capability bounding set to the current process'
242b8a62b91Sopenharmony_ci    ///   inheritable set.
243b8a62b91Sopenharmony_ci    /// - Allow taking bits out of capability bounding set.
244b8a62b91Sopenharmony_ci    /// - Allow modification of the securebits for a process.
245b8a62b91Sopenharmony_ci    SetPermittedCapabilities = CAP_SETPCAP,
246b8a62b91Sopenharmony_ci    /// Allow modification of `S_IMMUTABLE` and `S_APPEND` file attributes.
247b8a62b91Sopenharmony_ci    LinuxImmutable = CAP_LINUX_IMMUTABLE,
248b8a62b91Sopenharmony_ci    /// Allows binding to TCP/UDP sockets below 1024. Allows binding to ATM VCIs below 32.
249b8a62b91Sopenharmony_ci    NetBindService = CAP_NET_BIND_SERVICE,
250b8a62b91Sopenharmony_ci    /// Allow broadcasting, listen to multicast.
251b8a62b91Sopenharmony_ci    NetBroadcast = CAP_NET_BROADCAST,
252b8a62b91Sopenharmony_ci    /// Allow interface configuration. Allow administration of IP firewall, masquerading and
253b8a62b91Sopenharmony_ci    /// accounting. Allow setting debug option on sockets. Allow modification of routing tables.
254b8a62b91Sopenharmony_ci    /// Allow setting arbitrary process / process group ownership on sockets. Allow binding to any
255b8a62b91Sopenharmony_ci    /// address for transparent proxying (also via [`Capability::NetRaw`]). Allow setting TOS
256b8a62b91Sopenharmony_ci    /// (type of service). Allow setting promiscuous mode. Allow clearing driver statistics.
257b8a62b91Sopenharmony_ci    /// Allow multicasting. Allow read/write of device-specific registers. Allow activation of ATM
258b8a62b91Sopenharmony_ci    /// control sockets.
259b8a62b91Sopenharmony_ci    NetAdmin = CAP_NET_ADMIN,
260b8a62b91Sopenharmony_ci    /// Allow use of `RAW` sockets. Allow use of `PACKET` sockets. Allow binding to any address for
261b8a62b91Sopenharmony_ci    /// transparent proxying (also via [`Capability::NetAdmin`]).
262b8a62b91Sopenharmony_ci    NetRaw = CAP_NET_RAW,
263b8a62b91Sopenharmony_ci    /// Allow locking of shared memory segments. Allow mlock and mlockall (which doesn't really have
264b8a62b91Sopenharmony_ci    /// anything to do with IPC).
265b8a62b91Sopenharmony_ci    IPCLock = CAP_IPC_LOCK,
266b8a62b91Sopenharmony_ci    /// Override IPC ownership checks.
267b8a62b91Sopenharmony_ci    IPCOwner = CAP_IPC_OWNER,
268b8a62b91Sopenharmony_ci    /// Insert and remove kernel modules - modify kernel without limit.
269b8a62b91Sopenharmony_ci    SystemModule = CAP_SYS_MODULE,
270b8a62b91Sopenharmony_ci    /// Allow ioperm/iopl access. Allow sending USB messages to any device via `/dev/bus/usb`.
271b8a62b91Sopenharmony_ci    SystemRawIO = CAP_SYS_RAWIO,
272b8a62b91Sopenharmony_ci    /// Allow use of `chroot`.
273b8a62b91Sopenharmony_ci    SystemChangeRoot = CAP_SYS_CHROOT,
274b8a62b91Sopenharmony_ci    /// Allow `ptrace` of any process.
275b8a62b91Sopenharmony_ci    SystemProcessTrace = CAP_SYS_PTRACE,
276b8a62b91Sopenharmony_ci    /// Allow configuration of process accounting.
277b8a62b91Sopenharmony_ci    SystemProcessAccounting = CAP_SYS_PACCT,
278b8a62b91Sopenharmony_ci    /// Allow configuration of the secure attention key. Allow administration of the random device.
279b8a62b91Sopenharmony_ci    /// Allow examination and configuration of disk quotas. Allow setting the domainname.
280b8a62b91Sopenharmony_ci    /// Allow setting the hostname. Allow `mount` and `umount`, setting up new smb connection.
281b8a62b91Sopenharmony_ci    /// Allow some autofs root ioctls. Allow nfsservctl. Allow `VM86_REQUEST_IRQ`.
282b8a62b91Sopenharmony_ci    /// Allow to read/write pci config on alpha. Allow `irix_prctl` on mips (setstacksize).
283b8a62b91Sopenharmony_ci    /// Allow flushing all cache on m68k (`sys_cacheflush`). Allow removing semaphores.
284b8a62b91Sopenharmony_ci    /// Used instead of [`Capability::ChangeOwnership`] to "chown" IPC message queues, semaphores
285b8a62b91Sopenharmony_ci    /// and shared memory. Allow locking/unlocking of shared memory segment. Allow turning swap
286b8a62b91Sopenharmony_ci    /// on/off. Allow forged pids on socket credentials passing. Allow setting readahead and
287b8a62b91Sopenharmony_ci    /// flushing buffers on block devices. Allow setting geometry in floppy driver. Allow turning
288b8a62b91Sopenharmony_ci    /// DMA on/off in `xd` driver. Allow administration of md devices (mostly the above, but some
289b8a62b91Sopenharmony_ci    /// extra ioctls). Allow tuning the ide driver. Allow access to the nvram device. Allow
290b8a62b91Sopenharmony_ci    /// administration of `apm_bios`, serial and bttv (TV) device. Allow manufacturer commands in
291b8a62b91Sopenharmony_ci    /// isdn CAPI support driver. Allow reading non-standardized portions of pci configuration
292b8a62b91Sopenharmony_ci    /// space. Allow DDI debug ioctl on sbpcd driver. Allow setting up serial ports. Allow sending
293b8a62b91Sopenharmony_ci    /// raw qic-117 commands. Allow enabling/disabling tagged queuing on SCSI controllers and
294b8a62b91Sopenharmony_ci    /// sending arbitrary SCSI commands. Allow setting encryption key on loopback filesystem.
295b8a62b91Sopenharmony_ci    /// Allow setting zone reclaim policy. Allow everything under
296b8a62b91Sopenharmony_ci    /// [`Capability::BerkeleyPacketFilters`] and [`Capability::PerformanceMonitoring`] for backward
297b8a62b91Sopenharmony_ci    /// compatibility.
298b8a62b91Sopenharmony_ci    SystemAdmin = CAP_SYS_ADMIN,
299b8a62b91Sopenharmony_ci    /// Allow use of `reboot`.
300b8a62b91Sopenharmony_ci    SystemBoot = CAP_SYS_BOOT,
301b8a62b91Sopenharmony_ci    /// Allow raising priority and setting priority on other (different UID) processes. Allow use of
302b8a62b91Sopenharmony_ci    /// FIFO and round-robin (realtime) scheduling on own processes and setting the scheduling
303b8a62b91Sopenharmony_ci    /// algorithm used by another process. Allow setting cpu affinity on other processes.
304b8a62b91Sopenharmony_ci    /// Allow setting realtime ioprio class. Allow setting ioprio class on other processes.
305b8a62b91Sopenharmony_ci    SystemNice = CAP_SYS_NICE,
306b8a62b91Sopenharmony_ci    /// Override resource limits. Set resource limits. Override quota limits. Override reserved
307b8a62b91Sopenharmony_ci    /// space on ext2 filesystem. Modify data journaling mode on ext3 filesystem (uses journaling
308b8a62b91Sopenharmony_ci    /// resources). NOTE: ext2 honors fsuid when checking for resource overrides, so you can
309b8a62b91Sopenharmony_ci    /// override using fsuid too. Override size restrictions on IPC message queues. Allow more than
310b8a62b91Sopenharmony_ci    /// 64hz interrupts from the real-time clock. Override max number of consoles on console
311b8a62b91Sopenharmony_ci    /// allocation. Override max number of keymaps. Control memory reclaim behavior.
312b8a62b91Sopenharmony_ci    SystemResource = CAP_SYS_RESOURCE,
313b8a62b91Sopenharmony_ci    /// Allow manipulation of system clock. Allow `irix_stime` on mips. Allow setting the real-time
314b8a62b91Sopenharmony_ci    /// clock.
315b8a62b91Sopenharmony_ci    SystemTime = CAP_SYS_TIME,
316b8a62b91Sopenharmony_ci    /// Allow configuration of tty devices. Allow `vhangup` of tty.
317b8a62b91Sopenharmony_ci    SystemTTYConfig = CAP_SYS_TTY_CONFIG,
318b8a62b91Sopenharmony_ci    /// Allow the privileged aspects of `mknod`.
319b8a62b91Sopenharmony_ci    MakeNode = CAP_MKNOD,
320b8a62b91Sopenharmony_ci    /// Allow taking of leases on files.
321b8a62b91Sopenharmony_ci    Lease = CAP_LEASE,
322b8a62b91Sopenharmony_ci    /// Allow writing the audit log via unicast netlink socket.
323b8a62b91Sopenharmony_ci    AuditWrite = CAP_AUDIT_WRITE,
324b8a62b91Sopenharmony_ci    /// Allow configuration of audit via unicast netlink socket.
325b8a62b91Sopenharmony_ci    AuditControl = CAP_AUDIT_CONTROL,
326b8a62b91Sopenharmony_ci    /// Set or remove capabilities on files. Map `uid=0` into a child user namespace.
327b8a62b91Sopenharmony_ci    SetFileCapabilities = CAP_SETFCAP,
328b8a62b91Sopenharmony_ci    /// Override MAC access. The base kernel enforces no MAC policy. An LSM may enforce a MAC
329b8a62b91Sopenharmony_ci    /// policy, and if it does and it chooses to implement capability based overrides of that
330b8a62b91Sopenharmony_ci    /// policy, this is the capability it should use to do so.
331b8a62b91Sopenharmony_ci    MACOverride = CAP_MAC_OVERRIDE,
332b8a62b91Sopenharmony_ci    /// Allow MAC configuration or state changes. The base kernel requires no MAC configuration.
333b8a62b91Sopenharmony_ci    /// An LSM may enforce a MAC policy, and if it does and it chooses to implement capability based
334b8a62b91Sopenharmony_ci    /// checks on modifications to that policy or the data required to maintain it, this is the
335b8a62b91Sopenharmony_ci    /// capability it should use to do so.
336b8a62b91Sopenharmony_ci    MACAdmin = CAP_MAC_ADMIN,
337b8a62b91Sopenharmony_ci    /// Allow configuring the kernel's `syslog` (`printk` behaviour).
338b8a62b91Sopenharmony_ci    SystemLog = CAP_SYSLOG,
339b8a62b91Sopenharmony_ci    /// Allow triggering something that will wake the system.
340b8a62b91Sopenharmony_ci    WakeAlarm = CAP_WAKE_ALARM,
341b8a62b91Sopenharmony_ci    /// Allow preventing system suspends.
342b8a62b91Sopenharmony_ci    BlockSuspend = CAP_BLOCK_SUSPEND,
343b8a62b91Sopenharmony_ci    /// Allow reading the audit log via multicast netlink socket.
344b8a62b91Sopenharmony_ci    AuditRead = CAP_AUDIT_READ,
345b8a62b91Sopenharmony_ci    /// Allow system performance and observability privileged operations using `perf_events`,
346b8a62b91Sopenharmony_ci    /// `i915_perf` and other kernel subsystems.
347b8a62b91Sopenharmony_ci    PerformanceMonitoring = CAP_PERFMON,
348b8a62b91Sopenharmony_ci    /// This capability allows the following BPF operations:
349b8a62b91Sopenharmony_ci    /// - Creating all types of BPF maps
350b8a62b91Sopenharmony_ci    /// - Advanced verifier features
351b8a62b91Sopenharmony_ci    ///   - Indirect variable access
352b8a62b91Sopenharmony_ci    ///   - Bounded loops
353b8a62b91Sopenharmony_ci    ///   - BPF to BPF function calls
354b8a62b91Sopenharmony_ci    ///   - Scalar precision tracking
355b8a62b91Sopenharmony_ci    ///   - Larger complexity limits
356b8a62b91Sopenharmony_ci    ///   - Dead code elimination
357b8a62b91Sopenharmony_ci    ///   - And potentially other features
358b8a62b91Sopenharmony_ci    /// - Loading BPF Type Format (BTF) data
359b8a62b91Sopenharmony_ci    /// - Retrieve `xlated` and JITed code of BPF programs
360b8a62b91Sopenharmony_ci    /// - Use `bpf_spin_lock` helper
361b8a62b91Sopenharmony_ci    ///
362b8a62b91Sopenharmony_ci    /// [`Capability::PerformanceMonitoring`] relaxes the verifier checks further:
363b8a62b91Sopenharmony_ci    /// - BPF progs can use of pointer-to-integer conversions
364b8a62b91Sopenharmony_ci    /// - speculation attack hardening measures are bypassed
365b8a62b91Sopenharmony_ci    /// - `bpf_probe_read` to read arbitrary kernel memory is allowed
366b8a62b91Sopenharmony_ci    /// - `bpf_trace_printk` to print kernel memory is allowed
367b8a62b91Sopenharmony_ci    ///
368b8a62b91Sopenharmony_ci    /// [`Capability::SystemAdmin`] is required to use bpf_probe_write_user.
369b8a62b91Sopenharmony_ci    ///
370b8a62b91Sopenharmony_ci    /// [`Capability::SystemAdmin`] is required to iterate system wide loaded
371b8a62b91Sopenharmony_ci    /// programs, maps, links, BTFs and convert their IDs to file descriptors.
372b8a62b91Sopenharmony_ci    ///
373b8a62b91Sopenharmony_ci    /// [`Capability::PerformanceMonitoring`] and [`Capability::BerkeleyPacketFilters`] are required
374b8a62b91Sopenharmony_ci    /// to load tracing programs.
375b8a62b91Sopenharmony_ci    /// [`Capability::NetAdmin`] and [`Capability::BerkeleyPacketFilters`] are required to load
376b8a62b91Sopenharmony_ci    /// networking programs.
377b8a62b91Sopenharmony_ci    BerkeleyPacketFilters = CAP_BPF,
378b8a62b91Sopenharmony_ci    /// Allow checkpoint/restore related operations. Allow PID selection during `clone3`.
379b8a62b91Sopenharmony_ci    /// Allow writing to `ns_last_pid`.
380b8a62b91Sopenharmony_ci    CheckpointRestore = CAP_CHECKPOINT_RESTORE,
381b8a62b91Sopenharmony_ci}
382b8a62b91Sopenharmony_ci
383b8a62b91Sopenharmony_ci/// Check if the specified capability is in the calling thread's capability bounding set.
384b8a62b91Sopenharmony_ci///
385b8a62b91Sopenharmony_ci/// # References
386b8a62b91Sopenharmony_ci/// - [`prctl(PR_CAPBSET_READ,...)`]
387b8a62b91Sopenharmony_ci///
388b8a62b91Sopenharmony_ci/// [`prctl(PR_CAPBSET_READ,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
389b8a62b91Sopenharmony_ci#[inline]
390b8a62b91Sopenharmony_cipub fn is_in_capability_bounding_set(capability: Capability) -> io::Result<bool> {
391b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_CAPBSET_READ, capability as usize as *mut _) }.map(|r| r != 0)
392b8a62b91Sopenharmony_ci}
393b8a62b91Sopenharmony_ci
394b8a62b91Sopenharmony_ciconst PR_CAPBSET_DROP: c_int = 24;
395b8a62b91Sopenharmony_ci
396b8a62b91Sopenharmony_ci/// If the calling thread has the [`Capability::SetPermittedCapabilities`] capability within its
397b8a62b91Sopenharmony_ci/// user namespace, then drop the specified capability from the thread's capability bounding set.
398b8a62b91Sopenharmony_ci///
399b8a62b91Sopenharmony_ci/// # References
400b8a62b91Sopenharmony_ci/// - [`prctl(PR_CAPBSET_DROP,...)`]
401b8a62b91Sopenharmony_ci///
402b8a62b91Sopenharmony_ci/// [`prctl(PR_CAPBSET_DROP,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
403b8a62b91Sopenharmony_ci#[inline]
404b8a62b91Sopenharmony_cipub fn remove_capability_from_capability_bounding_set(capability: Capability) -> io::Result<()> {
405b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_CAPBSET_DROP, capability as usize as *mut _) }.map(|_r| ())
406b8a62b91Sopenharmony_ci}
407b8a62b91Sopenharmony_ci
408b8a62b91Sopenharmony_ci//
409b8a62b91Sopenharmony_ci// PR_GET_SECUREBITS/PR_SET_SECUREBITS
410b8a62b91Sopenharmony_ci//
411b8a62b91Sopenharmony_ci
412b8a62b91Sopenharmony_ciconst PR_GET_SECUREBITS: c_int = 27;
413b8a62b91Sopenharmony_ci
414b8a62b91Sopenharmony_cibitflags! {
415b8a62b91Sopenharmony_ci    /// `SECBIT_*`.
416b8a62b91Sopenharmony_ci    pub struct CapabilitiesSecureBits: u32 {
417b8a62b91Sopenharmony_ci        /// If this bit is set, then the kernel does not grant capabilities when
418b8a62b91Sopenharmony_ci        /// a `set-user-ID-root` program is executed, or when a process with an effective or real
419b8a62b91Sopenharmony_ci        /// UID of 0 calls `execve`.
420b8a62b91Sopenharmony_ci        const NO_ROOT = 1_u32 << 0;
421b8a62b91Sopenharmony_ci        /// Set [`NO_ROOT`] irreversibly.
422b8a62b91Sopenharmony_ci        const NO_ROOT_LOCKED = 1_u32 << 1;
423b8a62b91Sopenharmony_ci        /// Setting this flag stops the kernel from adjusting the process's permitted, effective,
424b8a62b91Sopenharmony_ci        /// and ambient capability sets when the thread's effective and filesystem UIDs are switched
425b8a62b91Sopenharmony_ci        /// between zero and nonzero values.
426b8a62b91Sopenharmony_ci        const NO_SETUID_FIXUP = 1_u32 << 2;
427b8a62b91Sopenharmony_ci        /// Set [`NO_SETUID_FIXUP`] irreversibly.
428b8a62b91Sopenharmony_ci        const NO_SETUID_FIXUP_LOCKED = 1_u32 << 3;
429b8a62b91Sopenharmony_ci        /// Setting this flag allows a thread that has one or more 0 UIDs to retain capabilities in
430b8a62b91Sopenharmony_ci        /// its permitted set when it switches all of its UIDs to nonzero values.
431b8a62b91Sopenharmony_ci        const KEEP_CAPS = 1_u32 << 4;
432b8a62b91Sopenharmony_ci        /// Set [`KEEP_CAPS`] irreversibly.
433b8a62b91Sopenharmony_ci        const KEEP_CAPS_LOCKED = 1_u32 << 5;
434b8a62b91Sopenharmony_ci        /// Setting this flag disallows raising ambient capabilities via the `prctl`'s
435b8a62b91Sopenharmony_ci        /// `PR_CAP_AMBIENT_RAISE` operation.
436b8a62b91Sopenharmony_ci        const NO_CAP_AMBIENT_RAISE = 1_u32 << 6;
437b8a62b91Sopenharmony_ci        /// Set [`NO_CAP_AMBIENT_RAISE`] irreversibly.
438b8a62b91Sopenharmony_ci        const NO_CAP_AMBIENT_RAISE_LOCKED = 1_u32 << 7;
439b8a62b91Sopenharmony_ci    }
440b8a62b91Sopenharmony_ci}
441b8a62b91Sopenharmony_ci
442b8a62b91Sopenharmony_ci/// Get the `securebits` flags of the calling thread.
443b8a62b91Sopenharmony_ci///
444b8a62b91Sopenharmony_ci/// # References
445b8a62b91Sopenharmony_ci/// - [`prctl(PR_GET_SECUREBITS,...)`]
446b8a62b91Sopenharmony_ci///
447b8a62b91Sopenharmony_ci/// [`prctl(PR_GET_SECUREBITS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
448b8a62b91Sopenharmony_ci#[inline]
449b8a62b91Sopenharmony_cipub fn capabilities_secure_bits() -> io::Result<CapabilitiesSecureBits> {
450b8a62b91Sopenharmony_ci    let r = unsafe { prctl_1arg(PR_GET_SECUREBITS)? } as c_uint;
451b8a62b91Sopenharmony_ci    CapabilitiesSecureBits::from_bits(r).ok_or(io::Errno::RANGE)
452b8a62b91Sopenharmony_ci}
453b8a62b91Sopenharmony_ci
454b8a62b91Sopenharmony_ciconst PR_SET_SECUREBITS: c_int = 28;
455b8a62b91Sopenharmony_ci
456b8a62b91Sopenharmony_ci/// Set the `securebits` flags of the calling thread.
457b8a62b91Sopenharmony_ci///
458b8a62b91Sopenharmony_ci/// # References
459b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_SECUREBITS,...)`]
460b8a62b91Sopenharmony_ci///
461b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_SECUREBITS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
462b8a62b91Sopenharmony_ci#[inline]
463b8a62b91Sopenharmony_cipub fn set_capabilities_secure_bits(bits: CapabilitiesSecureBits) -> io::Result<()> {
464b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_SET_SECUREBITS, bits.bits() as usize as *mut _) }.map(|_r| ())
465b8a62b91Sopenharmony_ci}
466b8a62b91Sopenharmony_ci
467b8a62b91Sopenharmony_ci//
468b8a62b91Sopenharmony_ci// PR_GET_TIMERSLACK/PR_SET_TIMERSLACK
469b8a62b91Sopenharmony_ci//
470b8a62b91Sopenharmony_ci
471b8a62b91Sopenharmony_ciconst PR_GET_TIMERSLACK: c_int = 30;
472b8a62b91Sopenharmony_ci
473b8a62b91Sopenharmony_ci/// Get the `current` timer slack value of the calling thread.
474b8a62b91Sopenharmony_ci///
475b8a62b91Sopenharmony_ci/// # References
476b8a62b91Sopenharmony_ci/// - [`prctl(PR_GET_TIMERSLACK,...)`]
477b8a62b91Sopenharmony_ci///
478b8a62b91Sopenharmony_ci/// [`prctl(PR_GET_TIMERSLACK,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
479b8a62b91Sopenharmony_ci#[inline]
480b8a62b91Sopenharmony_cipub fn current_timer_slack() -> io::Result<u64> {
481b8a62b91Sopenharmony_ci    unsafe { prctl_1arg(PR_GET_TIMERSLACK) }.map(|r| r as u64)
482b8a62b91Sopenharmony_ci}
483b8a62b91Sopenharmony_ci
484b8a62b91Sopenharmony_ciconst PR_SET_TIMERSLACK: c_int = 29;
485b8a62b91Sopenharmony_ci
486b8a62b91Sopenharmony_ci/// Sets the `current` timer slack value for the calling thread.
487b8a62b91Sopenharmony_ci///
488b8a62b91Sopenharmony_ci/// # References
489b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_TIMERSLACK,...)`]
490b8a62b91Sopenharmony_ci///
491b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_TIMERSLACK,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
492b8a62b91Sopenharmony_ci#[inline]
493b8a62b91Sopenharmony_cipub fn set_current_timer_slack(value: Option<NonZeroU64>) -> io::Result<()> {
494b8a62b91Sopenharmony_ci    let value = usize::try_from(value.map_or(0, NonZeroU64::get)).map_err(|_r| io::Errno::RANGE)?;
495b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_SET_TIMERSLACK, value as *mut _) }.map(|_r| ())
496b8a62b91Sopenharmony_ci}
497b8a62b91Sopenharmony_ci
498b8a62b91Sopenharmony_ci//
499b8a62b91Sopenharmony_ci// PR_GET_NO_NEW_PRIVS/PR_SET_NO_NEW_PRIVS
500b8a62b91Sopenharmony_ci//
501b8a62b91Sopenharmony_ci
502b8a62b91Sopenharmony_ciconst PR_GET_NO_NEW_PRIVS: c_int = 39;
503b8a62b91Sopenharmony_ci
504b8a62b91Sopenharmony_ci/// Get the value of the `no_new_privs` attribute for the calling thread.
505b8a62b91Sopenharmony_ci///
506b8a62b91Sopenharmony_ci/// # References
507b8a62b91Sopenharmony_ci/// - [`prctl(PR_GET_NO_NEW_PRIVS,...)`]
508b8a62b91Sopenharmony_ci///
509b8a62b91Sopenharmony_ci/// [`prctl(PR_GET_NO_NEW_PRIVS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
510b8a62b91Sopenharmony_ci#[inline]
511b8a62b91Sopenharmony_cipub fn no_new_privs() -> io::Result<bool> {
512b8a62b91Sopenharmony_ci    unsafe { prctl_1arg(PR_GET_NO_NEW_PRIVS) }.map(|r| r != 0)
513b8a62b91Sopenharmony_ci}
514b8a62b91Sopenharmony_ci
515b8a62b91Sopenharmony_ciconst PR_SET_NO_NEW_PRIVS: c_int = 38;
516b8a62b91Sopenharmony_ci
517b8a62b91Sopenharmony_ci/// Set the calling thread's `no_new_privs` attribute.
518b8a62b91Sopenharmony_ci///
519b8a62b91Sopenharmony_ci/// # References
520b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_NO_NEW_PRIVS,...)`]
521b8a62b91Sopenharmony_ci///
522b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_NO_NEW_PRIVS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
523b8a62b91Sopenharmony_ci#[inline]
524b8a62b91Sopenharmony_cipub fn set_no_new_privs(no_new_privs: bool) -> io::Result<()> {
525b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_SET_NO_NEW_PRIVS, no_new_privs as usize as *mut _) }.map(|_r| ())
526b8a62b91Sopenharmony_ci}
527b8a62b91Sopenharmony_ci
528b8a62b91Sopenharmony_ci//
529b8a62b91Sopenharmony_ci// PR_GET_TID_ADDRESS
530b8a62b91Sopenharmony_ci//
531b8a62b91Sopenharmony_ci
532b8a62b91Sopenharmony_ciconst PR_GET_TID_ADDRESS: c_int = 40;
533b8a62b91Sopenharmony_ci
534b8a62b91Sopenharmony_ci/// Get the `clear_child_tid` address set by `set_tid_address`
535b8a62b91Sopenharmony_ci/// and `clone`'s `CLONE_CHILD_CLEARTID` flag.
536b8a62b91Sopenharmony_ci///
537b8a62b91Sopenharmony_ci/// # References
538b8a62b91Sopenharmony_ci/// - [`prctl(PR_GET_TID_ADDRESS,...)`]
539b8a62b91Sopenharmony_ci///
540b8a62b91Sopenharmony_ci/// [`prctl(PR_GET_TID_ADDRESS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
541b8a62b91Sopenharmony_ci#[inline]
542b8a62b91Sopenharmony_cipub fn get_clear_child_tid_address() -> io::Result<Option<NonNull<c_void>>> {
543b8a62b91Sopenharmony_ci    unsafe { prctl_get_at_arg2_optional::<*mut c_void>(PR_GET_TID_ADDRESS) }.map(NonNull::new)
544b8a62b91Sopenharmony_ci}
545b8a62b91Sopenharmony_ci
546b8a62b91Sopenharmony_ci//
547b8a62b91Sopenharmony_ci// PR_GET_THP_DISABLE/PR_SET_THP_DISABLE
548b8a62b91Sopenharmony_ci//
549b8a62b91Sopenharmony_ci
550b8a62b91Sopenharmony_ciconst PR_GET_THP_DISABLE: c_int = 42;
551b8a62b91Sopenharmony_ci
552b8a62b91Sopenharmony_ci/// Get the current setting of the `THP disable` flag for the calling thread.
553b8a62b91Sopenharmony_ci///
554b8a62b91Sopenharmony_ci/// # References
555b8a62b91Sopenharmony_ci/// - [`prctl(PR_GET_THP_DISABLE,...)`]
556b8a62b91Sopenharmony_ci///
557b8a62b91Sopenharmony_ci/// [`prctl(PR_GET_THP_DISABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
558b8a62b91Sopenharmony_ci#[inline]
559b8a62b91Sopenharmony_cipub fn transparent_huge_pages_are_disabled() -> io::Result<bool> {
560b8a62b91Sopenharmony_ci    unsafe { prctl_1arg(PR_GET_THP_DISABLE) }.map(|r| r != 0)
561b8a62b91Sopenharmony_ci}
562b8a62b91Sopenharmony_ci
563b8a62b91Sopenharmony_ciconst PR_SET_THP_DISABLE: c_int = 41;
564b8a62b91Sopenharmony_ci
565b8a62b91Sopenharmony_ci/// Set the state of the `THP disable` flag for the calling thread.
566b8a62b91Sopenharmony_ci///
567b8a62b91Sopenharmony_ci/// # References
568b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_THP_DISABLE,...)`]
569b8a62b91Sopenharmony_ci///
570b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_THP_DISABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
571b8a62b91Sopenharmony_ci#[inline]
572b8a62b91Sopenharmony_cipub fn disable_transparent_huge_pages(thp_disable: bool) -> io::Result<()> {
573b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_SET_THP_DISABLE, thp_disable as usize as *mut _) }.map(|_r| ())
574b8a62b91Sopenharmony_ci}
575b8a62b91Sopenharmony_ci
576b8a62b91Sopenharmony_ci//
577b8a62b91Sopenharmony_ci// PR_CAP_AMBIENT
578b8a62b91Sopenharmony_ci//
579b8a62b91Sopenharmony_ci
580b8a62b91Sopenharmony_ciconst PR_CAP_AMBIENT: c_int = 47;
581b8a62b91Sopenharmony_ci
582b8a62b91Sopenharmony_ciconst PR_CAP_AMBIENT_IS_SET: usize = 1;
583b8a62b91Sopenharmony_ci
584b8a62b91Sopenharmony_ci/// Check if the specified capability is in the ambient set.
585b8a62b91Sopenharmony_ci///
586b8a62b91Sopenharmony_ci/// # References
587b8a62b91Sopenharmony_ci/// - [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_IS_SET,...)`]
588b8a62b91Sopenharmony_ci///
589b8a62b91Sopenharmony_ci/// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_IS_SET,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
590b8a62b91Sopenharmony_ci#[inline]
591b8a62b91Sopenharmony_cipub fn capability_is_in_ambient_capability_set(capability: Capability) -> io::Result<bool> {
592b8a62b91Sopenharmony_ci    let cap = capability as usize as *mut _;
593b8a62b91Sopenharmony_ci    unsafe { prctl_3args(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET as *mut _, cap) }.map(|r| r != 0)
594b8a62b91Sopenharmony_ci}
595b8a62b91Sopenharmony_ci
596b8a62b91Sopenharmony_ciconst PR_CAP_AMBIENT_CLEAR_ALL: usize = 4;
597b8a62b91Sopenharmony_ci
598b8a62b91Sopenharmony_ci/// Remove all capabilities from the ambient set.
599b8a62b91Sopenharmony_ci///
600b8a62b91Sopenharmony_ci/// # References
601b8a62b91Sopenharmony_ci/// - [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_CLEAR_ALL,...)`]
602b8a62b91Sopenharmony_ci///
603b8a62b91Sopenharmony_ci/// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_CLEAR_ALL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
604b8a62b91Sopenharmony_ci#[inline]
605b8a62b91Sopenharmony_cipub fn clear_ambient_capability_set() -> io::Result<()> {
606b8a62b91Sopenharmony_ci    unsafe { prctl_2args(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL as *mut _) }.map(|_r| ())
607b8a62b91Sopenharmony_ci}
608b8a62b91Sopenharmony_ci
609b8a62b91Sopenharmony_ciconst PR_CAP_AMBIENT_RAISE: usize = 2;
610b8a62b91Sopenharmony_ciconst PR_CAP_AMBIENT_LOWER: usize = 3;
611b8a62b91Sopenharmony_ci
612b8a62b91Sopenharmony_ci/// Add or remove the specified capability to the ambient set.
613b8a62b91Sopenharmony_ci///
614b8a62b91Sopenharmony_ci/// # References
615b8a62b91Sopenharmony_ci/// - [`prctl(PR_CAP_AMBIENT,...)`]
616b8a62b91Sopenharmony_ci///
617b8a62b91Sopenharmony_ci/// [`prctl(PR_CAP_AMBIENT,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
618b8a62b91Sopenharmony_ci#[inline]
619b8a62b91Sopenharmony_cipub fn configure_capability_in_ambient_capability_set(
620b8a62b91Sopenharmony_ci    capability: Capability,
621b8a62b91Sopenharmony_ci    enable: bool,
622b8a62b91Sopenharmony_ci) -> io::Result<()> {
623b8a62b91Sopenharmony_ci    let sub_operation = if enable {
624b8a62b91Sopenharmony_ci        PR_CAP_AMBIENT_RAISE
625b8a62b91Sopenharmony_ci    } else {
626b8a62b91Sopenharmony_ci        PR_CAP_AMBIENT_LOWER
627b8a62b91Sopenharmony_ci    };
628b8a62b91Sopenharmony_ci    let cap = capability as usize as *mut _;
629b8a62b91Sopenharmony_ci
630b8a62b91Sopenharmony_ci    unsafe { prctl_3args(PR_CAP_AMBIENT, sub_operation as *mut _, cap) }.map(|_r| ())
631b8a62b91Sopenharmony_ci}
632b8a62b91Sopenharmony_ci
633b8a62b91Sopenharmony_ci//
634b8a62b91Sopenharmony_ci// PR_SVE_GET_VL/PR_SVE_SET_VL
635b8a62b91Sopenharmony_ci//
636b8a62b91Sopenharmony_ci
637b8a62b91Sopenharmony_ciconst PR_SVE_GET_VL: c_int = 51;
638b8a62b91Sopenharmony_ci
639b8a62b91Sopenharmony_ciconst PR_SVE_VL_LEN_MASK: u32 = 0xffff;
640b8a62b91Sopenharmony_ciconst PR_SVE_VL_INHERIT: u32 = 1_u32 << 17;
641b8a62b91Sopenharmony_ci
642b8a62b91Sopenharmony_ci/// Scalable Vector Extension vector length configuration.
643b8a62b91Sopenharmony_ci#[derive(Copy, Clone, Debug, Eq, PartialEq)]
644b8a62b91Sopenharmony_cipub struct SVEVectorLengthConfig {
645b8a62b91Sopenharmony_ci    /// Vector length in bytes.
646b8a62b91Sopenharmony_ci    pub vector_length_in_bytes: u32,
647b8a62b91Sopenharmony_ci    /// Vector length inherited across `execve`.
648b8a62b91Sopenharmony_ci    pub vector_length_inherited_across_execve: bool,
649b8a62b91Sopenharmony_ci}
650b8a62b91Sopenharmony_ci
651b8a62b91Sopenharmony_ci/// Get the thread's current SVE vector length configuration.
652b8a62b91Sopenharmony_ci///
653b8a62b91Sopenharmony_ci/// # References
654b8a62b91Sopenharmony_ci/// - [`prctl(PR_SVE_GET_VL,...)`]
655b8a62b91Sopenharmony_ci///
656b8a62b91Sopenharmony_ci/// [`prctl(PR_SVE_GET_VL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
657b8a62b91Sopenharmony_ci#[inline]
658b8a62b91Sopenharmony_cipub fn sve_vector_length_configuration() -> io::Result<SVEVectorLengthConfig> {
659b8a62b91Sopenharmony_ci    let bits = unsafe { prctl_1arg(PR_SVE_GET_VL)? } as c_uint;
660b8a62b91Sopenharmony_ci    Ok(SVEVectorLengthConfig {
661b8a62b91Sopenharmony_ci        vector_length_in_bytes: bits & PR_SVE_VL_LEN_MASK,
662b8a62b91Sopenharmony_ci        vector_length_inherited_across_execve: (bits & PR_SVE_VL_INHERIT) != 0,
663b8a62b91Sopenharmony_ci    })
664b8a62b91Sopenharmony_ci}
665b8a62b91Sopenharmony_ci
666b8a62b91Sopenharmony_ciconst PR_SVE_SET_VL: c_int = 50;
667b8a62b91Sopenharmony_ci
668b8a62b91Sopenharmony_ciconst PR_SVE_SET_VL_ONEXEC: u32 = 1_u32 << 18;
669b8a62b91Sopenharmony_ci
670b8a62b91Sopenharmony_ci/// Configure the thread's vector length of Scalable Vector Extension.
671b8a62b91Sopenharmony_ci///
672b8a62b91Sopenharmony_ci/// # References
673b8a62b91Sopenharmony_ci/// - [`prctl(PR_SVE_SET_VL,...)`]
674b8a62b91Sopenharmony_ci///
675b8a62b91Sopenharmony_ci/// # Safety
676b8a62b91Sopenharmony_ci///
677b8a62b91Sopenharmony_ci/// Please ensure the conditions necessary to safely call this function,
678b8a62b91Sopenharmony_ci/// as detailed in the references above.
679b8a62b91Sopenharmony_ci///
680b8a62b91Sopenharmony_ci/// [`prctl(PR_SVE_SET_VL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
681b8a62b91Sopenharmony_ci#[inline]
682b8a62b91Sopenharmony_cipub unsafe fn set_sve_vector_length_configuration(
683b8a62b91Sopenharmony_ci    vector_length_in_bytes: usize,
684b8a62b91Sopenharmony_ci    vector_length_inherited_across_execve: bool,
685b8a62b91Sopenharmony_ci    defer_change_to_next_execve: bool,
686b8a62b91Sopenharmony_ci) -> io::Result<()> {
687b8a62b91Sopenharmony_ci    let vector_length_in_bytes =
688b8a62b91Sopenharmony_ci        u32::try_from(vector_length_in_bytes).map_err(|_r| io::Errno::RANGE)?;
689b8a62b91Sopenharmony_ci
690b8a62b91Sopenharmony_ci    let mut bits = vector_length_in_bytes & PR_SVE_VL_LEN_MASK;
691b8a62b91Sopenharmony_ci
692b8a62b91Sopenharmony_ci    if vector_length_inherited_across_execve {
693b8a62b91Sopenharmony_ci        bits |= PR_SVE_VL_INHERIT;
694b8a62b91Sopenharmony_ci    }
695b8a62b91Sopenharmony_ci
696b8a62b91Sopenharmony_ci    if defer_change_to_next_execve {
697b8a62b91Sopenharmony_ci        bits |= PR_SVE_SET_VL_ONEXEC;
698b8a62b91Sopenharmony_ci    }
699b8a62b91Sopenharmony_ci
700b8a62b91Sopenharmony_ci    prctl_2args(PR_SVE_SET_VL, bits as usize as *mut _).map(|_r| ())
701b8a62b91Sopenharmony_ci}
702b8a62b91Sopenharmony_ci
703b8a62b91Sopenharmony_ci//
704b8a62b91Sopenharmony_ci// PR_PAC_RESET_KEYS
705b8a62b91Sopenharmony_ci//
706b8a62b91Sopenharmony_ci
707b8a62b91Sopenharmony_ciconst PR_PAC_RESET_KEYS: c_int = 54;
708b8a62b91Sopenharmony_ci
709b8a62b91Sopenharmony_ci/// Securely reset the thread's pointer authentication keys to fresh random values generated
710b8a62b91Sopenharmony_ci/// by the kernel.
711b8a62b91Sopenharmony_ci///
712b8a62b91Sopenharmony_ci/// # References
713b8a62b91Sopenharmony_ci/// - [`prctl(PR_PAC_RESET_KEYS,...)`]
714b8a62b91Sopenharmony_ci///
715b8a62b91Sopenharmony_ci/// # Safety
716b8a62b91Sopenharmony_ci///
717b8a62b91Sopenharmony_ci/// Please ensure the conditions necessary to safely call this function,
718b8a62b91Sopenharmony_ci/// as detailed in the references above.
719b8a62b91Sopenharmony_ci///
720b8a62b91Sopenharmony_ci/// [`prctl(PR_PAC_RESET_KEYS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
721b8a62b91Sopenharmony_ci#[inline]
722b8a62b91Sopenharmony_cipub unsafe fn reset_pointer_authentication_keys(
723b8a62b91Sopenharmony_ci    keys: Option<PointerAuthenticationKeys>,
724b8a62b91Sopenharmony_ci) -> io::Result<()> {
725b8a62b91Sopenharmony_ci    let keys = keys.as_ref().map_or(0_u32, PointerAuthenticationKeys::bits);
726b8a62b91Sopenharmony_ci    prctl_2args(PR_PAC_RESET_KEYS, keys as usize as *mut _).map(|_r| ())
727b8a62b91Sopenharmony_ci}
728b8a62b91Sopenharmony_ci
729b8a62b91Sopenharmony_ci//
730b8a62b91Sopenharmony_ci// PR_GET_TAGGED_ADDR_CTRL/PR_SET_TAGGED_ADDR_CTRL
731b8a62b91Sopenharmony_ci//
732b8a62b91Sopenharmony_ci
733b8a62b91Sopenharmony_ciconst PR_GET_TAGGED_ADDR_CTRL: c_int = 56;
734b8a62b91Sopenharmony_ci
735b8a62b91Sopenharmony_ciconst PR_MTE_TAG_SHIFT: u32 = 3;
736b8a62b91Sopenharmony_ciconst PR_MTE_TAG_MASK: u32 = 0xffff_u32 << PR_MTE_TAG_SHIFT;
737b8a62b91Sopenharmony_ci
738b8a62b91Sopenharmony_cibitflags! {
739b8a62b91Sopenharmony_ci    /// Zero means addresses that are passed for the purpose of being dereferenced by the kernel must be untagged.
740b8a62b91Sopenharmony_ci    pub struct TaggedAddressMode: u32 {
741b8a62b91Sopenharmony_ci        /// Addresses that are passed for the purpose of being dereferenced by the kernel may be tagged.
742b8a62b91Sopenharmony_ci        const ENABLED = 1_u32 << 0;
743b8a62b91Sopenharmony_ci        /// Synchronous tag check fault mode.
744b8a62b91Sopenharmony_ci        const TCF_SYNC = 1_u32 << 1;
745b8a62b91Sopenharmony_ci        /// Asynchronous tag check fault mode.
746b8a62b91Sopenharmony_ci        const TCF_ASYNC = 1_u32 << 2;
747b8a62b91Sopenharmony_ci    }
748b8a62b91Sopenharmony_ci}
749b8a62b91Sopenharmony_ci
750b8a62b91Sopenharmony_ci/// Get the current tagged address mode for the calling thread.
751b8a62b91Sopenharmony_ci///
752b8a62b91Sopenharmony_ci/// # References
753b8a62b91Sopenharmony_ci/// - [`prctl(PR_GET_TAGGED_ADDR_CTRL,...)`]
754b8a62b91Sopenharmony_ci///
755b8a62b91Sopenharmony_ci/// [`prctl(PR_GET_TAGGED_ADDR_CTRL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
756b8a62b91Sopenharmony_ci#[inline]
757b8a62b91Sopenharmony_cipub fn current_tagged_address_mode() -> io::Result<(Option<TaggedAddressMode>, u32)> {
758b8a62b91Sopenharmony_ci    let r = unsafe { prctl_1arg(PR_GET_TAGGED_ADDR_CTRL)? } as c_uint;
759b8a62b91Sopenharmony_ci    let mode = r & 0b111_u32;
760b8a62b91Sopenharmony_ci    let mte_tag = (r & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT;
761b8a62b91Sopenharmony_ci    Ok((TaggedAddressMode::from_bits(mode), mte_tag))
762b8a62b91Sopenharmony_ci}
763b8a62b91Sopenharmony_ci
764b8a62b91Sopenharmony_ciconst PR_SET_TAGGED_ADDR_CTRL: c_int = 55;
765b8a62b91Sopenharmony_ci
766b8a62b91Sopenharmony_ci/// Controls support for passing tagged user-space addresses to the kernel.
767b8a62b91Sopenharmony_ci///
768b8a62b91Sopenharmony_ci/// # References
769b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_TAGGED_ADDR_CTRL,...)`]
770b8a62b91Sopenharmony_ci///
771b8a62b91Sopenharmony_ci/// # Safety
772b8a62b91Sopenharmony_ci///
773b8a62b91Sopenharmony_ci/// Please ensure the conditions necessary to safely call this function,
774b8a62b91Sopenharmony_ci/// as detailed in the references above.
775b8a62b91Sopenharmony_ci///
776b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_TAGGED_ADDR_CTRL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
777b8a62b91Sopenharmony_ci#[inline]
778b8a62b91Sopenharmony_cipub unsafe fn set_current_tagged_address_mode(
779b8a62b91Sopenharmony_ci    mode: Option<TaggedAddressMode>,
780b8a62b91Sopenharmony_ci    mte_tag: u32,
781b8a62b91Sopenharmony_ci) -> io::Result<()> {
782b8a62b91Sopenharmony_ci    let config = mode.as_ref().map_or(0_u32, TaggedAddressMode::bits)
783b8a62b91Sopenharmony_ci        | ((mte_tag << PR_MTE_TAG_SHIFT) & PR_MTE_TAG_MASK);
784b8a62b91Sopenharmony_ci    prctl_2args(PR_SET_TAGGED_ADDR_CTRL, config as usize as *mut _).map(|_r| ())
785b8a62b91Sopenharmony_ci}
786b8a62b91Sopenharmony_ci
787b8a62b91Sopenharmony_ci//
788b8a62b91Sopenharmony_ci// PR_SET_SYSCALL_USER_DISPATCH
789b8a62b91Sopenharmony_ci//
790b8a62b91Sopenharmony_ci
791b8a62b91Sopenharmony_ciconst PR_SET_SYSCALL_USER_DISPATCH: c_int = 59;
792b8a62b91Sopenharmony_ci
793b8a62b91Sopenharmony_ciconst PR_SYS_DISPATCH_OFF: usize = 0;
794b8a62b91Sopenharmony_ci
795b8a62b91Sopenharmony_ci/// Disable Syscall User Dispatch mechanism.
796b8a62b91Sopenharmony_ci///
797b8a62b91Sopenharmony_ci/// # References
798b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_OFF,...)`]
799b8a62b91Sopenharmony_ci///
800b8a62b91Sopenharmony_ci/// # Safety
801b8a62b91Sopenharmony_ci///
802b8a62b91Sopenharmony_ci/// Please ensure the conditions necessary to safely call this function,
803b8a62b91Sopenharmony_ci/// as detailed in the references above.
804b8a62b91Sopenharmony_ci///
805b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_OFF,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
806b8a62b91Sopenharmony_ci#[inline]
807b8a62b91Sopenharmony_cipub unsafe fn disable_syscall_user_dispatch() -> io::Result<()> {
808b8a62b91Sopenharmony_ci    prctl_2args(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_OFF as *mut _).map(|_r| ())
809b8a62b91Sopenharmony_ci}
810b8a62b91Sopenharmony_ci
811b8a62b91Sopenharmony_ciconst PR_SYS_DISPATCH_ON: usize = 1;
812b8a62b91Sopenharmony_ci
813b8a62b91Sopenharmony_ci/// Allow system calls to be executed.
814b8a62b91Sopenharmony_ciconst SYSCALL_DISPATCH_FILTER_ALLOW: u8 = 0;
815b8a62b91Sopenharmony_ci/// Block system calls from executing.
816b8a62b91Sopenharmony_ciconst SYSCALL_DISPATCH_FILTER_BLOCK: u8 = 1;
817b8a62b91Sopenharmony_ci
818b8a62b91Sopenharmony_ci/// Value of the fast switch flag controlling system calls user dispatch mechanism without the need
819b8a62b91Sopenharmony_ci/// to issue a syscall.
820b8a62b91Sopenharmony_ci#[derive(Copy, Clone, Debug, Eq, PartialEq)]
821b8a62b91Sopenharmony_ci#[repr(u8)]
822b8a62b91Sopenharmony_cipub enum SysCallUserDispatchFastSwitch {
823b8a62b91Sopenharmony_ci    /// System calls are allowed to execute.
824b8a62b91Sopenharmony_ci    Allow = SYSCALL_DISPATCH_FILTER_ALLOW,
825b8a62b91Sopenharmony_ci    /// System calls are blocked from executing.
826b8a62b91Sopenharmony_ci    Block = SYSCALL_DISPATCH_FILTER_BLOCK,
827b8a62b91Sopenharmony_ci}
828b8a62b91Sopenharmony_ci
829b8a62b91Sopenharmony_ciimpl TryFrom<u8> for SysCallUserDispatchFastSwitch {
830b8a62b91Sopenharmony_ci    type Error = io::Errno;
831b8a62b91Sopenharmony_ci
832b8a62b91Sopenharmony_ci    fn try_from(value: u8) -> Result<Self, Self::Error> {
833b8a62b91Sopenharmony_ci        match value {
834b8a62b91Sopenharmony_ci            SYSCALL_DISPATCH_FILTER_ALLOW => Ok(Self::Allow),
835b8a62b91Sopenharmony_ci            SYSCALL_DISPATCH_FILTER_BLOCK => Ok(Self::Block),
836b8a62b91Sopenharmony_ci            _ => Err(io::Errno::RANGE),
837b8a62b91Sopenharmony_ci        }
838b8a62b91Sopenharmony_ci    }
839b8a62b91Sopenharmony_ci}
840b8a62b91Sopenharmony_ci
841b8a62b91Sopenharmony_ci/// Enable Syscall User Dispatch mechanism.
842b8a62b91Sopenharmony_ci///
843b8a62b91Sopenharmony_ci/// # References
844b8a62b91Sopenharmony_ci/// - [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_ON,...)`]
845b8a62b91Sopenharmony_ci///
846b8a62b91Sopenharmony_ci/// # Safety
847b8a62b91Sopenharmony_ci///
848b8a62b91Sopenharmony_ci/// Please ensure the conditions necessary to safely call this function,
849b8a62b91Sopenharmony_ci/// as detailed in the references above.
850b8a62b91Sopenharmony_ci///
851b8a62b91Sopenharmony_ci/// [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_ON,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
852b8a62b91Sopenharmony_ci#[inline]
853b8a62b91Sopenharmony_cipub unsafe fn enable_syscall_user_dispatch(
854b8a62b91Sopenharmony_ci    always_allowed_region: &[u8],
855b8a62b91Sopenharmony_ci    fast_switch_flag: &AtomicU8,
856b8a62b91Sopenharmony_ci) -> io::Result<()> {
857b8a62b91Sopenharmony_ci    syscalls::prctl(
858b8a62b91Sopenharmony_ci        PR_SET_SYSCALL_USER_DISPATCH,
859b8a62b91Sopenharmony_ci        PR_SYS_DISPATCH_ON as *mut _,
860b8a62b91Sopenharmony_ci        always_allowed_region.as_ptr() as *mut _,
861b8a62b91Sopenharmony_ci        always_allowed_region.len() as *mut _,
862b8a62b91Sopenharmony_ci        fast_switch_flag as *const AtomicU8 as *mut _,
863b8a62b91Sopenharmony_ci    )
864b8a62b91Sopenharmony_ci    .map(|_r| ())
865b8a62b91Sopenharmony_ci}
866b8a62b91Sopenharmony_ci
867b8a62b91Sopenharmony_ci//
868b8a62b91Sopenharmony_ci// PR_SCHED_CORE
869b8a62b91Sopenharmony_ci//
870b8a62b91Sopenharmony_ci
871b8a62b91Sopenharmony_ciconst PR_SCHED_CORE: c_int = 62;
872b8a62b91Sopenharmony_ci
873b8a62b91Sopenharmony_ciconst PR_SCHED_CORE_GET: usize = 0;
874b8a62b91Sopenharmony_ci
875b8a62b91Sopenharmony_ciconst PR_SCHED_CORE_SCOPE_THREAD: u32 = 0;
876b8a62b91Sopenharmony_ciconst PR_SCHED_CORE_SCOPE_THREAD_GROUP: u32 = 1;
877b8a62b91Sopenharmony_ciconst PR_SCHED_CORE_SCOPE_PROCESS_GROUP: u32 = 2;
878b8a62b91Sopenharmony_ci
879b8a62b91Sopenharmony_ci/// `PR_SCHED_CORE_SCOPE_*`.
880b8a62b91Sopenharmony_ci#[derive(Copy, Clone, Debug, Eq, PartialEq)]
881b8a62b91Sopenharmony_ci#[repr(u32)]
882b8a62b91Sopenharmony_cipub enum CoreSchedulingScope {
883b8a62b91Sopenharmony_ci    /// Operation will be performed for the thread.
884b8a62b91Sopenharmony_ci    Thread = PR_SCHED_CORE_SCOPE_THREAD,
885b8a62b91Sopenharmony_ci    /// Operation will be performed for all tasks in the task group of the process.
886b8a62b91Sopenharmony_ci    ThreadGroup = PR_SCHED_CORE_SCOPE_THREAD_GROUP,
887b8a62b91Sopenharmony_ci    /// Operation will be performed for all processes in the process group.
888b8a62b91Sopenharmony_ci    ProcessGroup = PR_SCHED_CORE_SCOPE_PROCESS_GROUP,
889b8a62b91Sopenharmony_ci}
890b8a62b91Sopenharmony_ci
891b8a62b91Sopenharmony_ciimpl TryFrom<u32> for CoreSchedulingScope {
892b8a62b91Sopenharmony_ci    type Error = io::Errno;
893b8a62b91Sopenharmony_ci
894b8a62b91Sopenharmony_ci    fn try_from(value: u32) -> Result<Self, Self::Error> {
895b8a62b91Sopenharmony_ci        match value {
896b8a62b91Sopenharmony_ci            PR_SCHED_CORE_SCOPE_THREAD => Ok(Self::Thread),
897b8a62b91Sopenharmony_ci            PR_SCHED_CORE_SCOPE_THREAD_GROUP => Ok(Self::ThreadGroup),
898b8a62b91Sopenharmony_ci            PR_SCHED_CORE_SCOPE_PROCESS_GROUP => Ok(Self::ProcessGroup),
899b8a62b91Sopenharmony_ci            _ => Err(io::Errno::RANGE),
900b8a62b91Sopenharmony_ci        }
901b8a62b91Sopenharmony_ci    }
902b8a62b91Sopenharmony_ci}
903b8a62b91Sopenharmony_ci
904b8a62b91Sopenharmony_ci/// Get core scheduling cookie of a process.
905b8a62b91Sopenharmony_ci///
906b8a62b91Sopenharmony_ci/// # References
907b8a62b91Sopenharmony_ci/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_GET,...)`]
908b8a62b91Sopenharmony_ci///
909b8a62b91Sopenharmony_ci/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_GET,...)`]: https://www.kernel.org/doc/html/v5.18/admin-guide/hw-vuln/core-scheduling.html
910b8a62b91Sopenharmony_ci#[inline]
911b8a62b91Sopenharmony_cipub fn core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<u64> {
912b8a62b91Sopenharmony_ci    let mut value: MaybeUninit<u64> = MaybeUninit::uninit();
913b8a62b91Sopenharmony_ci    unsafe {
914b8a62b91Sopenharmony_ci        syscalls::prctl(
915b8a62b91Sopenharmony_ci            PR_SCHED_CORE,
916b8a62b91Sopenharmony_ci            PR_SCHED_CORE_GET as *mut _,
917b8a62b91Sopenharmony_ci            pid.as_raw_nonzero().get() as usize as *mut _,
918b8a62b91Sopenharmony_ci            scope as usize as *mut _,
919b8a62b91Sopenharmony_ci            value.as_mut_ptr().cast(),
920b8a62b91Sopenharmony_ci        )?;
921b8a62b91Sopenharmony_ci        Ok(value.assume_init())
922b8a62b91Sopenharmony_ci    }
923b8a62b91Sopenharmony_ci}
924b8a62b91Sopenharmony_ci
925b8a62b91Sopenharmony_ciconst PR_SCHED_CORE_CREATE: usize = 1;
926b8a62b91Sopenharmony_ci
927b8a62b91Sopenharmony_ci/// Create unique core scheduling cookie.
928b8a62b91Sopenharmony_ci///
929b8a62b91Sopenharmony_ci/// # References
930b8a62b91Sopenharmony_ci/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_CREATE,...)`]
931b8a62b91Sopenharmony_ci///
932b8a62b91Sopenharmony_ci/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_CREATE,...)`]: https://www.kernel.org/doc/html/v5.18/admin-guide/hw-vuln/core-scheduling.html
933b8a62b91Sopenharmony_ci#[inline]
934b8a62b91Sopenharmony_cipub fn create_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<()> {
935b8a62b91Sopenharmony_ci    unsafe {
936b8a62b91Sopenharmony_ci        syscalls::prctl(
937b8a62b91Sopenharmony_ci            PR_SCHED_CORE,
938b8a62b91Sopenharmony_ci            PR_SCHED_CORE_CREATE as *mut _,
939b8a62b91Sopenharmony_ci            pid.as_raw_nonzero().get() as usize as *mut _,
940b8a62b91Sopenharmony_ci            scope as usize as *mut _,
941b8a62b91Sopenharmony_ci            ptr::null_mut(),
942b8a62b91Sopenharmony_ci        )
943b8a62b91Sopenharmony_ci        .map(|_r| ())
944b8a62b91Sopenharmony_ci    }
945b8a62b91Sopenharmony_ci}
946b8a62b91Sopenharmony_ci
947b8a62b91Sopenharmony_ciconst PR_SCHED_CORE_SHARE_TO: usize = 2;
948b8a62b91Sopenharmony_ci
949b8a62b91Sopenharmony_ci/// Push core scheduling cookie to a process.
950b8a62b91Sopenharmony_ci///
951b8a62b91Sopenharmony_ci/// # References
952b8a62b91Sopenharmony_ci/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_TO,...)`]
953b8a62b91Sopenharmony_ci///
954b8a62b91Sopenharmony_ci/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_TO,...)`]: https://www.kernel.org/doc/html/v5.18/admin-guide/hw-vuln/core-scheduling.html
955b8a62b91Sopenharmony_ci#[inline]
956b8a62b91Sopenharmony_cipub fn push_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<()> {
957b8a62b91Sopenharmony_ci    unsafe {
958b8a62b91Sopenharmony_ci        syscalls::prctl(
959b8a62b91Sopenharmony_ci            PR_SCHED_CORE,
960b8a62b91Sopenharmony_ci            PR_SCHED_CORE_SHARE_TO as *mut _,
961b8a62b91Sopenharmony_ci            pid.as_raw_nonzero().get() as usize as *mut _,
962b8a62b91Sopenharmony_ci            scope as usize as *mut _,
963b8a62b91Sopenharmony_ci            ptr::null_mut(),
964b8a62b91Sopenharmony_ci        )
965b8a62b91Sopenharmony_ci        .map(|_r| ())
966b8a62b91Sopenharmony_ci    }
967b8a62b91Sopenharmony_ci}
968b8a62b91Sopenharmony_ci
969b8a62b91Sopenharmony_ciconst PR_SCHED_CORE_SHARE_FROM: usize = 3;
970b8a62b91Sopenharmony_ci
971b8a62b91Sopenharmony_ci/// Pull core scheduling cookie from a process.
972b8a62b91Sopenharmony_ci///
973b8a62b91Sopenharmony_ci/// # References
974b8a62b91Sopenharmony_ci/// - [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_FROM,...)`]
975b8a62b91Sopenharmony_ci///
976b8a62b91Sopenharmony_ci/// [`prctl(PR_SCHED_CORE,PR_SCHED_CORE_SHARE_FROM,...)`]: https://www.kernel.org/doc/html/v5.18/admin-guide/hw-vuln/core-scheduling.html
977b8a62b91Sopenharmony_ci#[inline]
978b8a62b91Sopenharmony_cipub fn pull_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Result<()> {
979b8a62b91Sopenharmony_ci    unsafe {
980b8a62b91Sopenharmony_ci        syscalls::prctl(
981b8a62b91Sopenharmony_ci            PR_SCHED_CORE,
982b8a62b91Sopenharmony_ci            PR_SCHED_CORE_SHARE_FROM as *mut _,
983b8a62b91Sopenharmony_ci            pid.as_raw_nonzero().get() as usize as *mut _,
984b8a62b91Sopenharmony_ci            scope as usize as *mut _,
985b8a62b91Sopenharmony_ci            ptr::null_mut(),
986b8a62b91Sopenharmony_ci        )
987b8a62b91Sopenharmony_ci        .map(|_r| ())
988b8a62b91Sopenharmony_ci    }
989b8a62b91Sopenharmony_ci}
990