mirror of
https://github.com/openai/codex.git
synced 2026-11-10 21:00:47 +00:00
Preserve custom arg0 for sandboxed exec-server processes (#34497)
## Why Sandbox wrappers replaced the process launch command and did not carry an `ExecParams.arg0` override through to the inner process. ## What changed - Route sandboxed Unix launches with a custom `arg0` through a helper mode that re-execs the requested program with the override. - Expose the helper executable to the filesystem sandbox and dispatch its mode from Codex and exec-server test binaries. ## Testing Add coverage for the prepared sandbox command and an end-to-end remote process that verifies both the custom `arg0` and filesystem restrictions. GitOrigin-RevId: c9f8eef3906d184e670184c2eeed250d5895a9ca
This commit is contained in:
@@ -11,6 +11,8 @@ use codex_network_proxy::RemoteNetworkProxyLaunchConfig;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
#[cfg(any(unix, windows))]
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
#[cfg(target_os = "linux")]
|
||||
use codex_sandboxing::landlock::CODEX_LINUX_SANDBOX_ARG0;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_path_uri::PathUri;
|
||||
use pretty_assertions::assert_eq;
|
||||
@@ -19,6 +21,8 @@ use tokio::io::AsyncWriteExt;
|
||||
use tokio::time::timeout;
|
||||
|
||||
use super::prepare_exec_request;
|
||||
#[cfg(unix)]
|
||||
use crate::CODEX_ARG0_EXEC_HELPER_ARG1;
|
||||
use crate::ExecParams;
|
||||
#[cfg(any(unix, windows))]
|
||||
use crate::ExecServerRuntimePaths;
|
||||
@@ -93,6 +97,61 @@ async fn sandbox_request_wraps_native_argv_on_executor() {
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[tokio::test]
|
||||
async fn sandbox_request_routes_custom_arg0_to_inner_helper() {
|
||||
let cwd: AbsolutePathBuf = std::env::current_dir()
|
||||
.expect("current directory")
|
||||
.try_into()
|
||||
.expect("absolute cwd");
|
||||
let cwd_uri = PathUri::from_abs_path(&cwd);
|
||||
let self_exe = std::env::current_exe().expect("current executable");
|
||||
let runtime_paths =
|
||||
ExecServerRuntimePaths::new(self_exe.clone(), Some(self_exe)).expect("runtime paths");
|
||||
let sandbox = FileSystemSandboxContext::from_permission_profile_with_cwd(
|
||||
PermissionProfile::workspace_write(),
|
||||
cwd_uri.clone(),
|
||||
);
|
||||
let params = ExecParams {
|
||||
process_id: ProcessId::from("process-custom-arg0"),
|
||||
argv: vec!["/bin/sh".to_string(), "-c".to_string(), "true".to_string()],
|
||||
cwd: cwd_uri,
|
||||
env_policy: None,
|
||||
env: HashMap::new(),
|
||||
tty: false,
|
||||
pipe_stdin: false,
|
||||
arg0: Some("custom-arg0".to_string()),
|
||||
sandbox: Some(sandbox),
|
||||
enforce_managed_network: false,
|
||||
managed_network: None,
|
||||
network_proxy: None,
|
||||
};
|
||||
|
||||
let prepared = prepare_exec_request(¶ms, HashMap::new(), Some(&runtime_paths))
|
||||
.await
|
||||
.expect("prepare sandboxed request");
|
||||
let helper_mode = prepared
|
||||
.command
|
||||
.iter()
|
||||
.position(|arg| arg == CODEX_ARG0_EXEC_HELPER_ARG1)
|
||||
.expect("sandboxed command should invoke arg0 helper");
|
||||
|
||||
assert_eq!(
|
||||
prepared.command[helper_mode..],
|
||||
[
|
||||
CODEX_ARG0_EXEC_HELPER_ARG1,
|
||||
"custom-arg0",
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"true",
|
||||
]
|
||||
);
|
||||
#[cfg(target_os = "linux")]
|
||||
assert_eq!(prepared.arg0, Some(CODEX_LINUX_SANDBOX_ARG0.to_string()));
|
||||
#[cfg(target_os = "macos")]
|
||||
assert_eq!(prepared.arg0, None);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[tokio::test]
|
||||
async fn sandbox_request_allows_prepared_managed_proxy_port() {
|
||||
|
||||
Reference in New Issue
Block a user