Files
codex/codex-rs/sandboxing/src/landlock_tests.rs
T
Michael Bolin e6db1a9442 linux-sandbox: switch helper plumbing to PermissionProfile (#20106)
## Why

`PermissionProfile` is the canonical runtime permission model in the
Rust workspace, but the Linux sandbox helper still accepted a legacy
`SandboxPolicy` plus separate filesystem and network policy flags. That
translation layer made the helper interface harder to reason about and
left `linux-sandbox`-specific callers and tests coupled to the legacy
policy representation.

This change moves the helper onto `PermissionProfile` directly so the
Linux sandbox plumbing matches the rest of the permission stack.

## What changed

- changed `codex-linux-sandbox` to accept `--permission-profile` and
derive the runtime filesystem and network policies internally
- updated the in-process seccomp and legacy Landlock path in
`codex-rs/linux-sandbox` to operate on `PermissionProfile`
- updated Linux sandbox argv construction in `codex-rs/sandboxing`,
`codex-rs/core`, and the CLI debug sandbox path to pass the canonical
profile instead of serializing compatibility policy projections
- simplified the Linux sandbox tests to build the exact permission
profile under test, including the managed-proxy path and
direct-runtime-enforcement carveout coverage
- removed helper-local `SandboxPolicy` usage from `bwrap` tests where
`FileSystemSandboxPolicy` is already the value being exercised

## Testing

- `cargo test -p codex-sandboxing`
- `cargo test -p codex-linux-sandbox` (on this macOS host, the crate
compiled cleanly and its Linux-only tests were cfg-gated)
- `cargo test -p codex-core --no-run`
- `cargo test -p codex-cli --no-run`
2026-04-28 19:43:44 -07:00

93 lines
2.3 KiB
Rust

use super::*;
use pretty_assertions::assert_eq;
#[test]
fn legacy_landlock_flag_is_included_when_requested() {
let command = vec!["/bin/true".to_string()];
let command_cwd = Path::new("/tmp/link");
let cwd = Path::new("/tmp");
let default_bwrap = create_linux_sandbox_command_args(
command.clone(),
command_cwd,
cwd,
/*use_legacy_landlock*/ false,
/*allow_network_for_proxy*/ false,
);
assert_eq!(
default_bwrap.contains(&"--use-legacy-landlock".to_string()),
false
);
let legacy_landlock = create_linux_sandbox_command_args(
command,
command_cwd,
cwd,
/*use_legacy_landlock*/ true,
/*allow_network_for_proxy*/ false,
);
assert_eq!(
legacy_landlock.contains(&"--use-legacy-landlock".to_string()),
true
);
}
#[test]
fn proxy_flag_is_included_when_requested() {
let command = vec!["/bin/true".to_string()];
let command_cwd = Path::new("/tmp/link");
let cwd = Path::new("/tmp");
let args = create_linux_sandbox_command_args(
command,
command_cwd,
cwd,
/*use_legacy_landlock*/ true,
/*allow_network_for_proxy*/ true,
);
assert_eq!(
args.contains(&"--allow-network-for-proxy".to_string()),
true
);
}
#[test]
fn permission_profile_flag_is_included() {
let command = vec!["/bin/true".to_string()];
let command_cwd = Path::new("/tmp/link");
let cwd = Path::new("/tmp");
let permission_profile = PermissionProfile::read_only();
let args = create_linux_sandbox_command_args_for_permission_profile(
command,
command_cwd,
&permission_profile,
cwd,
/*use_legacy_landlock*/ true,
/*allow_network_for_proxy*/ false,
);
assert_eq!(
args.windows(2)
.any(|window| { window[0] == "--permission-profile" && !window[1].is_empty() }),
true
);
assert_eq!(
args.windows(2)
.any(|window| window[0] == "--command-cwd" && window[1] == "/tmp/link"),
true
);
}
#[test]
fn proxy_network_requires_managed_requirements() {
assert_eq!(
allow_network_for_proxy(/*enforce_managed_network*/ false),
false
);
assert_eq!(
allow_network_for_proxy(/*enforce_managed_network*/ true),
true
);
}