mirror of
https://github.com/openai/codex.git
synced 2026-09-14 11:57:03 +00:00
fix(linux-sandbox): skip nested proxy netns setup
This commit is contained in:
@@ -90,6 +90,22 @@ pub fn run_main() -> ! {
|
||||
}
|
||||
ensure_inner_stage_mode_is_valid(apply_seccomp_then_exec, use_bwrap_sandbox);
|
||||
|
||||
let disable_nested_managed_proxy = should_disable_managed_proxy_for_nested_bwrap(
|
||||
allow_network_for_proxy,
|
||||
apply_seccomp_then_exec,
|
||||
);
|
||||
if disable_nested_managed_proxy {
|
||||
eprintln!(
|
||||
"codex-linux-sandbox: nested Codex bubblewrap sandbox detected; \
|
||||
skipping inner managed-proxy network namespace setup and relying on outer sandbox network restrictions"
|
||||
);
|
||||
}
|
||||
let allow_network_for_proxy = if disable_nested_managed_proxy {
|
||||
false
|
||||
} else {
|
||||
allow_network_for_proxy
|
||||
};
|
||||
|
||||
// Inner stage: apply seccomp/no_new_privs after bubblewrap has already
|
||||
// established the filesystem view.
|
||||
if apply_seccomp_then_exec {
|
||||
@@ -175,6 +191,63 @@ fn ensure_inner_stage_mode_is_valid(apply_seccomp_then_exec: bool, use_bwrap_san
|
||||
}
|
||||
}
|
||||
|
||||
fn should_disable_managed_proxy_for_nested_bwrap(
|
||||
allow_network_for_proxy: bool,
|
||||
apply_seccomp_then_exec: bool,
|
||||
) -> bool {
|
||||
should_disable_managed_proxy_for_nested_bwrap_with_ancestor_bwrap(
|
||||
allow_network_for_proxy,
|
||||
apply_seccomp_then_exec,
|
||||
has_bwrap_ancestor(),
|
||||
)
|
||||
}
|
||||
|
||||
fn should_disable_managed_proxy_for_nested_bwrap_with_ancestor_bwrap(
|
||||
allow_network_for_proxy: bool,
|
||||
apply_seccomp_then_exec: bool,
|
||||
has_bwrap_ancestor: bool,
|
||||
) -> bool {
|
||||
allow_network_for_proxy && !apply_seccomp_then_exec && has_bwrap_ancestor
|
||||
}
|
||||
|
||||
fn has_bwrap_ancestor() -> bool {
|
||||
const MAX_ANCESTOR_DEPTH: usize = 32;
|
||||
let mut pid = match parent_pid_of(std::process::id()) {
|
||||
Some(parent_pid) => parent_pid,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
for _ in 0..MAX_ANCESTOR_DEPTH {
|
||||
if pid == 0 {
|
||||
return false;
|
||||
}
|
||||
if process_comm(pid).as_deref() == Some("bwrap") {
|
||||
return true;
|
||||
}
|
||||
pid = match parent_pid_of(pid) {
|
||||
Some(parent_pid) if parent_pid != pid => parent_pid,
|
||||
_ => return false,
|
||||
};
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn process_comm(pid: u32) -> Option<String> {
|
||||
let path = format!("/proc/{pid}/comm");
|
||||
let comm = std::fs::read_to_string(path).ok()?;
|
||||
Some(comm.trim().to_string())
|
||||
}
|
||||
|
||||
fn parent_pid_of(pid: u32) -> Option<u32> {
|
||||
let path = format!("/proc/{pid}/status");
|
||||
let status = std::fs::read_to_string(path).ok()?;
|
||||
status
|
||||
.lines()
|
||||
.find_map(|line| line.strip_prefix("PPid:"))
|
||||
.and_then(|value| value.trim().parse::<u32>().ok())
|
||||
}
|
||||
|
||||
fn run_bwrap_with_proc_fallback(
|
||||
sandbox_policy_cwd: &Path,
|
||||
sandbox_policy: &codex_protocol::protocol::SandboxPolicy,
|
||||
|
||||
@@ -157,3 +157,23 @@ fn valid_inner_stage_modes_do_not_panic() {
|
||||
ensure_inner_stage_mode_is_valid(false, true);
|
||||
ensure_inner_stage_mode_is_valid(true, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_managed_proxy_fallback_only_applies_to_outer_stage() {
|
||||
assert_eq!(
|
||||
should_disable_managed_proxy_for_nested_bwrap_with_ancestor_bwrap(true, false, true),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
should_disable_managed_proxy_for_nested_bwrap_with_ancestor_bwrap(true, true, true),
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
should_disable_managed_proxy_for_nested_bwrap_with_ancestor_bwrap(true, false, false),
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
should_disable_managed_proxy_for_nested_bwrap_with_ancestor_bwrap(false, false, true),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user