use crate::orchestration::CapabilityPolicy;
use crate::stdlib::sandbox::sandbox_rejection;
use crate::value::VmError;
pub(super) fn confine(policy: &CapabilityPolicy) -> Result<(), VmError> {
let threads = std::fs::read_dir("/proc/self/task")
.map(|tasks| tasks.count())
.map_err(|error| {
sandbox_rejection(format!("cannot count this process's threads: {error}"))
})?;
if threads != 1 {
return Err(sandbox_rejection(format!(
"Landlock confines only the calling thread, and this process already runs {threads} \
threads; confine it before starting any other"
)));
}
let program = std::env::current_exe()
.map(|path| path.display().to_string())
.unwrap_or_default();
let landlock = super::landlock_profile(&program, policy, policy.sandbox_profile)?;
super::add_landlock_rules(&landlock).map_err(|error| {
sandbox_rejection(format!(
"failed to populate the Linux Landlock ruleset: {error}"
))
})?;
super::enter_landlock_ruleset(landlock.ruleset_fd)
.and_then(|()| super::confirm_filesystem_boundary_holds())
.map_err(|error| sandbox_rejection(format!("failed to confine this process: {error}")))
}