use crate::compat::{Compatibility, ABI};
use crate::errors::SyscallFlagError;
use crate::private;
use crate::uapi;
pub trait SyscallFlag: Copy + core::fmt::Debug + private::Sealed {}
pub(crate) trait SyscallFlagExt: SyscallFlag {
fn default_value(self) -> bool;
fn raw_bit(self) -> u32;
fn since(self) -> ABI;
fn try_compat(
self,
set: bool,
compat: &mut Compatibility,
) -> Result<bool, SyscallFlagError<Self>> {
if set == self.default_value() {
return Ok(false);
}
compat.try_compat_binary(compat.abi() >= self.since(), || {
SyscallFlagError::NotSupported { flag: self, set }
})
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
#[allow(clippy::enum_variant_names)]
pub enum RestrictSelfFlag {
LogSameExec,
LogNewExec,
LogSubdomains,
}
impl SyscallFlag for RestrictSelfFlag {}
impl RestrictSelfFlag {
pub(crate) fn is_set(self, raw_flags: u32) -> bool {
if raw_flags & self.raw_bit() != 0 {
!self.default_value()
} else {
self.default_value()
}
}
}
impl SyscallFlagExt for RestrictSelfFlag {
fn default_value(self) -> bool {
match self {
Self::LogSameExec => true,
Self::LogNewExec => false,
Self::LogSubdomains => true,
}
}
fn raw_bit(self) -> u32 {
match self {
Self::LogSameExec => uapi::LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF,
Self::LogNewExec => uapi::LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON,
Self::LogSubdomains => uapi::LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF,
}
}
fn since(self) -> ABI {
match self {
Self::LogSameExec => ABI::V7,
Self::LogNewExec => ABI::V7,
Self::LogSubdomains => ABI::V7,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::uapi;
#[test]
fn restrict_self_flag_raw_bit() {
assert_eq!(
RestrictSelfFlag::LogSameExec.raw_bit(),
uapi::LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF,
);
assert_eq!(
RestrictSelfFlag::LogNewExec.raw_bit(),
uapi::LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON,
);
assert_eq!(
RestrictSelfFlag::LogSubdomains.raw_bit(),
uapi::LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF,
);
}
#[test]
fn restrict_self_flag_default_value() {
assert!(RestrictSelfFlag::LogSameExec.default_value());
assert!(!RestrictSelfFlag::LogNewExec.default_value());
assert!(RestrictSelfFlag::LogSubdomains.default_value());
}
#[test]
fn restrict_self_flag_since() {
assert_eq!(RestrictSelfFlag::LogSameExec.since(), ABI::V7);
assert_eq!(RestrictSelfFlag::LogNewExec.since(), ABI::V7);
assert_eq!(RestrictSelfFlag::LogSubdomains.since(), ABI::V7);
}
}