mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-05-05 14:38:25 -04:00
166 lines
5.0 KiB
Rust
166 lines
5.0 KiB
Rust
use crate::error::{KernelError, Result};
|
|
|
|
bitflags::bitflags! {
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
pub struct CapabilitiesFlags: u64 {
|
|
const CAP_CHOWN = 1 << 0;
|
|
const CAP_DAC_OVERRIDE = 1 << 1;
|
|
const CAP_DAC_READ_SEARCH = 1 << 2;
|
|
const CAP_FOWNER = 1 << 3;
|
|
const CAP_FSETID = 1 << 4;
|
|
const CAP_KILL = 1 << 5;
|
|
const CAP_SETGID = 1 << 6;
|
|
const CAP_SETUID = 1 << 7;
|
|
const CAP_SETPCAP = 1 << 8;
|
|
const CAP_LINUX_IMMUTABLE = 1 << 9;
|
|
const CAP_NET_BIND_SERVICE = 1 << 10;
|
|
const CAP_NET_BROADCAST = 1 << 11;
|
|
const CAP_NET_ADMIN = 1 << 12;
|
|
const CAP_NET_RAW = 1 << 13;
|
|
const CAP_IPC_LOCK = 1 << 14;
|
|
const CAP_IPC_OWNER = 1 << 15;
|
|
const CAP_SYS_MODULE = 1 << 16;
|
|
const CAP_SYS_RAWIO = 1 << 17;
|
|
const CAP_SYS_CHROOT = 1 << 18;
|
|
const CAP_SYS_PTRACE = 1 << 19;
|
|
const CAP_SYS_PACCT = 1 << 20;
|
|
const CAP_SYS_ADMIN = 1 << 21;
|
|
const CAP_SYS_BOOT = 1 << 22;
|
|
const CAP_SYS_NICE = 1 << 23;
|
|
const CAP_SYS_RESOURCE = 1 << 24;
|
|
const CAP_SYS_TIME = 1 << 25;
|
|
const CAP_SYS_TTY_CONFIG = 1 << 26;
|
|
const CAP_MKNOD = 1 << 27;
|
|
const CAP_LEASE = 1 << 28;
|
|
const CAP_AUDIT_WRITE = 1 << 29;
|
|
const CAP_AUDIT_CONTROL = 1 << 30;
|
|
const CAP_SETFCAP = 1 << 31;
|
|
const CAP_MAC_OVERRIDE = 1 << 32;
|
|
const CAP_MAC_ADMIN = 1 << 33;
|
|
const CAP_SYSLOG = 1 << 34;
|
|
const CAP_WAKE_ALARM = 1 << 35;
|
|
const CAP_BLOCK_SUSPEND = 1 << 36;
|
|
const CAP_AUDIT_READ = 1 << 37;
|
|
const CAP_PERFMON = 1 << 38;
|
|
const CAP_BPF = 1 << 39;
|
|
const CAP_CHECKPOINT_RESTORE = 1 << 40;
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
pub struct Capabilities {
|
|
effective: CapabilitiesFlags,
|
|
permitted: CapabilitiesFlags,
|
|
inheritable: CapabilitiesFlags,
|
|
ambient: CapabilitiesFlags,
|
|
bounding: CapabilitiesFlags,
|
|
}
|
|
|
|
impl Capabilities {
|
|
pub fn new(
|
|
effective: CapabilitiesFlags,
|
|
permitted: CapabilitiesFlags,
|
|
inheritable: CapabilitiesFlags,
|
|
ambient: CapabilitiesFlags,
|
|
bounding: CapabilitiesFlags,
|
|
) -> Self {
|
|
Self {
|
|
effective,
|
|
permitted,
|
|
inheritable,
|
|
ambient,
|
|
bounding,
|
|
}
|
|
}
|
|
|
|
pub fn new_root() -> Self {
|
|
Self {
|
|
effective: CapabilitiesFlags::all(),
|
|
permitted: CapabilitiesFlags::all(),
|
|
inheritable: CapabilitiesFlags::all(),
|
|
ambient: CapabilitiesFlags::all(),
|
|
bounding: CapabilitiesFlags::all(),
|
|
}
|
|
}
|
|
|
|
pub fn new_empty() -> Self {
|
|
Self {
|
|
effective: CapabilitiesFlags::empty(),
|
|
permitted: CapabilitiesFlags::empty(),
|
|
inheritable: CapabilitiesFlags::empty(),
|
|
ambient: CapabilitiesFlags::empty(),
|
|
bounding: CapabilitiesFlags::empty(),
|
|
}
|
|
}
|
|
|
|
/// Convenience method for creating capabilities with a single capability
|
|
pub fn new_cap(cap: CapabilitiesFlags) -> Self {
|
|
Self {
|
|
effective: cap,
|
|
permitted: cap,
|
|
inheritable: cap,
|
|
ambient: cap,
|
|
bounding: cap,
|
|
}
|
|
}
|
|
|
|
/// Set the publicly mutable fields on capabilities
|
|
pub fn set_public(
|
|
&mut self,
|
|
caller_caps: Capabilities,
|
|
effective: CapabilitiesFlags,
|
|
permitted: CapabilitiesFlags,
|
|
inheritable: CapabilitiesFlags,
|
|
) -> Result<()> {
|
|
// permitted should be a subset of self.permitted, and effective should be a subset of permitted
|
|
// inheritable should be a subset of self.bounding, or caller's effective should contain CAP_SETPCAP
|
|
if !self.permitted.contains(permitted)
|
|
|| !permitted.contains(effective)
|
|
|| (!self.bounding.contains(inheritable)
|
|
&& !caller_caps
|
|
.effective
|
|
.contains(CapabilitiesFlags::CAP_SETPCAP))
|
|
{
|
|
return Err(KernelError::NotPermitted);
|
|
}
|
|
self.effective = effective;
|
|
self.permitted = permitted;
|
|
self.inheritable = inheritable;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn effective(&self) -> CapabilitiesFlags {
|
|
self.effective
|
|
}
|
|
|
|
pub fn permitted(&self) -> CapabilitiesFlags {
|
|
self.permitted
|
|
}
|
|
|
|
pub fn inheritable(&self) -> CapabilitiesFlags {
|
|
self.inheritable
|
|
}
|
|
|
|
pub fn ambient(&self) -> CapabilitiesFlags {
|
|
self.ambient
|
|
}
|
|
|
|
pub fn bounding(&self) -> CapabilitiesFlags {
|
|
self.bounding
|
|
}
|
|
|
|
/// Checks if a capability is effective, as in if it can be used.
|
|
pub fn is_capable(&self, cap: CapabilitiesFlags) -> bool {
|
|
self.effective.contains(cap)
|
|
}
|
|
|
|
/// Shortcut for returning EPERM if a capability is not effective.
|
|
pub fn check_capable(&self, cap: CapabilitiesFlags) -> Result<()> {
|
|
if !self.effective.contains(cap) {
|
|
Err(KernelError::NotPermitted)
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|