feat: flip the sense of the --sandbox option

This commit is contained in:
Michael Bolin
2025-04-29 14:24:12 -07:00
parent 3b39964f81
commit 32991d2fcc
21 changed files with 405 additions and 259 deletions
+1 -12
View File
@@ -5,7 +5,6 @@
use codex_core::protocol::SandboxPolicy;
use std::os::unix::process::ExitStatusExt;
use std::path::PathBuf;
use std::process;
use std::process::Command;
use std::process::ExitStatus;
@@ -15,7 +14,6 @@ use std::process::ExitStatus;
pub(crate) fn run_landlock(
command: Vec<String>,
sandbox_policy: SandboxPolicy,
writable_roots: Vec<PathBuf>,
) -> anyhow::Result<()> {
if command.is_empty() {
anyhow::bail!("command args are empty");
@@ -23,16 +21,7 @@ pub(crate) fn run_landlock(
// Spawn a new thread and apply the sandbox policies there.
let handle = std::thread::spawn(move || -> anyhow::Result<ExitStatus> {
// Apply sandbox policies inside this thread so only the child inherits
// them, not the entire CLI process.
if sandbox_policy.is_network_restricted() {
codex_core::linux::install_network_seccomp_filter_on_current_thread()?;
}
if sandbox_policy.is_file_write_restricted() {
codex_core::linux::install_filesystem_landlock_rules_on_current_thread(writable_roots)?;
}
codex_core::linux::apply_sandbox_policy_to_current_thread(sandbox_policy)?;
let status = Command::new(&command[0]).args(&command[1..]).status()?;
Ok(status)
});
+21 -11
View File
@@ -7,7 +7,7 @@ use std::path::PathBuf;
use clap::ArgAction;
use clap::Parser;
use codex_core::SandboxModeCliArg;
use codex_core::protocol::SandboxPolicy;
use codex_exec::Cli as ExecCli;
use codex_repl::Cli as ReplCli;
use codex_tui::Cli as TuiCli;
@@ -71,9 +71,9 @@ struct SeatbeltCommand {
#[arg(long = "writable-root", short = 'w', value_name = "DIR", action = ArgAction::Append, use_value_delimiter = false)]
writable_roots: Vec<PathBuf>,
/// Configure the process restrictions for the command.
#[arg(long = "sandbox", short = 's')]
sandbox_policy: SandboxModeCliArg,
/// Convenience alias for low-friction sandboxed automatic execution (network-disabled sandbox that can write to cwd and TMPDIR)
#[arg(long = "full-auto", default_value_t = false)]
full_auto: bool,
/// Full command args to run under seatbelt.
#[arg(trailing_var_arg = true)]
@@ -86,9 +86,9 @@ struct LandlockCommand {
#[arg(long = "writable-root", short = 'w', value_name = "DIR", action = ArgAction::Append, use_value_delimiter = false)]
writable_roots: Vec<PathBuf>,
/// Configure the process restrictions for the command.
#[arg(long = "sandbox", short = 's')]
sandbox_policy: SandboxModeCliArg,
/// Convenience alias for low-friction sandboxed automatic execution (network-disabled sandbox that can write to cwd and TMPDIR)
#[arg(long = "full-auto", default_value_t = false)]
full_auto: bool,
/// Full command args to run under landlock.
#[arg(trailing_var_arg = true)]
@@ -118,18 +118,20 @@ async fn main() -> anyhow::Result<()> {
Some(Subcommand::Debug(debug_args)) => match debug_args.cmd {
DebugCommand::Seatbelt(SeatbeltCommand {
command,
sandbox_policy,
writable_roots,
full_auto,
}) => {
seatbelt::run_seatbelt(command, sandbox_policy.into(), writable_roots).await?;
let sandbox_policy = create_sandbox_policy(full_auto, &writable_roots);
seatbelt::run_seatbelt(command, sandbox_policy).await?;
}
#[cfg(target_os = "linux")]
DebugCommand::Landlock(LandlockCommand {
command,
sandbox_policy,
writable_roots,
full_auto,
}) => {
landlock::run_landlock(command, sandbox_policy.into(), writable_roots)?;
let sandbox_policy = create_sandbox_policy(full_auto, &writable_roots);
landlock::run_landlock(command, sandbox_policy)?;
}
#[cfg(not(target_os = "linux"))]
DebugCommand::Landlock(_) => {
@@ -140,3 +142,11 @@ async fn main() -> anyhow::Result<()> {
Ok(())
}
fn create_sandbox_policy(full_auto: bool, writable_roots: &[PathBuf]) -> SandboxPolicy {
if full_auto {
SandboxPolicy::new_full_auto_policy_with_writable_roots(writable_roots)
} else {
SandboxPolicy::new_read_only_policy_with_writable_roots(writable_roots)
}
}
+1 -3
View File
@@ -1,13 +1,11 @@
use codex_core::exec::create_seatbelt_command;
use codex_core::protocol::SandboxPolicy;
use std::path::PathBuf;
pub(crate) async fn run_seatbelt(
command: Vec<String>,
sandbox_policy: SandboxPolicy,
writable_roots: Vec<PathBuf>,
) -> anyhow::Result<()> {
let seatbelt_command = create_seatbelt_command(command, sandbox_policy, &writable_roots);
let seatbelt_command = create_seatbelt_command(command, &sandbox_policy);
let status = tokio::process::Command::new(seatbelt_command[0].clone())
.args(&seatbelt_command[1..])
.spawn()