mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Limit the Linux /proc preflight filesystem view (#34409)
## What changed - Run the bubblewrap `/proc` mount probe with the minimal read-only filesystem policy instead of the command's filesystem policy and working directory. - Preserve the requested network namespace mode during the probe. - Add coverage that the probe mounts a temporary root and `/proc` without binding the full filesystem. GitOrigin-RevId: e3bc4352f510980aeebe81dedf3f9211947982ed
This commit is contained in:
1 parent
19940967bd
commit
44481a1c45
2 files changed
+39
-34
No files matched your search
@@ -27,7 +27,11 @@ use crate::proxy_routing::activate_proxy_routes_in_netns;
|
|||||||
use crate::proxy_routing::prepare_host_proxy_route_spec;
|
use crate::proxy_routing::prepare_host_proxy_route_spec;
|
||||||
use codex_protocol::error::Result as CodexResult;
|
use codex_protocol::error::Result as CodexResult;
|
||||||
use codex_protocol::models::PermissionProfile;
|
use codex_protocol::models::PermissionProfile;
|
||||||
|
use codex_protocol::protocol::FileSystemAccessMode;
|
||||||
|
use codex_protocol::protocol::FileSystemPath;
|
||||||
|
use codex_protocol::protocol::FileSystemSandboxEntry;
|
||||||
use codex_protocol::protocol::FileSystemSandboxPolicy;
|
use codex_protocol::protocol::FileSystemSandboxPolicy;
|
||||||
|
use codex_protocol::protocol::FileSystemSpecialPath;
|
||||||
use codex_protocol::protocol::NetworkSandboxPolicy;
|
use codex_protocol::protocol::NetworkSandboxPolicy;
|
||||||
use codex_sandboxing::landlock::CODEX_LINUX_SANDBOX_ARG0;
|
use codex_sandboxing::landlock::CODEX_LINUX_SANDBOX_ARG0;
|
||||||
|
|
||||||
@@ -328,13 +332,8 @@ fn run_bwrap_with_proc_fallback(
|
|||||||
let command_cwd = command_cwd.unwrap_or(sandbox_policy_cwd);
|
let command_cwd = command_cwd.unwrap_or(sandbox_policy_cwd);
|
||||||
|
|
||||||
if mount_proc
|
if mount_proc
|
||||||
&& !preflight_proc_mount_support(
|
&& !preflight_proc_mount_support(network_mode)
|
||||||
sandbox_policy_cwd,
|
.unwrap_or_else(|err| exit_with_bwrap_build_error(err))
|
||||||
command_cwd,
|
|
||||||
file_system_sandbox_policy,
|
|
||||||
network_mode,
|
|
||||||
)
|
|
||||||
.unwrap_or_else(|err| exit_with_bwrap_build_error(err))
|
|
||||||
{
|
{
|
||||||
// Keep the retry silent so sandbox-internal diagnostics do not leak into the
|
// Keep the retry silent so sandbox-internal diagnostics do not leak into the
|
||||||
// child process stderr stream.
|
// child process stderr stream.
|
||||||
@@ -441,34 +440,28 @@ fn current_process_argv0() -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn preflight_proc_mount_support(
|
fn preflight_proc_mount_support(network_mode: BwrapNetworkMode) -> CodexResult<bool> {
|
||||||
sandbox_policy_cwd: &Path,
|
let preflight_argv = build_preflight_bwrap_argv(network_mode)?;
|
||||||
command_cwd: &Path,
|
|
||||||
file_system_sandbox_policy: &FileSystemSandboxPolicy,
|
|
||||||
network_mode: BwrapNetworkMode,
|
|
||||||
) -> CodexResult<bool> {
|
|
||||||
let preflight_argv = build_preflight_bwrap_argv(
|
|
||||||
sandbox_policy_cwd,
|
|
||||||
command_cwd,
|
|
||||||
file_system_sandbox_policy,
|
|
||||||
network_mode,
|
|
||||||
)?;
|
|
||||||
let stderr = run_bwrap_in_child_capture_stderr(preflight_argv);
|
let stderr = run_bwrap_in_child_capture_stderr(preflight_argv);
|
||||||
Ok(!is_proc_mount_failure(stderr.as_str()))
|
Ok(!is_proc_mount_failure(stderr.as_str()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_preflight_bwrap_argv(
|
fn build_preflight_bwrap_argv(
|
||||||
sandbox_policy_cwd: &Path,
|
|
||||||
command_cwd: &Path,
|
|
||||||
file_system_sandbox_policy: &FileSystemSandboxPolicy,
|
|
||||||
network_mode: BwrapNetworkMode,
|
network_mode: BwrapNetworkMode,
|
||||||
) -> CodexResult<crate::bwrap::BwrapArgs> {
|
) -> CodexResult<crate::bwrap::BwrapArgs> {
|
||||||
|
let file_system_sandbox_policy =
|
||||||
|
FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry {
|
||||||
|
path: FileSystemPath::Special {
|
||||||
|
value: FileSystemSpecialPath::Minimal,
|
||||||
|
},
|
||||||
|
access: FileSystemAccessMode::Read,
|
||||||
|
}]);
|
||||||
let preflight_command = vec![resolve_true_command()];
|
let preflight_command = vec![resolve_true_command()];
|
||||||
build_bwrap_argv(
|
build_bwrap_argv(
|
||||||
preflight_command,
|
preflight_command,
|
||||||
file_system_sandbox_policy,
|
&file_system_sandbox_policy,
|
||||||
sandbox_policy_cwd,
|
Path::new("/"),
|
||||||
command_cwd,
|
Path::new("/"),
|
||||||
BwrapOptions {
|
BwrapOptions {
|
||||||
mount_proc: true,
|
mount_proc: true,
|
||||||
network_mode,
|
network_mode,
|
||||||
|
|||||||
@@ -258,20 +258,32 @@ fn root_write_read_only_carveout_requires_direct_runtime_enforcement() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn managed_proxy_preflight_argv_is_wrapped_for_full_access_policy() {
|
fn managed_proxy_preflight_argv_unshares_network() {
|
||||||
let mode = bwrap_network_mode(
|
let mode = bwrap_network_mode(
|
||||||
NetworkSandboxPolicy::Enabled,
|
NetworkSandboxPolicy::Enabled,
|
||||||
/*allow_network_for_proxy*/ true,
|
/*allow_network_for_proxy*/ true,
|
||||||
);
|
);
|
||||||
let argv = build_preflight_bwrap_argv(
|
let argv = build_preflight_bwrap_argv(mode)
|
||||||
Path::new("/"),
|
.expect("build preflight argv")
|
||||||
Path::new("/"),
|
.args;
|
||||||
&FileSystemSandboxPolicy::unrestricted(),
|
|
||||||
mode,
|
|
||||||
)
|
|
||||||
.expect("build preflight argv")
|
|
||||||
.args;
|
|
||||||
assert!(argv.iter().any(|arg| arg == "--"));
|
assert!(argv.iter().any(|arg| arg == "--"));
|
||||||
|
assert!(argv.iter().any(|arg| arg == "--unshare-net"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn proc_mount_preflight_does_not_bind_the_full_filesystem() {
|
||||||
|
let argv = build_preflight_bwrap_argv(BwrapNetworkMode::FullAccess)
|
||||||
|
.expect("build preflight argv")
|
||||||
|
.args;
|
||||||
|
|
||||||
|
assert!(argv.windows(2).any(|window| window == ["--tmpfs", "/"]));
|
||||||
|
assert!(argv.windows(2).any(|window| window == ["--proc", "/proc"]));
|
||||||
|
assert!(
|
||||||
|
!argv
|
||||||
|
.windows(3)
|
||||||
|
.any(|window| window == ["--ro-bind", "/", "/"])
|
||||||
|
);
|
||||||
|
assert!(!argv.windows(3).any(|window| window == ["--bind", "/", "/"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in new issue
Block a user