aboutsummaryrefslogtreecommitdiff
path: root/vendor/rustix/src/process/prctl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/process/prctl.rs')
-rw-r--r--vendor/rustix/src/process/prctl.rs1151
1 files changed, 0 insertions, 1151 deletions
diff --git a/vendor/rustix/src/process/prctl.rs b/vendor/rustix/src/process/prctl.rs
deleted file mode 100644
index 830abc1..0000000
--- a/vendor/rustix/src/process/prctl.rs
+++ /dev/null
@@ -1,1151 +0,0 @@
-//! Bindings for the Linux `prctl` system call.
-//!
-//! There are similarities (but also differences) with FreeBSD's `procctl`
-//! system call, whose interface is located in the `procctl.rs` file.
-
-#![allow(unsafe_code)]
-
-use core::mem::size_of;
-use core::ptr::{null, null_mut, NonNull};
-
-use bitflags::bitflags;
-
-use crate::backend::c::{c_int, c_uint, c_void};
-use crate::backend::prctl::syscalls;
-use crate::fd::{AsRawFd, BorrowedFd};
-use crate::ffi::CStr;
-use crate::io;
-use crate::prctl::*;
-use crate::process::{Pid, RawPid};
-use crate::signal::Signal;
-use crate::utils::{as_mut_ptr, as_ptr};
-
-//
-// PR_GET_PDEATHSIG/PR_SET_PDEATHSIG
-//
-
-const PR_GET_PDEATHSIG: c_int = 2;
-
-/// Get the current value of the parent process death signal.
-///
-/// # References
-/// - [Linux: `prctl(PR_GET_PDEATHSIG,...)`]
-/// - [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`]
-///
-/// [Linux: `prctl(PR_GET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-/// [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2
-#[inline]
-#[doc(alias = "PR_GET_PDEATHSIG")]
-pub fn parent_process_death_signal() -> io::Result<Option<Signal>> {
- unsafe { prctl_get_at_arg2_optional::<c_int>(PR_GET_PDEATHSIG) }.map(Signal::from_raw)
-}
-
-const PR_SET_PDEATHSIG: c_int = 1;
-
-/// Set the parent-death signal of the calling process.
-///
-/// # References
-/// - [Linux: `prctl(PR_SET_PDEATHSIG,...)`]
-/// - [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`]
-///
-/// [Linux: `prctl(PR_SET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-/// [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2
-#[inline]
-#[doc(alias = "PR_SET_PDEATHSIG")]
-pub fn set_parent_process_death_signal(signal: Option<Signal>) -> io::Result<()> {
- let signal = signal.map_or(0_usize, |signal| signal as usize);
- unsafe { prctl_2args(PR_SET_PDEATHSIG, signal as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_GET_DUMPABLE/PR_SET_DUMPABLE
-//
-
-const PR_GET_DUMPABLE: c_int = 3;
-
-const SUID_DUMP_DISABLE: i32 = 0;
-const SUID_DUMP_USER: i32 = 1;
-const SUID_DUMP_ROOT: i32 = 2;
-
-/// `SUID_DUMP_*` values for use with [`dumpable_behavior`] and
-/// [`set_dumpable_behavior`].
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(i32)]
-pub enum DumpableBehavior {
- /// Not dumpable.
- #[doc(alias = "SUID_DUMP_DISABLE")]
- NotDumpable = SUID_DUMP_DISABLE,
- /// Dumpable.
- #[doc(alias = "SUID_DUMP_USER")]
- Dumpable = SUID_DUMP_USER,
- /// Dumpable but only readable by root.
- #[doc(alias = "SUID_DUMP_ROOT")]
- DumpableReadableOnlyByRoot = SUID_DUMP_ROOT,
-}
-
-impl TryFrom<i32> for DumpableBehavior {
- type Error = io::Errno;
-
- fn try_from(value: i32) -> Result<Self, Self::Error> {
- match value {
- SUID_DUMP_DISABLE => Ok(Self::NotDumpable),
- SUID_DUMP_USER => Ok(Self::Dumpable),
- SUID_DUMP_ROOT => Ok(Self::DumpableReadableOnlyByRoot),
- _ => Err(io::Errno::RANGE),
- }
- }
-}
-
-/// Get the current state of the calling process' `dumpable` attribute.
-///
-/// # References
-/// - [`prctl(PR_GET_DUMPABLE,...)`]
-///
-/// [`prctl(PR_GET_DUMPABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_DUMPABLE")]
-pub fn dumpable_behavior() -> io::Result<DumpableBehavior> {
- unsafe { prctl_1arg(PR_GET_DUMPABLE) }.and_then(TryInto::try_into)
-}
-
-const PR_SET_DUMPABLE: c_int = 4;
-
-/// Set the state of the `dumpable` attribute, which determines whether the
-/// process can be traced and whether core dumps are produced for the calling
-/// process upon delivery of a signal whose default behavior is to produce a
-/// core dump.
-///
-/// A similar function with the same name is available on FreeBSD (as part of
-/// the `procctl` interface), but it has an extra argument which allows to
-/// select a process other then the current process.
-///
-/// # References
-/// - [`prctl(PR_SET_DUMPABLE,...)`]
-///
-/// [`prctl(PR_SET_DUMPABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_DUMPABLE")]
-pub fn set_dumpable_behavior(config: DumpableBehavior) -> io::Result<()> {
- unsafe { prctl_2args(PR_SET_DUMPABLE, config as usize as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_GET_UNALIGN/PR_SET_UNALIGN
-//
-
-const PR_GET_UNALIGN: c_int = 5;
-
-bitflags! {
- /// `PR_UNALIGN_*` flags for use with [`unaligned_access_control`] and
- /// [`set_unaligned_access_control`].
- #[repr(transparent)]
- #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
- pub struct UnalignedAccessControl: u32 {
- /// Silently fix up unaligned user accesses.
- #[doc(alias = "NOPRINT")]
- #[doc(alias = "PR_UNALIGN_NOPRINT")]
- const NO_PRINT = 1;
- /// Generate a [`Signal::Bus`] signal on unaligned user access.
- #[doc(alias = "PR_UNALIGN_SIGBUS")]
- const SIGBUS = 2;
-
- /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
- const _ = !0;
- }
-}
-
-/// Get unaligned access control bits.
-///
-/// # References
-/// - [`prctl(PR_GET_UNALIGN,...)`]
-///
-/// [`prctl(PR_GET_UNALIGN,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_UNALIGN")]
-pub fn unaligned_access_control() -> io::Result<UnalignedAccessControl> {
- let r = unsafe { prctl_get_at_arg2_optional::<c_uint>(PR_GET_UNALIGN)? };
- UnalignedAccessControl::from_bits(r).ok_or(io::Errno::RANGE)
-}
-
-const PR_SET_UNALIGN: c_int = 6;
-
-/// Set unaligned access control bits.
-///
-/// # References
-/// - [`prctl(PR_SET_UNALIGN,...)`]
-///
-/// [`prctl(PR_SET_UNALIGN,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_UNALIGN")]
-pub fn set_unaligned_access_control(config: UnalignedAccessControl) -> io::Result<()> {
- unsafe { prctl_2args(PR_SET_UNALIGN, config.bits() as usize as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_GET_FPEMU/PR_SET_FPEMU
-//
-
-const PR_GET_FPEMU: c_int = 9;
-
-bitflags! {
- /// `PR_FPEMU_*` flags for use with [`floating_point_emulation_control`]
- /// and [`set_floating_point_emulation_control`].
- #[repr(transparent)]
- #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
- pub struct FloatingPointEmulationControl: u32 {
- /// Silently emulate floating point operations accesses.
- #[doc(alias = "PR_UNALIGN_NOPRINT")]
- const NO_PRINT = 1;
- /// Don't emulate floating point operations, send a [`Signal::Fpe`]
- /// signal instead.
- #[doc(alias = "PR_UNALIGN_SIGFPE")]
- const SIGFPE = 2;
- }
-}
-
-/// Get floating point emulation control bits.
-///
-/// # References
-/// - [`prctl(PR_GET_FPEMU,...)`]
-///
-/// [`prctl(PR_GET_FPEMU,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_FPEMU")]
-pub fn floating_point_emulation_control() -> io::Result<FloatingPointEmulationControl> {
- let r = unsafe { prctl_get_at_arg2_optional::<c_uint>(PR_GET_FPEMU)? };
- FloatingPointEmulationControl::from_bits(r).ok_or(io::Errno::RANGE)
-}
-
-const PR_SET_FPEMU: c_int = 10;
-
-/// Set floating point emulation control bits.
-///
-/// # References
-/// - [`prctl(PR_SET_FPEMU,...)`]
-///
-/// [`prctl(PR_SET_FPEMU,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_FPEMU")]
-pub fn set_floating_point_emulation_control(
- config: FloatingPointEmulationControl,
-) -> io::Result<()> {
- unsafe { prctl_2args(PR_SET_FPEMU, config.bits() as usize as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_GET_FPEXC/PR_SET_FPEXC
-//
-
-const PR_GET_FPEXC: c_int = 11;
-
-bitflags! {
- /// Zero means floating point exceptions are disabled.
- #[repr(transparent)]
- #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
- pub struct FloatingPointExceptionMode: u32 {
- /// Async non-recoverable exception mode.
- const NONRECOV = 1;
- /// Async recoverable exception mode.
- const ASYNC = 2;
- /// Precise exception mode.
- const PRECISE = 3;
-
- /// Use FPEXC for floating point exception enables.
- const SW_ENABLE = 0x80;
- /// Floating point divide by zero.
- const DIV = 0x01_0000;
- /// Floating point overflow.
- const OVF = 0x02_0000;
- /// Floating point underflow.
- const UND = 0x04_0000;
- /// Floating point inexact result.
- const RES = 0x08_0000;
- /// Floating point invalid operation.
- const INV = 0x10_0000;
- }
-}
-
-/// Get floating point exception mode.
-///
-/// # References
-/// - [`prctl(PR_GET_FPEXC,...)`]
-///
-/// [`prctl(PR_GET_FPEXC,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_FPEXEC")]
-pub fn floating_point_exception_mode() -> io::Result<Option<FloatingPointExceptionMode>> {
- unsafe { prctl_get_at_arg2_optional::<c_uint>(PR_GET_FPEXC) }
- .map(FloatingPointExceptionMode::from_bits)
-}
-
-const PR_SET_FPEXC: c_int = 12;
-
-/// Set floating point exception mode.
-///
-/// # References
-/// - [`prctl(PR_SET_FPEXC,...)`]
-///
-/// [`prctl(PR_SET_FPEXC,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_FPEXEC")]
-pub fn set_floating_point_exception_mode(
- config: Option<FloatingPointExceptionMode>,
-) -> io::Result<()> {
- let config = config.as_ref().map_or(0, FloatingPointExceptionMode::bits);
- unsafe { prctl_2args(PR_SET_FPEXC, config as usize as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_GET_TIMING/PR_SET_TIMING
-//
-
-const PR_GET_TIMING: c_int = 13;
-
-const PR_TIMING_STATISTICAL: i32 = 0;
-const PR_TIMING_TIMESTAMP: i32 = 1;
-
-/// `PR_TIMING_*` values for use with [`timing_method`] and
-/// [`set_timing_method`].
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(i32)]
-pub enum TimingMethod {
- /// Normal, traditional, statistical process timing.
- Statistical = PR_TIMING_STATISTICAL,
- /// Accurate timestamp based process timing.
- TimeStamp = PR_TIMING_TIMESTAMP,
-}
-
-impl TryFrom<i32> for TimingMethod {
- type Error = io::Errno;
-
- fn try_from(value: i32) -> Result<Self, Self::Error> {
- match value {
- PR_TIMING_STATISTICAL => Ok(Self::Statistical),
- PR_TIMING_TIMESTAMP => Ok(Self::TimeStamp),
- _ => Err(io::Errno::RANGE),
- }
- }
-}
-
-/// Get which process timing method is currently in use.
-///
-/// # References
-/// - [`prctl(PR_GET_TIMING,...)`]
-///
-/// [`prctl(PR_GET_TIMING,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_TIMING")]
-pub fn timing_method() -> io::Result<TimingMethod> {
- unsafe { prctl_1arg(PR_GET_TIMING) }.and_then(TryInto::try_into)
-}
-
-const PR_SET_TIMING: c_int = 14;
-
-/// Set whether to use (normal, traditional) statistical process timing or
-/// accurate timestamp-based process timing.
-///
-/// # References
-/// - [`prctl(PR_SET_TIMING,...)`]
-///
-/// [`prctl(PR_SET_TIMING,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_TIMING")]
-pub fn set_timing_method(method: TimingMethod) -> io::Result<()> {
- unsafe { prctl_2args(PR_SET_TIMING, method as usize as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_GET_ENDIAN/PR_SET_ENDIAN
-//
-
-const PR_GET_ENDIAN: c_int = 19;
-
-const PR_ENDIAN_BIG: u32 = 0;
-const PR_ENDIAN_LITTLE: u32 = 1;
-const PR_ENDIAN_PPC_LITTLE: u32 = 2;
-
-/// `PR_ENDIAN_*` values for use with [`endian_mode`].
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(u32)]
-pub enum EndianMode {
- /// Big endian mode.
- Big = PR_ENDIAN_BIG,
- /// True little endian mode.
- Little = PR_ENDIAN_LITTLE,
- /// `PowerPC` pseudo little endian.
- PowerPCLittle = PR_ENDIAN_PPC_LITTLE,
-}
-
-impl TryFrom<u32> for EndianMode {
- type Error = io::Errno;
-
- fn try_from(value: u32) -> Result<Self, Self::Error> {
- match value {
- PR_ENDIAN_BIG => Ok(Self::Big),
- PR_ENDIAN_LITTLE => Ok(Self::Little),
- PR_ENDIAN_PPC_LITTLE => Ok(Self::PowerPCLittle),
- _ => Err(io::Errno::RANGE),
- }
- }
-}
-
-/// Get the endianness of the calling process.
-///
-/// # References
-/// - [`prctl(PR_GET_ENDIAN,...)`]
-///
-/// [`prctl(PR_GET_ENDIAN,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_ENDIAN")]
-pub fn endian_mode() -> io::Result<EndianMode> {
- unsafe { prctl_get_at_arg2::<c_uint, _>(PR_GET_ENDIAN) }
-}
-
-const PR_SET_ENDIAN: c_int = 20;
-
-/// Set the endianness of the calling process.
-///
-/// # References
-/// - [`prctl(PR_SET_ENDIAN,...)`]
-///
-/// # Safety
-///
-/// Please ensure the conditions necessary to safely call this function, as
-/// detailed in the references above.
-///
-/// [`prctl(PR_SET_ENDIAN,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_ENDIAN")]
-pub unsafe fn set_endian_mode(mode: EndianMode) -> io::Result<()> {
- prctl_2args(PR_SET_ENDIAN, mode as usize as *mut _).map(|_r| ())
-}
-
-//
-// PR_GET_TSC/PR_SET_TSC
-//
-
-const PR_GET_TSC: c_int = 25;
-
-const PR_TSC_ENABLE: u32 = 1;
-const PR_TSC_SIGSEGV: u32 = 2;
-
-/// `PR_TSC_*` values for use with [`time_stamp_counter_readability`] and
-/// [`set_time_stamp_counter_readability`].
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(u32)]
-pub enum TimeStampCounterReadability {
- /// Allow the use of the timestamp counter.
- Readable = PR_TSC_ENABLE,
- /// Throw a [`Signal::Segv`] signal instead of reading the TSC.
- RaiseSIGSEGV = PR_TSC_SIGSEGV,
-}
-
-impl TryFrom<u32> for TimeStampCounterReadability {
- type Error = io::Errno;
-
- fn try_from(value: u32) -> Result<Self, Self::Error> {
- match value {
- PR_TSC_ENABLE => Ok(Self::Readable),
- PR_TSC_SIGSEGV => Ok(Self::RaiseSIGSEGV),
- _ => Err(io::Errno::RANGE),
- }
- }
-}
-
-/// Get the state of the flag determining if the timestamp counter can be read.
-///
-/// # References
-/// - [`prctl(PR_GET_TSC,...)`]
-///
-/// [`prctl(PR_GET_TSC,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_TSC")]
-pub fn time_stamp_counter_readability() -> io::Result<TimeStampCounterReadability> {
- unsafe { prctl_get_at_arg2::<c_uint, _>(PR_GET_TSC) }
-}
-
-const PR_SET_TSC: c_int = 26;
-
-/// Set the state of the flag determining if the timestamp counter can be read
-/// by the process.
-///
-/// # References
-/// - [`prctl(PR_SET_TSC,...)`]
-///
-/// [`prctl(PR_SET_TSC,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_TSC")]
-pub fn set_time_stamp_counter_readability(
- readability: TimeStampCounterReadability,
-) -> io::Result<()> {
- unsafe { prctl_2args(PR_SET_TSC, readability as usize as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_TASK_PERF_EVENTS_DISABLE/PR_TASK_PERF_EVENTS_ENABLE
-//
-
-const PR_TASK_PERF_EVENTS_DISABLE: c_int = 31;
-const PR_TASK_PERF_EVENTS_ENABLE: c_int = 32;
-
-/// Enable or disable all performance counters attached to the calling process.
-///
-/// # References
-/// - [`prctl(PR_TASK_PERF_EVENTS_ENABLE,...)`]
-/// - [`prctl(PR_TASK_PERF_EVENTS_DISABLE,...)`]
-///
-/// [`prctl(PR_TASK_PERF_EVENTS_ENABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-/// [`prctl(PR_TASK_PERF_EVENTS_DISABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_TASK_PERF_EVENTS_ENABLE")]
-#[doc(alias = "PR_TASK_PERF_EVENTS_DISABLE")]
-pub fn configure_performance_counters(enable: bool) -> io::Result<()> {
- let option = if enable {
- PR_TASK_PERF_EVENTS_ENABLE
- } else {
- PR_TASK_PERF_EVENTS_DISABLE
- };
-
- unsafe { prctl_1arg(option) }.map(|_r| ())
-}
-
-//
-// PR_MCE_KILL_GET/PR_MCE_KILL
-//
-
-const PR_MCE_KILL_GET: c_int = 34;
-
-const PR_MCE_KILL_LATE: u32 = 0;
-const PR_MCE_KILL_EARLY: u32 = 1;
-const PR_MCE_KILL_DEFAULT: u32 = 2;
-
-/// `PR_MCE_KILL_*` values for use with
-/// [`machine_check_memory_corruption_kill_policy`] and
-/// [`set_machine_check_memory_corruption_kill_policy`].
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(u32)]
-pub enum MachineCheckMemoryCorruptionKillPolicy {
- /// Late kill policy.
- #[doc(alias = "PR_MCE_KILL_LATE")]
- Late = PR_MCE_KILL_LATE,
- /// Early kill policy.
- #[doc(alias = "PR_MCE_KILL_EARLY")]
- Early = PR_MCE_KILL_EARLY,
- /// System-wide default policy.
- #[doc(alias = "PR_MCE_KILL_DEFAULT")]
- Default = PR_MCE_KILL_DEFAULT,
-}
-
-impl TryFrom<u32> for MachineCheckMemoryCorruptionKillPolicy {
- type Error = io::Errno;
-
- fn try_from(value: u32) -> Result<Self, Self::Error> {
- match value {
- PR_MCE_KILL_LATE => Ok(Self::Late),
- PR_MCE_KILL_EARLY => Ok(Self::Early),
- PR_MCE_KILL_DEFAULT => Ok(Self::Default),
- _ => Err(io::Errno::RANGE),
- }
- }
-}
-
-/// Get the current per-process machine check kill policy.
-///
-/// # References
-/// - [`prctl(PR_MCE_KILL_GET,...)`]
-///
-/// [`prctl(PR_MCE_KILL_GET,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_MCE_KILL_GET")]
-pub fn machine_check_memory_corruption_kill_policy(
-) -> io::Result<MachineCheckMemoryCorruptionKillPolicy> {
- let r = unsafe { prctl_1arg(PR_MCE_KILL_GET)? } as c_uint;
- MachineCheckMemoryCorruptionKillPolicy::try_from(r)
-}
-
-const PR_MCE_KILL: c_int = 33;
-
-const PR_MCE_KILL_CLEAR: usize = 0;
-const PR_MCE_KILL_SET: usize = 1;
-
-/// Set the machine check memory corruption kill policy for the calling thread.
-///
-/// # References
-/// - [`prctl(PR_MCE_KILL,...)`]
-///
-/// [`prctl(PR_MCE_KILL,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_MCE_KILL")]
-pub fn set_machine_check_memory_corruption_kill_policy(
- policy: Option<MachineCheckMemoryCorruptionKillPolicy>,
-) -> io::Result<()> {
- let (sub_operation, policy) = if let Some(policy) = policy {
- (PR_MCE_KILL_SET, policy as usize as *mut _)
- } else {
- (PR_MCE_KILL_CLEAR, null_mut())
- };
-
- unsafe { prctl_3args(PR_MCE_KILL, sub_operation as *mut _, policy) }.map(|_r| ())
-}
-
-//
-// PR_SET_MM
-//
-
-const PR_SET_MM: c_int = 35;
-
-const PR_SET_MM_START_CODE: u32 = 1;
-const PR_SET_MM_END_CODE: u32 = 2;
-const PR_SET_MM_START_DATA: u32 = 3;
-const PR_SET_MM_END_DATA: u32 = 4;
-const PR_SET_MM_START_STACK: u32 = 5;
-const PR_SET_MM_START_BRK: u32 = 6;
-const PR_SET_MM_BRK: u32 = 7;
-const PR_SET_MM_ARG_START: u32 = 8;
-const PR_SET_MM_ARG_END: u32 = 9;
-const PR_SET_MM_ENV_START: u32 = 10;
-const PR_SET_MM_ENV_END: u32 = 11;
-const PR_SET_MM_AUXV: usize = 12;
-const PR_SET_MM_EXE_FILE: usize = 13;
-const PR_SET_MM_MAP: usize = 14;
-const PR_SET_MM_MAP_SIZE: usize = 15;
-
-/// `PR_SET_MM_*` values for use with [`set_virtual_memory_map_address`].
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(u32)]
-pub enum VirtualMemoryMapAddress {
- /// Set the address above which the program text can run.
- CodeStart = PR_SET_MM_START_CODE,
- /// Set the address below which the program text can run.
- CodeEnd = PR_SET_MM_END_CODE,
- /// Set the address above which initialized and uninitialized (bss) data
- /// are placed.
- DataStart = PR_SET_MM_START_DATA,
- /// Set the address below which initialized and uninitialized (bss) data
- /// are placed.
- DataEnd = PR_SET_MM_END_DATA,
- /// Set the start address of the stack.
- StackStart = PR_SET_MM_START_STACK,
- /// Set the address above which the program heap can be expanded with `brk`
- /// call.
- BrkStart = PR_SET_MM_START_BRK,
- /// Set the current `brk` value.
- BrkCurrent = PR_SET_MM_BRK,
- /// Set the address above which the program command line is placed.
- ArgStart = PR_SET_MM_ARG_START,
- /// Set the address below which the program command line is placed.
- ArgEnd = PR_SET_MM_ARG_END,
- /// Set the address above which the program environment is placed.
- EnvironmentStart = PR_SET_MM_ENV_START,
- /// Set the address below which the program environment is placed.
- EnvironmentEnd = PR_SET_MM_ENV_END,
-}
-
-/// Modify certain kernel memory map descriptor addresses of the calling
-/// process.
-///
-/// # References
-/// - [`prctl(PR_SET_MM,...)`]
-///
-/// # Safety
-///
-/// Please ensure the conditions necessary to safely call this function, as
-/// detailed in the references above.
-///
-/// [`prctl(PR_SET_MM,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_MM")]
-pub unsafe fn set_virtual_memory_map_address(
- option: VirtualMemoryMapAddress,
- address: Option<NonNull<c_void>>,
-) -> io::Result<()> {
- let address = address.map_or_else(null_mut, NonNull::as_ptr);
- prctl_3args(PR_SET_MM, option as usize as *mut _, address).map(|_r| ())
-}
-
-/// Supersede the `/proc/pid/exe` symbolic link with a new one pointing to a
-/// new executable file.
-///
-/// # References
-/// - [`prctl(PR_SET_MM,PR_SET_MM_EXE_FILE,...)`]
-///
-/// [`prctl(PR_SET_MM,PR_SET_MM_EXE_FILE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_MM")]
-#[doc(alias = "PR_SET_MM_EXE_FILE")]
-pub fn set_executable_file(fd: BorrowedFd<'_>) -> io::Result<()> {
- let fd = usize::try_from(fd.as_raw_fd()).map_err(|_r| io::Errno::RANGE)?;
- unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_EXE_FILE as *mut _, fd as *mut _) }.map(|_r| ())
-}
-
-/// Set a new auxiliary vector.
-///
-/// # References
-/// - [`prctl(PR_SET_MM,PR_SET_MM_AUXV,...)`]
-///
-/// # Safety
-///
-/// Please ensure the conditions necessary to safely call this function, as
-/// detailed in the references above.
-///
-/// [`prctl(PR_SET_MM,PR_SET_MM_AUXV,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_MM")]
-#[doc(alias = "PR_SET_MM_AUXV")]
-pub unsafe fn set_auxiliary_vector(auxv: &[*const c_void]) -> io::Result<()> {
- syscalls::prctl(
- PR_SET_MM,
- PR_SET_MM_AUXV as *mut _,
- auxv.as_ptr() as *mut _,
- auxv.len() as *mut _,
- null_mut(),
- )
- .map(|_r| ())
-}
-
-/// Get the size of the [`PrctlMmMap`] the kernel expects.
-///
-/// # References
-/// - [`prctl(PR_SET_MM,PR_SET_MM_MAP_SIZE,...)`]
-///
-/// [`prctl(PR_SET_MM,PR_SET_MM_MAP_SIZE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_MM")]
-#[doc(alias = "PR_SET_MM_MAP_SIZE")]
-pub fn virtual_memory_map_config_struct_size() -> io::Result<usize> {
- let mut value: c_uint = 0;
- let value_ptr = as_mut_ptr(&mut value);
- unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_MAP_SIZE as *mut _, value_ptr.cast())? };
- Ok(value as usize)
-}
-
-/// This structure provides new memory descriptor map which mostly modifies
-/// `/proc/pid/stat[m]` output for a task.
-/// This mostly done in a sake of checkpoint/restore functionality.
-#[repr(C)]
-#[derive(Debug, Clone)]
-pub struct PrctlMmMap {
- /// Code section start address.
- pub start_code: u64,
- /// Code section end address.
- pub end_code: u64,
- /// Data section start address.
- pub start_data: u64,
- /// Data section end address.
- pub end_data: u64,
- /// `brk` start address.
- pub start_brk: u64,
- /// `brk` current address.
- pub brk: u64,
- /// Stack start address.
- pub start_stack: u64,
- /// Program command line start address.
- pub arg_start: u64,
- /// Program command line end address.
- pub arg_end: u64,
- /// Program environment start address.
- pub env_start: u64,
- /// Program environment end address.
- pub env_end: u64,
- /// Auxiliary vector start address.
- pub auxv: *mut u64,
- /// Auxiliary vector size.
- pub auxv_size: u32,
- /// File descriptor of executable file that was used to create this
- /// process.
- pub exe_fd: u32,
-}
-
-/// Provides one-shot access to all the addresses by passing in a
-/// [`PrctlMmMap`].
-///
-/// # References
-/// - [`prctl(PR_SET_MM,PR_SET_MM_MAP,...)`]
-///
-/// # Safety
-///
-/// Please ensure the conditions necessary to safely call this function, as
-/// detailed in the references above.
-///
-/// [`prctl(PR_SET_MM,PR_SET_MM_MAP,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_MM")]
-#[doc(alias = "PR_SET_MM_MAP")]
-pub unsafe fn configure_virtual_memory_map(config: &PrctlMmMap) -> io::Result<()> {
- syscalls::prctl(
- PR_SET_MM,
- PR_SET_MM_MAP as *mut _,
- as_ptr(config) as *mut _,
- size_of::<PrctlMmMap>() as *mut _,
- null_mut(),
- )
- .map(|_r| ())
-}
-
-//
-// PR_SET_PTRACER
-//
-
-const PR_SET_PTRACER: c_int = 0x59_61_6d_61;
-
-const PR_SET_PTRACER_ANY: usize = usize::MAX;
-
-/// Process ptracer.
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum PTracer {
- /// None.
- None,
- /// Disable `ptrace` restrictions for the calling process.
- Any,
- /// Specific process.
- ProcessID(Pid),
-}
-
-/// Declare that the ptracer process can `ptrace` the calling process as if it
-/// were a direct process ancestor.
-///
-/// # References
-/// - [`prctl(PR_SET_PTRACER,...)`]
-///
-/// [`prctl(PR_SET_PTRACER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_PTRACER")]
-pub fn set_ptracer(tracer: PTracer) -> io::Result<()> {
- let pid = match tracer {
- PTracer::None => null_mut(),
- PTracer::Any => PR_SET_PTRACER_ANY as *mut _,
- PTracer::ProcessID(pid) => pid.as_raw_nonzero().get() as usize as *mut _,
- };
-
- unsafe { prctl_2args(PR_SET_PTRACER, pid) }.map(|_r| ())
-}
-
-//
-// PR_GET_CHILD_SUBREAPER/PR_SET_CHILD_SUBREAPER
-//
-
-const PR_GET_CHILD_SUBREAPER: c_int = 37;
-
-/// Get the `child subreaper` setting of the calling process.
-///
-/// # References
-/// - [`prctl(PR_GET_CHILD_SUBREAPER,...)`]
-///
-/// [`prctl(PR_GET_CHILD_SUBREAPER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_CHILD_SUBREAPER")]
-pub fn child_subreaper() -> io::Result<Option<Pid>> {
- unsafe {
- let r = prctl_get_at_arg2_optional::<c_uint>(PR_GET_CHILD_SUBREAPER)?;
- Ok(Pid::from_raw(r as RawPid))
- }
-}
-
-const PR_SET_CHILD_SUBREAPER: c_int = 36;
-
-/// Set the `child subreaper` attribute of the calling process.
-///
-/// # References
-/// - [`prctl(PR_SET_CHILD_SUBREAPER,...)`]
-///
-/// [`prctl(PR_SET_CHILD_SUBREAPER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_CHILD_SUBREAPER")]
-pub fn set_child_subreaper(pid: Option<Pid>) -> io::Result<()> {
- let pid = pid.map_or(0_usize, |pid| pid.as_raw_nonzero().get() as usize);
- unsafe { prctl_2args(PR_SET_CHILD_SUBREAPER, pid as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_GET_FP_MODE/PR_SET_FP_MODE
-//
-
-const PR_GET_FP_MODE: c_int = 46;
-
-const PR_FP_MODE_FR: u32 = 1_u32 << 0;
-const PR_FP_MODE_FRE: u32 = 1_u32 << 1;
-
-/// `PR_FP_MODE_*` values for use with [`floating_point_mode`] and
-/// [`set_floating_point_mode`].
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(u32)]
-pub enum FloatingPointMode {
- /// 64-bit floating point registers.
- FloatingPointRegisters = PR_FP_MODE_FR,
- /// Enable emulation of 32-bit floating-point mode.
- FloatingPointEmulation = PR_FP_MODE_FRE,
-}
-
-impl TryFrom<u32> for FloatingPointMode {
- type Error = io::Errno;
-
- fn try_from(value: u32) -> Result<Self, Self::Error> {
- match value {
- PR_FP_MODE_FR => Ok(Self::FloatingPointRegisters),
- PR_FP_MODE_FRE => Ok(Self::FloatingPointEmulation),
- _ => Err(io::Errno::RANGE),
- }
- }
-}
-
-/// Get the current floating point mode.
-///
-/// # References
-/// - [`prctl(PR_GET_FP_MODE,...)`]
-///
-/// [`prctl(PR_GET_FP_MODE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_FP_MODE")]
-pub fn floating_point_mode() -> io::Result<FloatingPointMode> {
- let r = unsafe { prctl_1arg(PR_GET_FP_MODE)? } as c_uint;
- FloatingPointMode::try_from(r)
-}
-
-const PR_SET_FP_MODE: c_int = 45;
-
-/// Allow control of the floating point mode from user space.
-///
-/// # References
-/// - [`prctl(PR_SET_FP_MODE,...)`]
-///
-/// [`prctl(PR_SET_FP_MODE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_FP_MODE")]
-pub fn set_floating_point_mode(mode: FloatingPointMode) -> io::Result<()> {
- unsafe { prctl_2args(PR_SET_FP_MODE, mode as usize as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_GET_SPECULATION_CTRL/PR_SET_SPECULATION_CTRL
-//
-
-const PR_GET_SPECULATION_CTRL: c_int = 52;
-
-const PR_SPEC_STORE_BYPASS: u32 = 0;
-const PR_SPEC_INDIRECT_BRANCH: u32 = 1;
-const PR_SPEC_L1D_FLUSH: u32 = 2;
-
-/// `PR_SPEC_*` values for use with [`speculative_feature_state`] and
-/// [`control_speculative_feature`].
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(u32)]
-pub enum SpeculationFeature {
- /// Set the state of the speculative store bypass misfeature.
- SpeculativeStoreBypass = PR_SPEC_STORE_BYPASS,
- /// Set the state of the indirect branch speculation misfeature.
- IndirectBranchSpeculation = PR_SPEC_INDIRECT_BRANCH,
- /// Flush L1D Cache on context switch out of the task.
- FlushL1DCacheOnContextSwitchOutOfTask = PR_SPEC_L1D_FLUSH,
-}
-
-impl TryFrom<u32> for SpeculationFeature {
- type Error = io::Errno;
-
- fn try_from(value: u32) -> Result<Self, Self::Error> {
- match value {
- PR_SPEC_STORE_BYPASS => Ok(Self::SpeculativeStoreBypass),
- PR_SPEC_INDIRECT_BRANCH => Ok(Self::IndirectBranchSpeculation),
- PR_SPEC_L1D_FLUSH => Ok(Self::FlushL1DCacheOnContextSwitchOutOfTask),
- _ => Err(io::Errno::RANGE),
- }
- }
-}
-
-bitflags! {
- /// `PR_SPEC_*` flags for use with [`control_speculative_feature`].
- #[repr(transparent)]
- #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
- pub struct SpeculationFeatureControl: u32 {
- /// The speculation feature is enabled, mitigation is disabled.
- const ENABLE = 1_u32 << 1;
- /// The speculation feature is disabled, mitigation is enabled.
- const DISABLE = 1_u32 << 2;
- /// The speculation feature is disabled, mitigation is enabled, and it
- /// cannot be undone.
- const FORCE_DISABLE = 1_u32 << 3;
- /// The speculation feature is disabled, mitigation is enabled, and the
- /// state will be cleared on `execve`.
- const DISABLE_NOEXEC = 1_u32 << 4;
- }
-}
-
-bitflags! {
- /// Zero means the processors are not vulnerable.
- #[repr(transparent)]
- #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
- pub struct SpeculationFeatureState: u32 {
- /// Mitigation can be controlled per thread by
- /// `PR_SET_SPECULATION_CTRL`.
- const PRCTL = 1_u32 << 0;
- /// The speculation feature is enabled, mitigation is disabled.
- const ENABLE = 1_u32 << 1;
- /// The speculation feature is disabled, mitigation is enabled.
- const DISABLE = 1_u32 << 2;
- /// The speculation feature is disabled, mitigation is enabled, and it
- /// cannot be undone.
- const FORCE_DISABLE = 1_u32 << 3;
- /// The speculation feature is disabled, mitigation is enabled, and the
- /// state will be cleared on `execve`.
- const DISABLE_NOEXEC = 1_u32 << 4;
- }
-}
-
-/// Get the state of the speculation misfeature.
-///
-/// # References
-/// - [`prctl(PR_GET_SPECULATION_CTRL,...)`]
-///
-/// [`prctl(PR_GET_SPECULATION_CTRL,...)`]: https://www.kernel.org/doc/html/v5.18/userspace-api/spec_ctrl.html
-#[inline]
-#[doc(alias = "PR_GET_SPECULATION_CTRL")]
-pub fn speculative_feature_state(
- feature: SpeculationFeature,
-) -> io::Result<Option<SpeculationFeatureState>> {
- let r = unsafe { prctl_2args(PR_GET_SPECULATION_CTRL, feature as usize as *mut _)? } as c_uint;
- Ok(SpeculationFeatureState::from_bits(r))
-}
-
-const PR_SET_SPECULATION_CTRL: c_int = 53;
-
-/// Sets the state of the speculation misfeature.
-///
-/// # References
-/// - [`prctl(PR_SET_SPECULATION_CTRL,...)`]
-///
-/// [`prctl(PR_SET_SPECULATION_CTRL,...)`]: https://www.kernel.org/doc/html/v5.18/userspace-api/spec_ctrl.html
-#[inline]
-#[doc(alias = "PR_SET_SPECULATION_CTRL")]
-pub fn control_speculative_feature(
- feature: SpeculationFeature,
- config: SpeculationFeatureControl,
-) -> io::Result<()> {
- let feature = feature as usize as *mut _;
- let config = config.bits() as usize as *mut _;
- unsafe { prctl_3args(PR_SET_SPECULATION_CTRL, feature, config) }.map(|_r| ())
-}
-
-//
-// PR_GET_IO_FLUSHER/PR_SET_IO_FLUSHER
-//
-
-const PR_GET_IO_FLUSHER: c_int = 58;
-
-/// Get the `IO_FLUSHER` state of the caller.
-///
-/// # References
-/// - [`prctl(PR_GET_IO_FLUSHER,...)`]
-///
-/// [`prctl(PR_GET_IO_FLUSHER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_GET_IO_FLUSHER")]
-pub fn is_io_flusher() -> io::Result<bool> {
- unsafe { prctl_1arg(PR_GET_IO_FLUSHER) }.map(|r| r != 0)
-}
-
-const PR_SET_IO_FLUSHER: c_int = 57;
-
-/// Put the process in the `IO_FLUSHER` state, allowing it to make progress
-/// when allocating memory.
-///
-/// # References
-/// - [`prctl(PR_SET_IO_FLUSHER,...)`]
-///
-/// [`prctl(PR_SET_IO_FLUSHER,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html
-#[inline]
-#[doc(alias = "PR_SET_IO_FLUSHER")]
-pub fn configure_io_flusher_behavior(enable: bool) -> io::Result<()> {
- unsafe { prctl_2args(PR_SET_IO_FLUSHER, usize::from(enable) as *mut _) }.map(|_r| ())
-}
-
-//
-// PR_PAC_GET_ENABLED_KEYS/PR_PAC_SET_ENABLED_KEYS
-//
-
-const PR_PAC_GET_ENABLED_KEYS: c_int = 61;
-
-/// Get enabled pointer authentication keys.
-///
-/// # References
-/// - [`prctl(PR_PAC_GET_ENABLED_KEYS,...)`]
-///
-/// [`prctl(PR_PAC_GET_ENABLED_KEYS,...)`]: https://www.kernel.org/doc/html/v5.18/arm64/pointer-authentication.html
-#[inline]
-#[doc(alias = "PR_PAC_GET_ENABLED_KEYS")]
-pub fn enabled_pointer_authentication_keys() -> io::Result<PointerAuthenticationKeys> {
- let r = unsafe { prctl_1arg(PR_PAC_GET_ENABLED_KEYS)? } as c_uint;
- PointerAuthenticationKeys::from_bits(r).ok_or(io::Errno::RANGE)
-}
-
-const PR_PAC_SET_ENABLED_KEYS: c_int = 60;
-
-/// Set enabled pointer authentication keys.
-///
-/// # References
-/// - [`prctl(PR_PAC_SET_ENABLED_KEYS,...)`]
-///
-/// # Safety
-///
-/// Please ensure the conditions necessary to safely call this function, as
-/// detailed in the references above.
-///
-/// [`prctl(PR_PAC_SET_ENABLED_KEYS,...)`]: https://www.kernel.org/doc/html/v5.18/arm64/pointer-authentication.html
-#[inline]
-#[doc(alias = "PR_PAC_SET_ENABLED_KEYS")]
-pub unsafe fn configure_pointer_authentication_keys(
- config: impl Iterator<Item = (PointerAuthenticationKeys, bool)>,
-) -> io::Result<()> {
- let mut affected_keys: u32 = 0;
- let mut enabled_keys: u32 = 0;
-
- for (key, enable) in config {
- let key = key.bits();
- affected_keys |= key;
-
- if enable {
- enabled_keys |= key;
- } else {
- enabled_keys &= !key;
- }
- }
-
- if affected_keys == 0 {
- return Ok(()); // Nothing to do.
- }
-
- prctl_3args(
- PR_PAC_SET_ENABLED_KEYS,
- affected_keys as usize as *mut _,
- enabled_keys as usize as *mut _,
- )
- .map(|_r| ())
-}
-
-//
-// PR_SET_VMA
-//
-
-const PR_SET_VMA: c_int = 0x53_56_4d_41;
-
-const PR_SET_VMA_ANON_NAME: usize = 0;
-
-/// Set the name for a virtual memory region.
-///
-/// # References
-/// - [`prctl(PR_SET_VMA,PR_SET_VMA_ANON_NAME,...)`]
-///
-/// [`prctl(PR_SET_VMA,PR_SET_VMA_ANON_NAME,...)`]: https://lwn.net/Articles/867818/
-#[inline]
-#[doc(alias = "PR_SET_VMA")]
-#[doc(alias = "PR_SET_VMA_ANON_NAME")]
-pub fn set_virtual_memory_region_name(region: &[u8], name: Option<&CStr>) -> io::Result<()> {
- unsafe {
- syscalls::prctl(
- PR_SET_VMA,
- PR_SET_VMA_ANON_NAME as *mut _,
- region.as_ptr() as *mut _,
- region.len() as *mut _,
- name.map_or_else(null, CStr::as_ptr) as *mut _,
- )
- .map(|_r| ())
- }
-}