mirror of
https://github.com/openai/codex.git
synced 2026-11-08 20:40:33 +00:00
feat: experimental env var: CODEX_SANDBOX_NETWORK_DISABLED
Previous to this change:
```
$ cargo run --bin codex -- debug seatbelt --full-auto -- cargo test
---- keeps_previous_response_id_between_tasks stdout ----
thread 'keeps_previous_response_id_between_tasks' panicked at /Users/mbolin/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wiremock-0.6.3/src/mock_server/builder.rs:107:46:
Failed to bind an OS port for a mock server.: Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
keeps_previous_response_id_between_tasks
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass `-p codex-core --test previous_response_id`
```
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
#[cfg(unix)]
|
||||
pub(crate) fn handle_exit_status(status: std::process::ExitStatus) -> ! {
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
|
||||
// Use ExitStatus to derive the exit code.
|
||||
if let Some(code) = status.code() {
|
||||
std::process::exit(code);
|
||||
} else if let Some(signal) = status.signal() {
|
||||
std::process::exit(128 + signal);
|
||||
} else {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(crate) fn handle_exit_status(status: std::process::ExitStatus) -> ! {
|
||||
if let Some(code) = status.code() {
|
||||
std::process::exit(code);
|
||||
} else {
|
||||
// Rare on Windows, but if it happens: use fallback code.
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,14 @@
|
||||
//! On Linux the command is executed inside a Landlock + seccomp sandbox by
|
||||
//! calling the low-level `exec_linux` helper from `codex_core::linux`.
|
||||
|
||||
use codex_core::exec::StdioPolicy;
|
||||
use codex_core::exec::spawn_child_sync;
|
||||
use codex_core::exec_linux::apply_sandbox_policy_to_current_thread;
|
||||
use codex_core::protocol::SandboxPolicy;
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
use std::process;
|
||||
use std::process::Command;
|
||||
use std::process::ExitStatus;
|
||||
|
||||
use crate::exit_status::handle_exit_status;
|
||||
|
||||
/// Execute `command` in a Linux sandbox (Landlock + seccomp) the way Codex
|
||||
/// would.
|
||||
pub fn run_landlock(command: Vec<String>, sandbox_policy: SandboxPolicy) -> anyhow::Result<()> {
|
||||
@@ -19,20 +21,15 @@ pub fn run_landlock(command: Vec<String>, sandbox_policy: SandboxPolicy) -> anyh
|
||||
// Spawn a new thread and apply the sandbox policies there.
|
||||
let handle = std::thread::spawn(move || -> anyhow::Result<ExitStatus> {
|
||||
let cwd = std::env::current_dir()?;
|
||||
codex_core::linux::apply_sandbox_policy_to_current_thread(sandbox_policy, &cwd)?;
|
||||
let status = Command::new(&command[0]).args(&command[1..]).status()?;
|
||||
|
||||
apply_sandbox_policy_to_current_thread(&sandbox_policy, &cwd)?;
|
||||
let mut child = spawn_child_sync(command, cwd, &sandbox_policy, StdioPolicy::Inherit)?;
|
||||
let status = child.wait()?;
|
||||
Ok(status)
|
||||
});
|
||||
let status = handle
|
||||
.join()
|
||||
.map_err(|e| anyhow::anyhow!("Failed to join thread: {e:?}"))??;
|
||||
|
||||
// Use ExitStatus to derive the exit code.
|
||||
if let Some(code) = status.code() {
|
||||
process::exit(code);
|
||||
} else if let Some(signal) = status.signal() {
|
||||
process::exit(128 + signal);
|
||||
} else {
|
||||
process::exit(1);
|
||||
}
|
||||
handle_exit_status(status);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#[cfg(target_os = "linux")]
|
||||
mod exit_status;
|
||||
#[cfg(unix)]
|
||||
pub mod landlock;
|
||||
pub mod proto;
|
||||
pub mod seatbelt;
|
||||
|
||||
@@ -3,6 +3,7 @@ use codex_cli::LandlockCommand;
|
||||
use codex_cli::SeatbeltCommand;
|
||||
use codex_cli::create_sandbox_policy;
|
||||
use codex_cli::proto;
|
||||
#[cfg(target_os = "macos")]
|
||||
use codex_cli::seatbelt;
|
||||
use codex_exec::Cli as ExecCli;
|
||||
use codex_tui::Cli as TuiCli;
|
||||
@@ -74,6 +75,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
proto::run_main(proto_cli).await?;
|
||||
}
|
||||
Some(Subcommand::Debug(debug_args)) => match debug_args.cmd {
|
||||
#[cfg(target_os = "macos")]
|
||||
DebugCommand::Seatbelt(SeatbeltCommand {
|
||||
command,
|
||||
sandbox,
|
||||
@@ -82,7 +84,11 @@ async fn main() -> anyhow::Result<()> {
|
||||
let sandbox_policy = create_sandbox_policy(full_auto, sandbox);
|
||||
seatbelt::run_seatbelt(command, sandbox_policy).await?;
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
DebugCommand::Seatbelt(_) => {
|
||||
anyhow::bail!("Seatbelt is only supported on macOS.");
|
||||
}
|
||||
#[cfg(unix)]
|
||||
DebugCommand::Landlock(LandlockCommand {
|
||||
command,
|
||||
sandbox,
|
||||
@@ -91,7 +97,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
let sandbox_policy = create_sandbox_policy(full_auto, sandbox);
|
||||
codex_cli::landlock::run_landlock(command, sandbox_policy)?;
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
#[cfg(not(unix))]
|
||||
DebugCommand::Landlock(_) => {
|
||||
anyhow::bail!("Landlock is only supported on Linux.");
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
use codex_core::exec::create_seatbelt_command;
|
||||
use codex_core::exec::StdioPolicy;
|
||||
use codex_core::exec::spawn_command_under_seatbelt;
|
||||
use codex_core::protocol::SandboxPolicy;
|
||||
|
||||
use crate::exit_status::handle_exit_status;
|
||||
|
||||
pub async fn run_seatbelt(
|
||||
command: Vec<String>,
|
||||
sandbox_policy: SandboxPolicy,
|
||||
) -> anyhow::Result<()> {
|
||||
let cwd = std::env::current_dir().expect("failed to get cwd");
|
||||
let seatbelt_command = create_seatbelt_command(command, &sandbox_policy, &cwd);
|
||||
let status = tokio::process::Command::new(seatbelt_command[0].clone())
|
||||
.args(&seatbelt_command[1..])
|
||||
.spawn()
|
||||
.map_err(|e| anyhow::anyhow!("Failed to spawn command: {}", e))?
|
||||
.wait()
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to wait for command: {}", e))?;
|
||||
std::process::exit(status.code().unwrap_or(1));
|
||||
let mut child =
|
||||
spawn_command_under_seatbelt(command, &sandbox_policy, cwd, StdioPolicy::Inherit).await?;
|
||||
let status = child.wait().await?;
|
||||
handle_exit_status(status);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user