Files
asterinas/kernel/src/process/credentials/capabilities.rs
2024-12-17 20:14:13 +08:00

104 lines
3.0 KiB
Rust

// SPDX-License-Identifier: MPL-2.0
use core::sync::atomic::{AtomicU64, Ordering};
use atomic_integer_wrapper::define_atomic_version_of_integer_like_type;
use bitflags::bitflags;
bitflags! {
/// Represents a set of Linux capabilities.
pub struct CapSet: u64 {
const CHOWN = 1 << 0;
const DAC_OVERRIDE = 1 << 1;
const DAC_READ_SEARCH = 1 << 2;
const FOWNER = 1 << 3;
const FSETID = 1 << 4;
const KILL = 1 << 5;
const SETGID = 1 << 6;
const SETUID = 1 << 7;
const SETPCAP = 1 << 8;
const LINUX_IMMUTABLE = 1 << 9;
const NET_BIND_SERVICE = 1 << 10;
const NET_BROADCAST = 1 << 11;
const NET_ADMIN = 1 << 12;
const NET_RAW = 1 << 13;
const IPC_LOCK = 1 << 14;
const IPC_OWNER = 1 << 15;
const SYS_MODULE = 1 << 16;
const SYS_RAWIO = 1 << 17;
const SYS_CHROOT = 1 << 18;
const SYS_PTRACE = 1 << 19;
const SYS_PACCT = 1 << 20;
const SYS_ADMIN = 1 << 21;
const SYS_BOOT = 1 << 22;
const SYS_NICE = 1 << 23;
const SYS_RESOURCE = 1 << 24;
const SYS_TIME = 1 << 25;
const SYS_TTY_CONFIG = 1 << 26;
const MKNOD = 1 << 27;
const LEASE = 1 << 28;
const AUDIT_WRITE = 1 << 29;
const AUDIT_CONTROL = 1 << 30;
const SETFCAP = 1 << 31;
const MAC_OVERRIDE = 1 << 32;
const MAC_ADMIN = 1 << 33;
const SYSLOG = 1 << 34;
const WAKE_ALARM = 1 << 35;
const BLOCK_SUSPEND = 1 << 36;
const AUDIT_READ = 1 << 37;
const PERFMON = 1 << 38;
const BPF = 1 << 39;
const CHECKPOINT_RESTORE = 1u64 << 40;
// ... include other capabilities as needed
}
}
impl CapSet {
const MASK: u64 = (1 << (CapSet::most_significant_bit() + 1)) - 1;
/// Converts the capability set to a `u32`. The higher bits are truncated.
pub fn as_u32(&self) -> u32 {
self.bits() as u32
}
/// Creates a new `CapSet` with a full capability set, typically for a root user.
pub const fn new_root() -> Self {
CapSet::all()
}
/// The most significant bit in a 64-bit `CapSet` that may be set to represent a Linux capability.
pub const fn most_significant_bit() -> u8 {
// CHECKPOINT_RESTORE is the Linux capability with the largest numerical value
40
}
}
impl TryFrom<u64> for CapSet {
type Error = &'static str;
fn try_from(value: u64) -> Result<Self, Self::Error> {
if value & !CapSet::MASK != 0 {
Err("Invalid CapSet.")
} else {
Ok(CapSet { bits: value })
}
}
}
impl From<CapSet> for u64 {
fn from(value: CapSet) -> Self {
value.bits()
}
}
define_atomic_version_of_integer_like_type!(CapSet, try_from = true, {
#[derive(Debug)]
pub(super) struct AtomicCapSet(AtomicU64);
});
impl Clone for AtomicCapSet {
fn clone(&self) -> Self {
Self::new(self.load(Ordering::Relaxed))
}
}