diff --git a/src/sandbox.rs b/src/sandbox.rs index 9429c9e..08a94dd 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -57,6 +57,12 @@ fn add_blacklist_mode(cmd: &mut Command) -> Result<(), SandboxError> { let ctx = blacklist::resolve_path_context()?; cmd.args(["--ro-bind", "/", "/"]); + cmd.args(["--dev-bind", "/dev", "/dev"]); + cmd.args(["--proc", "/proc"]); + cmd.args(["--bind", "/tmp", "/tmp"]); + cmd.args(["--bind", "/var/tmp", "/var/tmp"]); + cmd.args(["--bind", "/run", "/run"]); + let overlays = blacklist::resolve_overlays(&ctx)?; for dir in &overlays.tmpfs_dirs { cmd.arg("--tmpfs").arg(dir); @@ -65,12 +71,6 @@ fn add_blacklist_mode(cmd: &mut Command) -> Result<(), SandboxError> { cmd.arg("--ro-bind").arg("/dev/null").arg(file); } - cmd.args(["--dev-bind", "/dev", "/dev"]); - cmd.args(["--proc", "/proc"]); - cmd.args(["--bind", "/tmp", "/tmp"]); - cmd.args(["--bind", "/var/tmp", "/var/tmp"]); - cmd.args(["--bind", "/run", "/run"]); - Ok(()) } diff --git a/tests/integration.rs b/tests/integration.rs index 8c5c202..b44dee8 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -211,6 +211,32 @@ fn dry_run_prints_and_exits() { ); } +#[test] +fn blacklist_overlays_survive_tmp_bind() { + fs::write("/tmp/ssh-sandbox-test", "secret").expect("failed to write sentinel"); + let _cleanup = CleanupFile("/tmp/ssh-sandbox-test"); + + let output = sandbox(&[]) + .args([ + "--", + "bash", + "-c", + "cat /tmp/ssh-sandbox-test 2>/dev/null && echo LEAKED || echo HIDDEN", + ]) + .output() + .expect("agent-sandbox binary failed to execute"); + + let stdout = String::from_utf8_lossy(&output.stdout); + assert!( + stdout.contains("HIDDEN"), + "expected /tmp/ssh-* to be hidden in blacklist mode, got: {stdout}" + ); + assert!( + !stdout.contains("LEAKED"), + "/tmp/ssh-sandbox-test was readable inside the sandbox" + ); +} + #[test] fn rw_missing_path_errors() { let output = sandbox(&["--rw", "/nonexistent/xyz"])