diff --git a/src/agents.rs b/src/agents.rs index 1a64f87..d6892c3 100644 --- a/src/agents.rs +++ b/src/agents.rs @@ -2,7 +2,7 @@ use std::env; use std::path::PathBuf; pub fn agent_rw_paths() -> Vec { - let home = match env::var("HOME") { + let home = match crate::require_home() { Ok(h) => PathBuf::from(h), Err(_) => return vec![], }; diff --git a/src/blacklist.rs b/src/blacklist.rs index 46a7c8f..f7fab8a 100644 --- a/src/blacklist.rs +++ b/src/blacklist.rs @@ -39,7 +39,7 @@ pub fn resolve_overlays(ctx: &PathContext) -> Result Result { - let home = std::env::var("HOME").map_err(|_| SandboxError::HomeNotSet)?; + let home = crate::require_home()?; let run_user = std::env::var("XDG_RUNTIME_DIR") .ok() .or_else(resolve_run_user_from_proc) diff --git a/src/lib.rs b/src/lib.rs index a86b186..00bf34c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ mod sandbox; pub use errors::SandboxError; +use std::env; use std::ffi::OsString; use std::os::unix::process::CommandExt; use std::path::PathBuf; @@ -27,6 +28,13 @@ pub struct SandboxConfig { pub dry_run: bool, } +pub fn require_home() -> Result { + env::var("HOME") + .ok() + .filter(|h| !h.is_empty()) + .ok_or(SandboxError::HomeNotSet) +} + pub fn run(config: SandboxConfig) -> Result<(), SandboxError> { preflight::check(&config)?; diff --git a/src/sandbox.rs b/src/sandbox.rs index 08a94dd..391cc1f 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -75,7 +75,7 @@ fn add_blacklist_mode(cmd: &mut Command) -> Result<(), SandboxError> { } fn add_whitelist_mode(cmd: &mut Command) -> Result<(), SandboxError> { - let home = std::env::var("HOME").map_err(|_| SandboxError::HomeNotSet)?; + let home = crate::require_home()?; cmd.args(["--ro-bind", "/usr", "/usr"]); for path in ["/lib", "/lib64", "/lib32", "/bin", "/sbin"] { diff --git a/tests/integration.rs b/tests/integration.rs index c5e5e04..8eb0292 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -284,6 +284,25 @@ fn relative_ro_path_works() { ); } +#[test] +fn empty_home_rejected() { + let output = sandbox(&[]) + .env("HOME", "") + .args(["--", "true"]) + .output() + .expect("agent-sandbox binary failed to execute"); + + assert!( + !output.status.success(), + "expected failure with empty HOME, but got success" + ); + let stderr = String::from_utf8_lossy(&output.stderr); + assert!( + stderr.to_lowercase().contains("home"), + "expected error mentioning HOME, got: {stderr}" + ); +} + #[test] fn rw_missing_path_errors() { let output = sandbox(&["--rw", "/nonexistent/xyz"])