mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
feat(sandbox): enforce proxy-aware network routing in sandbox (#11113)
## Summary - expand proxy env injection to cover common tool env vars (`HTTP_PROXY`/`HTTPS_PROXY`/`ALL_PROXY`/`NO_PROXY` families + tool-specific variants) - harden macOS Seatbelt network policy generation to route through inferred loopback proxy endpoints and fail closed when proxy env is malformed - thread proxy-aware Linux sandbox flags and add minimal bwrap netns isolation hook for restricted non-proxy runs - add/refresh tests for proxy env wiring, Seatbelt policy generation, and Linux sandbox argument wiring
This commit is contained in:
committed by
GitHub
Unverified
parent
b61ea47e83
commit
3391e5ea86
+28
-19
@@ -26,9 +26,10 @@ use crate::protocol::ExecCommandOutputDeltaEvent;
|
||||
use crate::protocol::ExecOutputStream;
|
||||
use crate::protocol::SandboxPolicy;
|
||||
use crate::sandboxing::CommandSpec;
|
||||
use crate::sandboxing::ExecEnv;
|
||||
use crate::sandboxing::ExecRequest;
|
||||
use crate::sandboxing::SandboxManager;
|
||||
use crate::sandboxing::SandboxPermissions;
|
||||
use crate::spawn::SpawnChildRequest;
|
||||
use crate::spawn::StdioPolicy;
|
||||
use crate::spawn::spawn_child_async;
|
||||
use crate::text_encoding::bytes_to_string_smart;
|
||||
@@ -157,9 +158,18 @@ pub async fn process_exec_tool_call(
|
||||
stdout_stream: Option<StdoutStream>,
|
||||
) -> Result<ExecToolCallOutput> {
|
||||
let windows_sandbox_level = params.windows_sandbox_level;
|
||||
let enforce_managed_network = params.network.is_some();
|
||||
let sandbox_type = match &sandbox_policy {
|
||||
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. } => {
|
||||
SandboxType::None
|
||||
if enforce_managed_network {
|
||||
get_platform_sandbox(
|
||||
windows_sandbox_level
|
||||
!= codex_protocol::config_types::WindowsSandboxLevel::Disabled,
|
||||
)
|
||||
.unwrap_or(SandboxType::None)
|
||||
} else {
|
||||
SandboxType::None
|
||||
}
|
||||
}
|
||||
_ => get_platform_sandbox(
|
||||
windows_sandbox_level != codex_protocol::config_types::WindowsSandboxLevel::Disabled,
|
||||
@@ -200,11 +210,13 @@ pub async fn process_exec_tool_call(
|
||||
};
|
||||
|
||||
let manager = SandboxManager::new();
|
||||
let exec_env = manager
|
||||
let exec_req = manager
|
||||
.transform(crate::sandboxing::SandboxTransformRequest {
|
||||
spec,
|
||||
policy: sandbox_policy,
|
||||
sandbox: sandbox_type,
|
||||
enforce_managed_network,
|
||||
network: network.as_ref(),
|
||||
sandbox_policy_cwd: sandbox_cwd,
|
||||
codex_linux_sandbox_exe: codex_linux_sandbox_exe.as_ref(),
|
||||
use_linux_sandbox_bwrap,
|
||||
@@ -213,19 +225,19 @@ pub async fn process_exec_tool_call(
|
||||
.map_err(CodexErr::from)?;
|
||||
|
||||
// Route through the sandboxing module for a single, unified execution path.
|
||||
crate::sandboxing::execute_env(exec_env, sandbox_policy, network, stdout_stream).await
|
||||
crate::sandboxing::execute_env(exec_req, sandbox_policy, stdout_stream).await
|
||||
}
|
||||
|
||||
pub(crate) async fn execute_exec_env(
|
||||
env: ExecEnv,
|
||||
env: ExecRequest,
|
||||
sandbox_policy: &SandboxPolicy,
|
||||
stdout_stream: Option<StdoutStream>,
|
||||
network: Option<NetworkProxy>,
|
||||
) -> Result<ExecToolCallOutput> {
|
||||
let ExecEnv {
|
||||
let ExecRequest {
|
||||
command,
|
||||
cwd,
|
||||
mut env,
|
||||
env,
|
||||
network,
|
||||
expiration,
|
||||
sandbox,
|
||||
windows_sandbox_level,
|
||||
@@ -234,10 +246,6 @@ pub(crate) async fn execute_exec_env(
|
||||
arg0,
|
||||
} = env;
|
||||
|
||||
if let Some(network) = network.as_ref() {
|
||||
network.apply_to_env(&mut env);
|
||||
}
|
||||
|
||||
let params = ExecParams {
|
||||
command,
|
||||
cwd,
|
||||
@@ -694,7 +702,7 @@ async fn exec(
|
||||
command,
|
||||
cwd,
|
||||
env,
|
||||
network: _,
|
||||
network,
|
||||
arg0,
|
||||
expiration,
|
||||
windows_sandbox_level: _,
|
||||
@@ -708,15 +716,16 @@ async fn exec(
|
||||
))
|
||||
})?;
|
||||
let arg0_ref = arg0.as_deref();
|
||||
let child = spawn_child_async(
|
||||
PathBuf::from(program),
|
||||
args.into(),
|
||||
arg0_ref,
|
||||
let child = spawn_child_async(SpawnChildRequest {
|
||||
program: PathBuf::from(program),
|
||||
args: args.into(),
|
||||
arg0: arg0_ref,
|
||||
cwd,
|
||||
sandbox_policy,
|
||||
StdioPolicy::RedirectForShellTool,
|
||||
network: network.as_ref(),
|
||||
stdio_policy: StdioPolicy::RedirectForShellTool,
|
||||
env,
|
||||
)
|
||||
})
|
||||
.await?;
|
||||
consume_truncated_output(child, expiration, stdout_stream).await
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user