Close hostile recovery and concurrency gaps
This commit is contained in:
parent
696dae610a
commit
3f9b1b3543
1 changed files with 306 additions and 113 deletions
|
|
@ -8,42 +8,55 @@ use rustix::thread::{
|
|||
#[allow(clippy::disallowed_methods, clippy::disallowed_types)]
|
||||
fn main() -> ExitCode {
|
||||
if std::env::var_os("LAZARET_CAPABILITY_DROP_ISOLATED").is_none() {
|
||||
let before = lazaret_linux::capability::inspect(CapabilitySet::NET_ADMIN)
|
||||
.expect("inspect unprivileged capability state");
|
||||
if lazaret_linux::capability::irreversibly_drop(CapabilitySet::NET_ADMIN).is_err()
|
||||
|| lazaret_linux::capability::inspect(CapabilitySet::NET_ADMIN).ok() != Some(before)
|
||||
{
|
||||
return ExitCode::FAILURE;
|
||||
}
|
||||
return match std::process::Command::new("unshare")
|
||||
let isolated = match std::process::Command::new("unshare")
|
||||
.args(["--user", "--map-root-user"])
|
||||
.arg(std::env::current_exe().expect("test executable path"))
|
||||
.env("LAZARET_CAPABILITY_DROP_ISOLATED", "1")
|
||||
.output()
|
||||
{
|
||||
Ok(output) if output.status.success() => ExitCode::SUCCESS,
|
||||
Ok(output) if output.status.success() => true,
|
||||
Ok(output)
|
||||
if String::from_utf8_lossy(&output.stderr).contains("Operation not permitted") =>
|
||||
{
|
||||
eprintln!("SKIP isolated capability-positive branch: user namespaces unavailable");
|
||||
ExitCode::SUCCESS
|
||||
true
|
||||
}
|
||||
Ok(output) => {
|
||||
eprintln!(
|
||||
"isolated capability-positive branch failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
ExitCode::FAILURE
|
||||
false
|
||||
}
|
||||
Err(error) if error.kind() == std::io::ErrorKind::NotFound => {
|
||||
eprintln!("SKIP isolated capability-positive branch: unshare is unavailable");
|
||||
ExitCode::SUCCESS
|
||||
true
|
||||
}
|
||||
Err(error) => {
|
||||
eprintln!("failed to run isolated capability-positive branch: {error}");
|
||||
ExitCode::FAILURE
|
||||
false
|
||||
}
|
||||
};
|
||||
if !isolated {
|
||||
return ExitCode::FAILURE;
|
||||
}
|
||||
let before = lazaret_linux::capability::inspect(CapabilitySet::NET_ADMIN)
|
||||
.expect("inspect unprivileged capability state");
|
||||
return match lazaret_linux::capability::irreversibly_drop(CapabilitySet::NET_ADMIN) {
|
||||
Ok(())
|
||||
if lazaret_linux::capability::require_regain_refused(CapabilitySet::NET_ADMIN)
|
||||
.is_ok() =>
|
||||
{
|
||||
ExitCode::SUCCESS
|
||||
}
|
||||
Err(_)
|
||||
if lazaret_linux::capability::inspect(CapabilitySet::NET_ADMIN).ok()
|
||||
== Some(before) =>
|
||||
{
|
||||
ExitCode::SUCCESS
|
||||
}
|
||||
Ok(()) | Err(_) => ExitCode::FAILURE,
|
||||
};
|
||||
}
|
||||
|
||||
let capability = CapabilitySet::NET_ADMIN;
|
||||
|
|
|
|||
Loading…
Reference in a new issue