diff options
Diffstat (limited to 'vendor/rustix/src/thread/libcap.rs')
-rw-r--r-- | vendor/rustix/src/thread/libcap.rs | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/vendor/rustix/src/thread/libcap.rs b/vendor/rustix/src/thread/libcap.rs new file mode 100644 index 0000000..0a0fbb4 --- /dev/null +++ b/vendor/rustix/src/thread/libcap.rs @@ -0,0 +1,185 @@ +use bitflags::bitflags; +use core::mem::MaybeUninit; + +use crate::pid::Pid; +use crate::{backend, io}; + +/// `__user_cap_data_struct` +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct CapabilitySets { + /// `__user_cap_data_struct.effective` + pub effective: CapabilityFlags, + /// `__user_cap_data_struct.permitted` + pub permitted: CapabilityFlags, + /// `__user_cap_data_struct.inheritable` + pub inheritable: CapabilityFlags, +} + +bitflags! { + /// `CAP_*` constants. + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct CapabilityFlags: u64 { + /// `CAP_CHOWN` + const CHOWN = 1 << linux_raw_sys::general::CAP_CHOWN; + /// `CAP_DAC_OVERRIDE` + const DAC_OVERRIDE = 1 << linux_raw_sys::general::CAP_DAC_OVERRIDE; + /// `CAP_DAC_READ_SEARCH` + const DAC_READ_SEARCH = 1 << linux_raw_sys::general::CAP_DAC_READ_SEARCH; + /// `CAP_FOWNER` + const FOWNER = 1 << linux_raw_sys::general::CAP_FOWNER; + /// `CAP_FSETID` + const FSETID = 1 << linux_raw_sys::general::CAP_FSETID; + /// `CAP_KILL` + const KILL = 1 << linux_raw_sys::general::CAP_KILL; + /// `CAP_SETGID` + const SETGID = 1 << linux_raw_sys::general::CAP_SETGID; + /// `CAP_SETUID` + const SETUID = 1 << linux_raw_sys::general::CAP_SETUID; + /// `CAP_SETPCAP` + const SETPCAP = 1 << linux_raw_sys::general::CAP_SETPCAP; + /// `CAP_LINUX_IMMUTABLE` + const LINUX_IMMUTABLE = 1 << linux_raw_sys::general::CAP_LINUX_IMMUTABLE; + /// `CAP_NET_BIND_SERVICE` + const NET_BIND_SERVICE = 1 << linux_raw_sys::general::CAP_NET_BIND_SERVICE; + /// `CAP_NET_BROADCAST` + const NET_BROADCAST = 1 << linux_raw_sys::general::CAP_NET_BROADCAST; + /// `CAP_NET_ADMIN` + const NET_ADMIN = 1 << linux_raw_sys::general::CAP_NET_ADMIN; + /// `CAP_NET_RAW` + const NET_RAW = 1 << linux_raw_sys::general::CAP_NET_RAW; + /// `CAP_IPC_LOCK` + const IPC_LOCK = 1 << linux_raw_sys::general::CAP_IPC_LOCK; + /// `CAP_IPC_OWNER` + const IPC_OWNER = 1 << linux_raw_sys::general::CAP_IPC_OWNER; + /// `CAP_SYS_MODULE` + const SYS_MODULE = 1 << linux_raw_sys::general::CAP_SYS_MODULE; + /// `CAP_SYS_RAWIO` + const SYS_RAWIO = 1 << linux_raw_sys::general::CAP_SYS_RAWIO; + /// `CAP_SYS_CHROOT` + const SYS_CHROOT = 1 << linux_raw_sys::general::CAP_SYS_CHROOT; + /// `CAP_SYS_PTRACE` + const SYS_PTRACE = 1 << linux_raw_sys::general::CAP_SYS_PTRACE; + /// `CAP_SYS_PACCT` + const SYS_PACCT = 1 << linux_raw_sys::general::CAP_SYS_PACCT; + /// `CAP_SYS_ADMIN` + const SYS_ADMIN = 1 << linux_raw_sys::general::CAP_SYS_ADMIN; + /// `CAP_SYS_BOOT` + const SYS_BOOT = 1 << linux_raw_sys::general::CAP_SYS_BOOT; + /// `CAP_SYS_NICE` + const SYS_NICE = 1 << linux_raw_sys::general::CAP_SYS_NICE; + /// `CAP_SYS_RESOURCE` + const SYS_RESOURCE = 1 << linux_raw_sys::general::CAP_SYS_RESOURCE; + /// `CAP_SYS_TIME` + const SYS_TIME = 1 << linux_raw_sys::general::CAP_SYS_TIME; + /// `CAP_SYS_TTY_CONFIG` + const SYS_TTY_CONFIG = 1 << linux_raw_sys::general::CAP_SYS_TTY_CONFIG; + /// `CAP_MKNOD` + const MKNOD = 1 << linux_raw_sys::general::CAP_MKNOD; + /// `CAP_LEASE` + const LEASE = 1 << linux_raw_sys::general::CAP_LEASE; + /// `CAP_AUDIT_WRITE` + const AUDIT_WRITE = 1 << linux_raw_sys::general::CAP_AUDIT_WRITE; + /// `CAP_AUDIT_CONTROL` + const AUDIT_CONTROL = 1 << linux_raw_sys::general::CAP_AUDIT_CONTROL; + /// `CAP_SETFCAP` + const SETFCAP = 1 << linux_raw_sys::general::CAP_SETFCAP; + /// `CAP_MAC_OVERRIDE` + const MAC_OVERRIDE = 1 << linux_raw_sys::general::CAP_MAC_OVERRIDE; + /// `CAP_MAC_ADMIN` + const MAC_ADMIN = 1 << linux_raw_sys::general::CAP_MAC_ADMIN; + /// `CAP_SYSLOG` + const SYSLOG = 1 << linux_raw_sys::general::CAP_SYSLOG; + /// `CAP_WAKE_ALARM` + const WAKE_ALARM = 1 << linux_raw_sys::general::CAP_WAKE_ALARM; + /// `CAP_BLOCK_SUSPEND` + const BLOCK_SUSPEND = 1 << linux_raw_sys::general::CAP_BLOCK_SUSPEND; + /// `CAP_AUDIT_READ` + const AUDIT_READ = 1 << linux_raw_sys::general::CAP_AUDIT_READ; + /// `CAP_PERFMON` + const PERFMON = 1 << linux_raw_sys::general::CAP_PERFMON; + /// `CAP_BPF` + const BPF = 1 << linux_raw_sys::general::CAP_BPF; + /// `CAP_CHECKPOINT_RESTORE` + const CHECKPOINT_RESTORE = 1 << linux_raw_sys::general::CAP_CHECKPOINT_RESTORE; + + /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> + const _ = !0; + } +} + +/// `capget(_LINUX_CAPABILITY_VERSION_3, pid)` +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/capget.2.html +#[inline] +#[doc(alias = "capget")] +pub fn capabilities(pid: Option<Pid>) -> io::Result<CapabilitySets> { + capget(pid) +} + +/// `capset(_LINUX_CAPABILITY_VERSION_3, pid, effective, permitted, +/// inheritable)` +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/capget.2.html +#[inline] +#[doc(alias = "capset")] +pub fn set_capabilities(pid: Option<Pid>, sets: CapabilitySets) -> io::Result<()> { + capset(pid, sets) +} + +#[inline] +#[allow(unsafe_code)] +fn capget(pid: Option<Pid>) -> io::Result<CapabilitySets> { + let mut data = [MaybeUninit::<linux_raw_sys::general::__user_cap_data_struct>::uninit(); 2]; + + let data = { + let mut header = linux_raw_sys::general::__user_cap_header_struct { + version: linux_raw_sys::general::_LINUX_CAPABILITY_VERSION_3, + pid: Pid::as_raw(pid) as backend::c::c_int, + }; + + backend::thread::syscalls::capget(&mut header, &mut data)?; + // SAFETY: v3 is a 64-bit implementation, so the kernel filled in both + // data structs. + unsafe { (data[0].assume_init(), data[1].assume_init()) } + }; + + let effective = u64::from(data.0.effective) | (u64::from(data.1.effective) << u32::BITS); + let permitted = u64::from(data.0.permitted) | (u64::from(data.1.permitted) << u32::BITS); + let inheritable = u64::from(data.0.inheritable) | (u64::from(data.1.inheritable) << u32::BITS); + + // The kernel returns a partitioned bitset that we just combined above. + Ok(CapabilitySets { + effective: CapabilityFlags::from_bits_retain(effective), + permitted: CapabilityFlags::from_bits_retain(permitted), + inheritable: CapabilityFlags::from_bits_retain(inheritable), + }) +} + +#[inline] +fn capset(pid: Option<Pid>, sets: CapabilitySets) -> io::Result<()> { + let mut header = linux_raw_sys::general::__user_cap_header_struct { + version: linux_raw_sys::general::_LINUX_CAPABILITY_VERSION_3, + pid: Pid::as_raw(pid) as backend::c::c_int, + }; + let data = [ + linux_raw_sys::general::__user_cap_data_struct { + effective: sets.effective.bits() as u32, + permitted: sets.permitted.bits() as u32, + inheritable: sets.inheritable.bits() as u32, + }, + linux_raw_sys::general::__user_cap_data_struct { + effective: (sets.effective.bits() >> u32::BITS) as u32, + permitted: (sets.permitted.bits() >> u32::BITS) as u32, + inheritable: (sets.inheritable.bits() >> u32::BITS) as u32, + }, + ]; + + backend::thread::syscalls::capset(&mut header, &data) +} |