From 8f30d2896529e811756a3886bee060aaaf0815d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Sun, 12 Apr 2026 14:36:07 +0200 Subject: [PATCH] Let --rw override --ro on a child path by emitting ro binds first --- src/sandbox.rs | 6 +++--- tests/integration.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/sandbox.rs b/src/sandbox.rs index 5f30e22..6091291 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -28,13 +28,13 @@ pub fn build_command(config: &SandboxConfig) -> Result { cmd.arg("--bind-try").arg(&path).arg(&path); } + for path in &config.extra_ro { + add_ro_bind(&mut cmd, path)?; + } add_rw_bind(&mut cmd, &config.chdir)?; for path in &config.extra_rw { add_rw_bind(&mut cmd, path)?; } - for path in &config.extra_ro { - add_ro_bind(&mut cmd, path)?; - } add_env_policy(&mut cmd, config); add_user_env_overrides(&mut cmd, config); diff --git a/tests/integration.rs b/tests/integration.rs index 8dac1a6..429232e 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -210,6 +210,40 @@ fn extra_rw_mount() { ); } +#[test] +fn rw_refines_ro_parent() { + let parent = TempDir::new().expect("failed to create temp dir"); + let child = parent.path().join("sub"); + fs::create_dir(&child).expect("failed to create sub dir"); + fs::write(parent.path().join("top.txt"), "top").expect("write"); + fs::write(child.join("inner.txt"), "inner").expect("write"); + let parent_str = parent.path().to_str().unwrap(); + let child_str = child.to_str().unwrap(); + + let output = sandbox(&["--ro", parent_str, "--rw", child_str]) + .args([ + "--", + "bash", + "-c", + &format!( + "touch {parent_str}/top_new 2>&1 || echo parent_ro; \ + touch {child_str}/child_new && echo child_rw" + ), + ]) + .output() + .expect("agent-sandbox binary failed to execute"); + + let stdout = String::from_utf8_lossy(&output.stdout); + assert!( + stdout.contains("parent_ro"), + "parent should be read-only, got: {stdout}" + ); + assert!( + stdout.contains("child_rw"), + "child should be writable, got: {stdout}" + ); +} + #[test] fn chdir_override() { let dir = TempDir::new().expect("failed to create temp dir");