pve-lxc-syscalld/src/capability.rs

90 lines
2.7 KiB
Rust
Raw Normal View History

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(())
}
}