Compare commits

...

7 Commits

5 changed files with 124 additions and 0 deletions

2
MODULE.bazel.lock generated
View File

@@ -1124,6 +1124,8 @@
"proc-macro-error2_2.0.1": "{\"dependencies\":[{\"name\":\"proc-macro-error-attr2\",\"req\":\"=2.0.0\"},{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"syn\",\"optional\":true,\"req\":\"^2\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"syn\",\"req\":\"^2\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.99\"}],\"features\":{\"default\":[\"syn-error\"],\"nightly\":[],\"syn-error\":[\"dep:syn\"]}}",
"proc-macro2_1.0.106": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"flate2\",\"req\":\"^1.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quote\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rayon\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tar\",\"req\":\"^0.4\"},{\"name\":\"unicode-ident\",\"req\":\"^1.0\"}],\"features\":{\"default\":[\"proc-macro\"],\"nightly\":[],\"proc-macro\":[],\"span-locations\":[]}}",
"process-wrap_9.0.1": "{\"dependencies\":[{\"name\":\"futures\",\"optional\":true,\"req\":\"^0.3.30\"},{\"name\":\"indexmap\",\"req\":\"^2.9.0\"},{\"default_features\":false,\"features\":[\"fs\",\"poll\",\"signal\"],\"name\":\"nix\",\"optional\":true,\"req\":\"^0.30.1\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"remoteprocess\",\"req\":\"^0.5.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.20.0\"},{\"features\":[\"io-util\",\"macros\",\"process\",\"rt\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1.38.2\"},{\"features\":[\"io-util\",\"macros\",\"process\",\"rt\",\"rt-multi-thread\",\"time\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.38.2\"},{\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.40\"},{\"name\":\"windows\",\"optional\":true,\"req\":\"^0.62.2\",\"target\":\"cfg(windows)\"}],\"features\":{\"creation-flags\":[\"dep:windows\",\"windows/Win32_System_Threading\"],\"default\":[\"creation-flags\",\"job-object\",\"kill-on-drop\",\"process-group\",\"process-session\",\"tracing\"],\"job-object\":[\"dep:windows\",\"windows/Win32_Security\",\"windows/Win32_System_Diagnostics_ToolHelp\",\"windows/Win32_System_IO\",\"windows/Win32_System_JobObjects\",\"windows/Win32_System_Threading\"],\"kill-on-drop\":[],\"process-group\":[],\"process-session\":[\"process-group\"],\"reset-sigmask\":[],\"std\":[\"dep:nix\"],\"tokio1\":[\"dep:nix\",\"dep:futures\",\"dep:tokio\"],\"tracing\":[\"dep:tracing\"]}}",
"procfs-core_0.18.0": "{\"dependencies\":[{\"name\":\"backtrace\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"bitflags\",\"req\":\"^2\"},{\"default_features\":false,\"features\":[\"clock\"],\"name\":\"chrono\",\"optional\":true,\"req\":\"^0.4.20\"},{\"name\":\"hex\",\"req\":\"^0.4\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"default\":[\"chrono\"],\"serde1\":[\"serde\",\"bitflags/serde\"]}}",
"procfs_0.18.0": "{\"dependencies\":[{\"name\":\"backtrace\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"bitflags\",\"req\":\"^2.0\"},{\"default_features\":false,\"features\":[\"clock\"],\"name\":\"chrono\",\"optional\":true,\"req\":\"^0.4.20\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"failure\",\"req\":\"^0.1\"},{\"name\":\"flate2\",\"optional\":true,\"req\":\"^1.0.3\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2.139\"},{\"default_features\":false,\"name\":\"procfs-core\",\"req\":\"^0.18.0\"},{\"kind\":\"dev\",\"name\":\"procinfo\",\"req\":\"^0.4.2\"},{\"features\":[\"fs\",\"process\",\"param\",\"system\",\"thread\"],\"name\":\"rustix\",\"req\":\"^1.0.1\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"backtrace\":[\"dep:backtrace\",\"procfs-core/backtrace\"],\"default\":[\"chrono\",\"flate2\",\"procfs-core/default\"],\"serde1\":[\"serde\",\"procfs-core/serde1\"]}}",
"proptest_1.9.0": "{\"dependencies\":[{\"name\":\"bit-set\",\"optional\":true,\"req\":\"^0.8.0\"},{\"name\":\"bit-vec\",\"optional\":true,\"req\":\"^0.8.0\"},{\"name\":\"bitflags\",\"req\":\"^2.9\"},{\"default_features\":false,\"name\":\"num-traits\",\"req\":\"^0.2.15\"},{\"name\":\"proptest-macro\",\"optional\":true,\"req\":\"^0.4.0\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"rand\",\"req\":\"^0.9\"},{\"default_features\":false,\"name\":\"rand_chacha\",\"req\":\"^0.9\"},{\"name\":\"rand_xorshift\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"regex\",\"req\":\"^1.0\"},{\"name\":\"regex-syntax\",\"optional\":true,\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"rusty-fork\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"tempfile\",\"optional\":true,\"req\":\"^3.0\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"=1.0.112\"},{\"name\":\"unarray\",\"req\":\"^0.1.4\"},{\"name\":\"x86\",\"optional\":true,\"req\":\"^0.52.0\"}],\"features\":{\"alloc\":[],\"atomic64bit\":[],\"attr-macro\":[\"proptest-macro\"],\"bit-set\":[\"dep:bit-set\",\"dep:bit-vec\"],\"default\":[\"std\",\"fork\",\"timeout\",\"bit-set\"],\"default-code-coverage\":[\"std\",\"fork\",\"timeout\",\"bit-set\"],\"fork\":[\"std\",\"rusty-fork\",\"tempfile\"],\"handle-panics\":[\"std\"],\"hardware-rng\":[\"x86\"],\"no_std\":[\"num-traits/libm\"],\"std\":[\"rand/std\",\"rand/os_rng\",\"regex-syntax\",\"num-traits/std\"],\"timeout\":[\"fork\",\"rusty-fork/timeout\"],\"unstable\":[]}}",
"prost-derive_0.14.3": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0.1\"},{\"name\":\"itertools\",\"req\":\">=0.10.1, <=0.14\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0.60\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"extra-traits\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}",
"prost_0.14.3": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bytes\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"name\":\"prost-derive\",\"optional\":true,\"req\":\"^0.14.3\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"}],\"features\":{\"default\":[\"derive\",\"std\"],\"derive\":[\"dep:prost-derive\"],\"no-recursion-limit\":[],\"std\":[]}}",

25
codex-rs/Cargo.lock generated
View File

@@ -2022,6 +2022,7 @@ dependencies = [
"libc",
"pkg-config",
"pretty_assertions",
"procfs",
"seccompiler",
"serde",
"serde_json",
@@ -6916,6 +6917,30 @@ dependencies = [
"windows 0.62.2",
]
[[package]]
name = "procfs"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7"
dependencies = [
"bitflags 2.10.0",
"chrono",
"flate2",
"procfs-core",
"rustix 1.1.3",
]
[[package]]
name = "procfs-core"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405"
dependencies = [
"bitflags 2.10.0",
"chrono",
"hex",
]
[[package]]
name = "proptest"
version = "1.9.0"

View File

@@ -22,6 +22,7 @@ codex-protocol = { workspace = true }
codex-utils-absolute-path = { workspace = true }
landlock = { workspace = true }
libc = { workspace = true }
procfs = "0.18"
seccompiler = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }

View File

@@ -1,4 +1,5 @@
use clap::Parser;
use procfs::process::Process;
use std::ffi::CString;
use std::fs::File;
use std::io::Read;
@@ -90,6 +91,20 @@ pub fn run_main() -> ! {
}
ensure_inner_stage_mode_is_valid(apply_seccomp_then_exec, use_bwrap_sandbox);
let disable_nested_managed_proxy =
allow_network_for_proxy && !apply_seccomp_then_exec && has_bwrap_ancestor();
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 +190,66 @@ fn ensure_inner_stage_mode_is_valid(apply_seccomp_then_exec: bool, use_bwrap_san
}
}
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 is_codex_bwrap_process(pid) {
return true;
}
pid = match parent_pid_of(pid) {
Some(parent_pid) if parent_pid != pid => parent_pid,
_ => return false,
};
}
false
}
fn is_codex_bwrap_process(pid: u32) -> bool {
if process_comm(pid).as_deref() != Some("bwrap") {
return false;
}
let cmdline = match process_cmdline(pid) {
Some(cmdline) => cmdline,
None => return false,
};
is_codex_bwrap_cmdline(cmdline.as_slice())
}
fn is_codex_bwrap_cmdline(cmdline: &[String]) -> bool {
cmdline
.windows(2)
.any(|pair| pair[0] == "--argv0" && pair[1] == "codex-linux-sandbox")
}
fn process_comm(pid: u32) -> Option<String> {
let pid = i32::try_from(pid).ok()?;
let process = Process::new(pid).ok()?;
let stat = process.stat().ok()?;
Some(stat.comm)
}
fn process_cmdline(pid: u32) -> Option<Vec<String>> {
let pid = i32::try_from(pid).ok()?;
let process = Process::new(pid).ok()?;
process.cmdline().ok()
}
fn parent_pid_of(pid: u32) -> Option<u32> {
let pid = i32::try_from(pid).ok()?;
let process = Process::new(pid).ok()?;
let stat = process.stat().ok()?;
u32::try_from(stat.ppid).ok()
}
fn run_bwrap_with_proc_fallback(
sandbox_policy_cwd: &Path,
sandbox_policy: &codex_protocol::protocol::SandboxPolicy,

View File

@@ -157,3 +157,24 @@ 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 codex_bwrap_cmdline_requires_argv0_marker() {
assert!(is_codex_bwrap_cmdline(&[
"bwrap".to_string(),
"--argv0".to_string(),
"codex-linux-sandbox".to_string(),
"--".to_string(),
"/path/to/codex-linux-sandbox".to_string(),
]));
assert!(!is_codex_bwrap_cmdline(&[
"bwrap".to_string(),
"--".to_string(),
"/bin/sh".to_string(),
]));
assert!(!is_codex_bwrap_cmdline(&[
"bwrap".to_string(),
"--argv0".to_string(),
"bash".to_string(),
]));
}