5bd0c5620f
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
90 lines
2.7 KiB
Rust
90 lines
2.7 KiB
Rust
use std::io;
|
|
use std::os::raw::{c_int, c_ulong};
|
|
|
|
bitflags::bitflags! {
|
|
pub struct SecureBits: c_ulong {
|
|
const NOROOT = 0b0_0000_0001;
|
|
const NOROOT_LOCKED = 0b0_0000_0010;
|
|
const NO_SETUID_FIXUP = 0b0_0000_0100;
|
|
const NO_SETUID_FIXUP_LOCKED = 0b0_0000_1000;
|
|
const KEEP_CAPS = 0b0_0001_0000;
|
|
const KEEP_CAPS_LOCKED = 0b0_0010_0000;
|
|
const NO_CAP_AMBIENT_RAISE = 0b0_0100_0000;
|
|
const NO_CAP_AMBIENT_RAISE_LOCKED = 0b0_1000_0000;
|
|
|
|
const ALL_BITS = 0b0_0101_0101;
|
|
const ALL_LOCKS = 0b0_1010_1010;
|
|
}
|
|
}
|
|
|
|
impl SecureBits {
|
|
pub fn apply(self) -> io::Result<()> {
|
|
c_result!(unsafe { libc::prctl(libc::PR_SET_SECUREBITS, self.bits()) })?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn get_current() -> io::Result<Self> {
|
|
let bits = c_result!(unsafe { libc::prctl(libc::PR_GET_SECUREBITS) })?;
|
|
Self::from_bits(bits as _)
|
|
.ok_or_else(|| io_format_err!("prctl() returned unknown securebits"))
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Default)]
|
|
pub struct Capabilities {
|
|
pub inheritable: u64,
|
|
pub permitted: u64,
|
|
pub effective: u64,
|
|
//bounding: u64, // we don't care currently
|
|
}
|
|
|
|
// Too lazy to bindgen libcap stuff...
|
|
const CAPABILITY_VERSION_3: u32 = 0x2008_0522;
|
|
|
|
/// Represents process capabilities.
|
|
///
|
|
/// This can be used to change the process' capability sets (if permitted by the kernel).
|
|
impl Capabilities {
|
|
// We currently don't implement capget as it takes a pid which is racy on kernels without pidfd
|
|
// support. Later on we might support a `capget(&PidFd)` method?
|
|
|
|
/// Change our process capabilities. This does not include the bounding set.
|
|
pub fn capset(&self) -> io::Result<()> {
|
|
// kernel abi:
|
|
#[allow(dead_code)]
|
|
struct Header {
|
|
version: u32,
|
|
pid: c_int,
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
struct Data {
|
|
effective: u32,
|
|
permitted: u32,
|
|
inheritable: u32,
|
|
}
|
|
|
|
let header = Header {
|
|
version: CAPABILITY_VERSION_3,
|
|
pid: 0, // equivalent to gettid(),
|
|
};
|
|
|
|
let data = [
|
|
Data {
|
|
effective: self.effective as u32,
|
|
permitted: self.permitted as u32,
|
|
inheritable: self.inheritable as u32,
|
|
},
|
|
Data {
|
|
effective: (self.effective >> 32) as u32,
|
|
permitted: (self.permitted >> 32) as u32,
|
|
inheritable: (self.inheritable >> 32) as u32,
|
|
},
|
|
];
|
|
|
|
c_try!(unsafe { libc::syscall(libc::SYS_capset, &header, &data) });
|
|
|
|
Ok(())
|
|
}
|
|
}
|