Bind persistent tmp dirs with --bind-fd so the sandbox inherits no host descriptor

This commit is contained in:
2026-11-04 18:10:43 +01:00
parent b5937b1a84
commit 14c4f44a1f
3 changed files with 65 additions and 16 deletions
+33
View File
@@ -463,6 +463,39 @@ fn persistent_tmp_survives_across_invocations() {
);
}
#[test]
fn persistent_tmp_leaks_no_descriptor_into_host_tmp() {
let label = format!("e2e-fd-escape-{}-{}", std::process::id(), rand_suffix());
let _cleanup_tmp = CleanupPath::new(format!("/tmp/agent-sandbox-{label}"));
let _cleanup_var = CleanupPath::new(format!("/var/tmp/agent-sandbox-{label}"));
let canary_name = format!("agent-sandbox-fd-canary-{label}");
let canary_host = format!("/tmp/{canary_name}");
let _cleanup_canary = CleanupPath::new(&canary_host);
fs::write(&canary_host, "host-secret").unwrap();
let output = Sandbox::new(&["--persistent-tmp", "--persistent-key", &label])
.args([
"--",
"bash",
"-c",
&format!(
"for fd in /proc/self/fd/*; do cat \"$fd/../{canary_name}\" 2>/dev/null; done; true"
),
])
.output()
.expect("agent-sandbox binary failed to execute");
assert!(
output.status.success(),
"stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
assert!(
!String::from_utf8_lossy(&output.stdout).contains("host-secret"),
"an inherited descriptor reaches host /tmp"
);
}
#[test]
fn persistent_tmp_is_noop_in_blacklist_mode() {
let label = format!("e2e-bl-noop-{}-{}", std::process::id(), rand_suffix());