mirror of
https://github.com/openai/codex.git
synced 2026-05-04 05:11:37 +03: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:
@@ -42,18 +42,22 @@ pub(crate) fn apply_sandbox_policy_to_current_thread(
|
||||
sandbox_policy: &SandboxPolicy,
|
||||
cwd: &Path,
|
||||
apply_landlock_fs: bool,
|
||||
allow_network_for_proxy: bool,
|
||||
) -> Result<()> {
|
||||
let install_network_seccomp =
|
||||
should_install_network_seccomp(sandbox_policy, allow_network_for_proxy);
|
||||
|
||||
// `PR_SET_NO_NEW_PRIVS` is required for seccomp, but it also prevents
|
||||
// setuid privilege elevation. Many `bwrap` deployments rely on setuid, so
|
||||
// we avoid this unless we need seccomp or we are explicitly using the
|
||||
// legacy Landlock filesystem pipeline.
|
||||
if !sandbox_policy.has_full_network_access()
|
||||
if install_network_seccomp
|
||||
|| (apply_landlock_fs && !sandbox_policy.has_full_disk_write_access())
|
||||
{
|
||||
set_no_new_privs()?;
|
||||
}
|
||||
|
||||
if !sandbox_policy.has_full_network_access() {
|
||||
if install_network_seccomp {
|
||||
install_network_seccomp_filter_on_current_thread()?;
|
||||
}
|
||||
|
||||
@@ -72,6 +76,15 @@ pub(crate) fn apply_sandbox_policy_to_current_thread(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn should_install_network_seccomp(
|
||||
sandbox_policy: &SandboxPolicy,
|
||||
allow_network_for_proxy: bool,
|
||||
) -> bool {
|
||||
// Managed-network sessions should remain fail-closed even for policies that
|
||||
// would normally grant full network access (for example, DangerFullAccess).
|
||||
!sandbox_policy.has_full_network_access() || allow_network_for_proxy
|
||||
}
|
||||
|
||||
/// Enable `PR_SET_NO_NEW_PRIVS` so seccomp can be applied safely.
|
||||
fn set_no_new_privs() -> Result<()> {
|
||||
let result = unsafe { libc::prctl(libc::PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) };
|
||||
@@ -183,3 +196,38 @@ fn install_network_seccomp_filter_on_current_thread() -> std::result::Result<(),
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::should_install_network_seccomp;
|
||||
use codex_core::protocol::SandboxPolicy;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn managed_network_enforces_seccomp_even_for_full_network_policy() {
|
||||
assert_eq!(
|
||||
should_install_network_seccomp(&SandboxPolicy::DangerFullAccess, true),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn full_network_policy_without_managed_network_skips_seccomp() {
|
||||
assert_eq!(
|
||||
should_install_network_seccomp(&SandboxPolicy::DangerFullAccess, false),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn restricted_network_policy_always_installs_seccomp() {
|
||||
assert!(should_install_network_seccomp(
|
||||
&SandboxPolicy::ReadOnly,
|
||||
false
|
||||
));
|
||||
assert!(should_install_network_seccomp(
|
||||
&SandboxPolicy::ReadOnly,
|
||||
true
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user