From be21bf1c5a65ce1f54dcf7565bf7da7933e8bbcd Mon Sep 17 00:00:00 2001 From: David Wiesen Date: Thu, 11 Jun 2026 09:19:12 -0700 Subject: [PATCH] Namespace arg0 helpers by runtime family --- codex-rs/arg0/src/lib.rs | 3 +- codex-rs/core/src/config/permissions.rs | 3 +- codex-rs/core/src/config/permissions_tests.rs | 3 +- codex-rs/utils/home-dir/src/lib.rs | 30 +++++++++++++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/codex-rs/arg0/src/lib.rs b/codex-rs/arg0/src/lib.rs index ba254d57ab..dd35b7df3b 100644 --- a/codex-rs/arg0/src/lib.rs +++ b/codex-rs/arg0/src/lib.rs @@ -8,6 +8,7 @@ use codex_apply_patch::CODEX_CORE_APPLY_PATCH_ARG1; use codex_exec_server::CODEX_FS_HELPER_ARG1; use codex_install_context::InstallContext; use codex_sandboxing::landlock::CODEX_LINUX_SANDBOX_ARG0; +use codex_utils_home_dir::arg0_temp_root_for_runtime; use codex_utils_home_dir::find_codex_home; #[cfg(unix)] use std::os::unix::fs::symlink; @@ -337,7 +338,7 @@ fn prepare_path_entry_for_codex_aliases( std::fs::create_dir_all(&codex_home)?; // Use a CODEX_HOME-scoped temp root to avoid cluttering the top-level directory. - let temp_root = codex_home.join("tmp").join("arg0"); + let temp_root = arg0_temp_root_for_runtime(codex_home.as_path()); std::fs::create_dir_all(&temp_root)?; #[cfg(unix)] { diff --git a/codex-rs/core/src/config/permissions.rs b/codex-rs/core/src/config/permissions.rs index f683d9c7eb..52c04ba257 100644 --- a/codex-rs/core/src/config/permissions.rs +++ b/codex-rs/core/src/config/permissions.rs @@ -37,6 +37,7 @@ use codex_protocol::permissions::FileSystemSpecialPath; use codex_protocol::permissions::NetworkSandboxPolicy; use codex_protocol::permissions::project_roots_glob_pattern; use codex_utils_absolute_path::AbsolutePathBuf; +use codex_utils_home_dir::arg0_temp_root_for_runtime; use super::ProjectConfig; @@ -483,7 +484,7 @@ pub(crate) fn get_readable_roots_required_for_codex_runtime( zsh_path: Option<&PathBuf>, main_execve_wrapper_exe: Option<&PathBuf>, ) -> Vec { - let arg0_root = AbsolutePathBuf::from_absolute_path(codex_home.join("tmp").join("arg0")).ok(); + let arg0_root = AbsolutePathBuf::from_absolute_path(arg0_temp_root_for_runtime(codex_home)).ok(); let zsh_path = zsh_path.and_then(|path| AbsolutePathBuf::from_absolute_path(path).ok()); let execve_wrapper_root = main_execve_wrapper_exe.and_then(|path| { let path = AbsolutePathBuf::from_absolute_path(path).ok()?; diff --git a/codex-rs/core/src/config/permissions_tests.rs b/codex-rs/core/src/config/permissions_tests.rs index 88a757181e..e4e77607a6 100644 --- a/codex-rs/core/src/config/permissions_tests.rs +++ b/codex-rs/core/src/config/permissions_tests.rs @@ -18,6 +18,7 @@ use codex_protocol::permissions::FileSystemSandboxEntry; use codex_protocol::permissions::FileSystemSandboxPolicy; use codex_protocol::permissions::FileSystemSpecialPath; use codex_utils_absolute_path::AbsolutePathBuf; +use codex_utils_home_dir::arg0_temp_root_for_runtime; use pretty_assertions::assert_eq; use std::collections::BTreeMap; use tempfile::TempDir; @@ -49,7 +50,7 @@ async fn restricted_read_implicitly_allows_helper_executables() -> std::io::Resu let cwd = temp_dir.path().join("workspace"); let codex_home = temp_dir.path().join(".codex"); let zsh_path = temp_dir.path().join("runtime").join("zsh"); - let arg0_root = codex_home.join("tmp").join("arg0"); + let arg0_root = arg0_temp_root_for_runtime(&codex_home); let allowed_arg0_dir = arg0_root.join("codex-arg0-session"); let sibling_arg0_dir = arg0_root.join("codex-arg0-other-session"); let execve_wrapper = allowed_arg0_dir.join("codex-execve-wrapper"); diff --git a/codex-rs/utils/home-dir/src/lib.rs b/codex-rs/utils/home-dir/src/lib.rs index caa43569c7..348b2c96d9 100644 --- a/codex-rs/utils/home-dir/src/lib.rs +++ b/codex-rs/utils/home-dir/src/lib.rs @@ -1,5 +1,6 @@ use codex_utils_absolute_path::AbsolutePathBuf; use dirs::home_dir; +use std::path::Path; use std::path::PathBuf; /// Returns the path to the Codex configuration directory, which can be @@ -17,6 +18,23 @@ pub fn find_codex_home() -> std::io::Result { find_codex_home_from_env(codex_home_env.as_deref()) } +/// Returns the CODEX_HOME-scoped arg0 helper root for the current runtime +/// family so Windows and Unix/WSL helper shims never share the same namespace. +pub fn arg0_temp_root_for_runtime(codex_home: &Path) -> PathBuf { + codex_home + .join("tmp") + .join("arg0") + .join(current_runtime_family()) +} + +fn current_runtime_family() -> &'static str { + if cfg!(windows) { + "windows" + } else { + "unix" + } +} + fn find_codex_home_from_env(codex_home_env: Option<&str>) -> std::io::Result { // Honor the `CODEX_HOME` environment variable when it is set to allow users // (and tests) to override the default location. @@ -64,6 +82,7 @@ fn find_codex_home_from_env(codex_home_env: Option<&str>) -> std::io::Result