summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/thread/libcap.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/thread/libcap.rs')
-rw-r--r--vendor/rustix/src/thread/libcap.rs187
1 files changed, 187 insertions, 0 deletions
diff --git a/vendor/rustix/src/thread/libcap.rs b/vendor/rustix/src/thread/libcap.rs
new file mode 100644
index 000000000..f4798b8f4
--- /dev/null
+++ b/vendor/rustix/src/thread/libcap.rs
@@ -0,0 +1,187 @@
+use bitflags::bitflags;
+use core::mem::MaybeUninit;
+
+use crate::process::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.
+ 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;
+ }
+}
+
+/// `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()) }
+ };
+
+ {
+ // TODO: With Rust 1.53, we can use u32::BITS in the shifts.
+ const BITS: u32 = 32;
+ let effective = u64::from(data.0.effective) | (u64::from(data.1.effective) << BITS);
+ let permitted = u64::from(data.0.permitted) | (u64::from(data.1.permitted) << BITS);
+ let inheritable = u64::from(data.0.inheritable) | (u64::from(data.1.inheritable) << BITS);
+
+ // SAFETY: the kernel returns a partitioned bitset that we just combined above
+ Ok(CapabilitySets {
+ effective: unsafe { CapabilityFlags::from_bits_unchecked(effective) },
+ permitted: unsafe { CapabilityFlags::from_bits_unchecked(permitted) },
+ inheritable: unsafe { CapabilityFlags::from_bits_unchecked(inheritable) },
+ })
+ }
+}
+
+#[inline]
+fn capset(pid: Option<Pid>, sets: CapabilitySets) -> io::Result<()> {
+ // TODO: With Rust 1.53, we can use u32::BITS in the shifts.
+ const BITS: u32 = 32;
+
+ 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() >> BITS) as u32,
+ permitted: (sets.permitted.bits() >> BITS) as u32,
+ inheritable: (sets.inheritable.bits() >> BITS) as u32,
+ },
+ ];
+
+ backend::thread::syscalls::capset(&mut header, &data)
+}