Add fail-closed Linux process and descriptor primitives
This commit is contained in:
parent
b34421efa1
commit
1468f6b841
1 changed files with 1725 additions and 15 deletions
123
crates/lazaret-linux/src/platform.rs
Normal file
123
crates/lazaret-linux/src/platform.rs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
use std::fmt;
|
||||
|
||||
pub const MINIMUM_KERNEL_MAJOR: u64 = 6;
|
||||
pub const MINIMUM_KERNEL_MINOR: u64 = 9;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct PlatformObservation<'a> {
|
||||
pub operating_system: &'a str,
|
||||
pub architecture: &'a str,
|
||||
pub kernel_release: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum PlatformRefusal {
|
||||
OperatingSystem(String),
|
||||
Architecture(String),
|
||||
KernelRelease(String),
|
||||
KernelFloor { major: u64, minor: u64 },
|
||||
}
|
||||
|
||||
impl fmt::Display for PlatformRefusal {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::OperatingSystem(value) => {
|
||||
write!(formatter, "unsupported operating system {value}")
|
||||
}
|
||||
Self::Architecture(value) => write!(formatter, "unsupported architecture {value}"),
|
||||
Self::KernelRelease(value) => write!(formatter, "invalid Linux kernel release {value}"),
|
||||
Self::KernelFloor { major, minor } => write!(
|
||||
formatter,
|
||||
"Linux kernel {major}.{minor} is below the required 6.9 floor"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for PlatformRefusal {}
|
||||
|
||||
/// # Errors
|
||||
/// Refuses unsupported operating systems, architectures, and kernel releases.
|
||||
pub fn check_platform(observation: &PlatformObservation<'_>) -> Result<(), PlatformRefusal> {
|
||||
if observation.operating_system != "linux" {
|
||||
return Err(PlatformRefusal::OperatingSystem(
|
||||
observation.operating_system.into(),
|
||||
));
|
||||
}
|
||||
if observation.architecture != "x86_64" {
|
||||
return Err(PlatformRefusal::Architecture(
|
||||
observation.architecture.into(),
|
||||
));
|
||||
}
|
||||
let (major, minor) = parse_kernel_release(observation.kernel_release)?;
|
||||
if (major, minor) < (MINIMUM_KERNEL_MAJOR, MINIMUM_KERNEL_MINOR) {
|
||||
return Err(PlatformRefusal::KernelFloor { major, minor });
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
/// Refuses releases without numeric major and minor components.
|
||||
pub fn parse_kernel_release(release: &str) -> Result<(u64, u64), PlatformRefusal> {
|
||||
let mut components = release.split('.');
|
||||
let major = components
|
||||
.next()
|
||||
.and_then(|value| value.parse().ok())
|
||||
.ok_or_else(|| PlatformRefusal::KernelRelease(release.into()))?;
|
||||
let minor = components
|
||||
.next()
|
||||
.and_then(|value| {
|
||||
value
|
||||
.split_once('-')
|
||||
.map_or(value, |(number, _)| number)
|
||||
.parse()
|
||||
.ok()
|
||||
})
|
||||
.ok_or_else(|| PlatformRefusal::KernelRelease(release.into()))?;
|
||||
Ok((major, minor))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{PlatformObservation, PlatformRefusal, check_platform};
|
||||
|
||||
#[test]
|
||||
fn accepts_floor_and_newer_linux_x86_64() {
|
||||
for release in ["6.9.0", "6.9.12-custom", "6.10.0", "7.0"] {
|
||||
check_platform(&PlatformObservation {
|
||||
operating_system: "linux",
|
||||
architecture: "x86_64",
|
||||
kernel_release: release,
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_older_kernel_and_other_platforms() {
|
||||
let old = check_platform(&PlatformObservation {
|
||||
operating_system: "linux",
|
||||
architecture: "x86_64",
|
||||
kernel_release: "6.8.14",
|
||||
});
|
||||
assert_eq!(
|
||||
old,
|
||||
Err(PlatformRefusal::KernelFloor { major: 6, minor: 8 })
|
||||
);
|
||||
|
||||
for observation in [
|
||||
PlatformObservation {
|
||||
operating_system: "freebsd",
|
||||
architecture: "x86_64",
|
||||
kernel_release: "14.0",
|
||||
},
|
||||
PlatformObservation {
|
||||
operating_system: "linux",
|
||||
architecture: "aarch64",
|
||||
kernel_release: "6.9.0",
|
||||
},
|
||||
] {
|
||||
assert!(check_platform(&observation).is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue