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