Merge 6a9db12adb into sapling-pr-archive-bolinfest

This commit is contained in:
Michael Bolin
2026-04-30 09:15:01 -07:00
committed by GitHub
4 changed files with 153 additions and 140 deletions
+81 -58
View File
@@ -38,12 +38,12 @@ use codex_protocol::protocol::Event;
use codex_protocol::protocol::EventMsg;
use codex_protocol::protocol::ExecCommandOutputDeltaEvent;
use codex_protocol::protocol::ExecOutputStream;
use codex_protocol::protocol::SandboxPolicy;
use codex_sandboxing::SandboxCommand;
use codex_sandboxing::SandboxManager;
use codex_sandboxing::SandboxTransformRequest;
use codex_sandboxing::SandboxType;
use codex_sandboxing::SandboxablePreference;
use codex_sandboxing::compatibility_sandbox_policy_for_permission_profile;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_pty::DEFAULT_OUTPUT_BYTES_CAP;
use codex_utils_pty::process_group::kill_child_process_group;
@@ -111,6 +111,16 @@ pub(crate) struct WindowsSandboxFilesystemOverrides {
pub(crate) additional_deny_write_paths: Vec<AbsolutePathBuf>,
}
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
struct RawExecSandboxContext<'a> {
sandbox: SandboxType,
permission_profile: &'a PermissionProfile,
file_system_sandbox_policy: &'a FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
sandbox_policy_cwd: &'a AbsolutePathBuf,
windows_sandbox_filesystem_overrides: Option<&'a WindowsSandboxFilesystemOverrides>,
}
fn windows_sandbox_uses_elevated_backend(
sandbox_level: WindowsSandboxLevel,
proxy_enforced: bool,
@@ -392,11 +402,10 @@ pub fn build_exec_request(
exec_req.windows_sandbox_level,
exec_req.network.is_some(),
);
let sandbox_policy = exec_req.compatibility_sandbox_policy();
exec_req.windows_sandbox_filesystem_overrides = if use_windows_elevated_backend {
resolve_windows_elevated_filesystem_overrides(
exec_req.sandbox,
&sandbox_policy,
&exec_req.permission_profile,
&exec_req.file_system_sandbox_policy,
exec_req.network_sandbox_policy,
sandbox_cwd,
@@ -405,7 +414,7 @@ pub fn build_exec_request(
} else {
resolve_windows_restricted_token_filesystem_overrides(
exec_req.sandbox,
&sandbox_policy,
&exec_req.permission_profile,
&exec_req.file_system_sandbox_policy,
exec_req.network_sandbox_policy,
sandbox_cwd,
@@ -421,7 +430,6 @@ pub(crate) async fn execute_exec_request(
stdout_stream: Option<StdoutStream>,
after_spawn: Option<Box<dyn FnOnce() + Send>>,
) -> Result<ExecToolCallOutput> {
let sandbox_policy = exec_request.compatibility_sandbox_policy();
let ExecRequest {
command,
cwd,
@@ -431,11 +439,11 @@ pub(crate) async fn execute_exec_request(
expiration,
capture_policy,
sandbox,
windows_sandbox_policy_cwd: _,
windows_sandbox_policy_cwd,
windows_sandbox_level,
windows_sandbox_private_desktop,
permission_profile: _,
file_system_sandbox_policy: _,
permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
windows_sandbox_filesystem_overrides,
arg0,
@@ -456,38 +464,46 @@ pub(crate) async fn execute_exec_request(
};
let start = Instant::now();
let raw_output_result = get_raw_output_result(
params,
network_sandbox_policy,
stdout_stream,
after_spawn,
let sandbox_context = RawExecSandboxContext {
sandbox,
&sandbox_policy,
windows_sandbox_filesystem_overrides.as_ref(),
)
.await;
permission_profile: &permission_profile,
file_system_sandbox_policy: &file_system_sandbox_policy,
network_sandbox_policy,
sandbox_policy_cwd: &windows_sandbox_policy_cwd,
windows_sandbox_filesystem_overrides: windows_sandbox_filesystem_overrides.as_ref(),
};
let raw_output_result =
get_raw_output_result(params, stdout_stream, after_spawn, sandbox_context).await;
let duration = start.elapsed();
finalize_exec_result(raw_output_result, sandbox, duration)
}
async fn get_raw_output_result(
params: ExecParams,
network_sandbox_policy: NetworkSandboxPolicy,
stdout_stream: Option<StdoutStream>,
after_spawn: Option<Box<dyn FnOnce() + Send>>,
#[cfg_attr(not(windows), allow(unused_variables))] sandbox: SandboxType,
#[cfg_attr(not(windows), allow(unused_variables))] sandbox_policy: &SandboxPolicy,
#[cfg_attr(not(windows), allow(unused_variables))] windows_sandbox_filesystem_overrides: Option<
&WindowsSandboxFilesystemOverrides,
>,
sandbox_context: RawExecSandboxContext<'_>,
) -> Result<RawExecToolCallOutput> {
#[cfg(target_os = "windows")]
if sandbox == SandboxType::WindowsRestrictedToken {
return exec_windows_sandbox(params, sandbox_policy, windows_sandbox_filesystem_overrides)
.await;
if sandbox_context.sandbox == SandboxType::WindowsRestrictedToken {
return exec_windows_sandbox(
params,
sandbox_context.permission_profile,
sandbox_context.file_system_sandbox_policy,
sandbox_context.network_sandbox_policy,
sandbox_context.sandbox_policy_cwd,
sandbox_context.windows_sandbox_filesystem_overrides,
)
.await;
}
exec(params, network_sandbox_policy, stdout_stream, after_spawn).await
exec(
params,
sandbox_context.network_sandbox_policy,
stdout_stream,
after_spawn,
)
.await
}
#[cfg(target_os = "windows")]
@@ -559,7 +575,10 @@ fn record_windows_sandbox_spawn_failure(
#[cfg(target_os = "windows")]
async fn exec_windows_sandbox(
params: ExecParams,
sandbox_policy: &SandboxPolicy,
permission_profile: &PermissionProfile,
file_system_sandbox_policy: &FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
sandbox_policy_cwd: &AbsolutePathBuf,
windows_sandbox_filesystem_overrides: Option<&WindowsSandboxFilesystemOverrides>,
) -> Result<RawExecToolCallOutput> {
use crate::config::find_codex_home;
@@ -589,7 +608,13 @@ async fn exec_windows_sandbox(
None
};
let policy_str = serde_json::to_string(sandbox_policy).map_err(|err| {
let sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
sandbox_policy_cwd,
);
let policy_str = serde_json::to_string(&sandbox_policy).map_err(|err| {
CodexErr::Io(io::Error::other(format!(
"failed to serialize Windows sandbox policy: {err}"
)))
@@ -969,21 +994,16 @@ async fn exec(
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
fn should_use_windows_restricted_token_sandbox(
sandbox: SandboxType,
sandbox_policy: &SandboxPolicy,
file_system_sandbox_policy: &FileSystemSandboxPolicy,
) -> bool {
sandbox == SandboxType::WindowsRestrictedToken
&& file_system_sandbox_policy.kind == FileSystemSandboxKind::Restricted
&& !matches!(
sandbox_policy,
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }
)
}
#[cfg_attr(not(test), allow(dead_code))]
pub(crate) fn unsupported_windows_restricted_token_sandbox_reason(
sandbox: SandboxType,
sandbox_policy: &SandboxPolicy,
permission_profile: &PermissionProfile,
file_system_sandbox_policy: &FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
sandbox_policy_cwd: &AbsolutePathBuf,
@@ -992,7 +1012,7 @@ pub(crate) fn unsupported_windows_restricted_token_sandbox_reason(
if windows_sandbox_level == WindowsSandboxLevel::Elevated {
resolve_windows_elevated_filesystem_overrides(
sandbox,
sandbox_policy,
permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
sandbox_policy_cwd,
@@ -1002,7 +1022,7 @@ pub(crate) fn unsupported_windows_restricted_token_sandbox_reason(
} else {
resolve_windows_restricted_token_filesystem_overrides(
sandbox,
sandbox_policy,
permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
sandbox_policy_cwd,
@@ -1014,7 +1034,7 @@ pub(crate) fn unsupported_windows_restricted_token_sandbox_reason(
pub(crate) fn resolve_windows_restricted_token_filesystem_overrides(
sandbox: SandboxType,
sandbox_policy: &SandboxPolicy,
permission_profile: &PermissionProfile,
file_system_sandbox_policy: &FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
sandbox_policy_cwd: &AbsolutePathBuf,
@@ -1029,22 +1049,15 @@ pub(crate) fn resolve_windows_restricted_token_filesystem_overrides(
let needs_direct_runtime_enforcement = file_system_sandbox_policy
.needs_direct_runtime_enforcement(network_sandbox_policy, sandbox_policy_cwd);
if should_use_windows_restricted_token_sandbox(
sandbox,
sandbox_policy,
file_system_sandbox_policy,
) && !needs_direct_runtime_enforcement
if should_use_windows_restricted_token_sandbox(sandbox, file_system_sandbox_policy)
&& !needs_direct_runtime_enforcement
{
return Ok(None);
}
if !should_use_windows_restricted_token_sandbox(
sandbox,
sandbox_policy,
file_system_sandbox_policy,
) {
if !should_use_windows_restricted_token_sandbox(sandbox, file_system_sandbox_policy) {
return Err(format!(
"windows sandbox backend cannot enforce file_system={:?}, network={network_sandbox_policy:?}, legacy_policy={sandbox_policy:?}; refusing to run unsandboxed",
"windows sandbox backend cannot enforce file_system={:?}, network={network_sandbox_policy:?}, permission_profile={permission_profile:?}; refusing to run unsandboxed",
file_system_sandbox_policy.kind,
));
}
@@ -1069,7 +1082,14 @@ pub(crate) fn resolve_windows_restricted_token_filesystem_overrides(
);
}
let legacy_writable_roots = sandbox_policy.get_writable_roots_with_cwd(sandbox_policy_cwd);
let legacy_sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
sandbox_policy_cwd,
);
let legacy_writable_roots =
legacy_sandbox_policy.get_writable_roots_with_cwd(sandbox_policy_cwd);
let split_writable_roots =
file_system_sandbox_policy.get_writable_roots_with_cwd(sandbox_policy_cwd);
let legacy_root_paths: BTreeSet<PathBuf> = legacy_writable_roots
@@ -1154,7 +1174,7 @@ fn normalize_windows_override_path(path: &Path) -> std::result::Result<PathBuf,
pub(crate) fn resolve_windows_elevated_filesystem_overrides(
sandbox: SandboxType,
sandbox_policy: &SandboxPolicy,
permission_profile: &PermissionProfile,
file_system_sandbox_policy: &FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
sandbox_policy_cwd: &AbsolutePathBuf,
@@ -1164,13 +1184,9 @@ pub(crate) fn resolve_windows_elevated_filesystem_overrides(
return Ok(None);
}
if !should_use_windows_restricted_token_sandbox(
sandbox,
sandbox_policy,
file_system_sandbox_policy,
) {
if !should_use_windows_restricted_token_sandbox(sandbox, file_system_sandbox_policy) {
return Err(format!(
"windows sandbox backend cannot enforce file_system={:?}, network={network_sandbox_policy:?}, legacy_policy={sandbox_policy:?}; refusing to run unsandboxed",
"windows sandbox backend cannot enforce file_system={:?}, network={network_sandbox_policy:?}, permission_profile={permission_profile:?}; refusing to run unsandboxed",
file_system_sandbox_policy.kind,
));
}
@@ -1200,7 +1216,14 @@ pub(crate) fn resolve_windows_elevated_filesystem_overrides(
let needs_direct_runtime_enforcement = file_system_sandbox_policy
.needs_direct_runtime_enforcement(network_sandbox_policy, sandbox_policy_cwd);
let normalize_path = |path: PathBuf| dunce::canonicalize(&path).unwrap_or(path);
let legacy_writable_roots = sandbox_policy.get_writable_roots_with_cwd(sandbox_policy_cwd);
let legacy_sandbox_policy = compatibility_sandbox_policy_for_permission_profile(
permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
sandbox_policy_cwd,
);
let legacy_writable_roots =
legacy_sandbox_policy.get_writable_roots_with_cwd(sandbox_policy_cwd);
let legacy_root_paths: BTreeSet<PathBuf> = legacy_writable_roots
.iter()
.map(|root| normalize_path(root.root.to_path_buf()))
+67 -80
View File
@@ -378,15 +378,14 @@ async fn process_exec_tool_call_preserves_full_buffer_capture_policy() -> Result
#[test]
fn windows_restricted_token_skips_external_sandbox_policies() {
let policy = SandboxPolicy::ExternalSandbox {
network_access: codex_protocol::protocol::NetworkAccess::Restricted,
let permission_profile = PermissionProfile::External {
network: NetworkSandboxPolicy::Restricted,
};
let file_system_policy = FileSystemSandboxPolicy::from(&policy);
let file_system_policy = permission_profile.file_system_sandbox_policy();
assert_eq!(
should_use_windows_restricted_token_sandbox(
SandboxType::WindowsRestrictedToken,
&policy,
&file_system_policy,
),
false
@@ -395,13 +394,12 @@ fn windows_restricted_token_skips_external_sandbox_policies() {
#[test]
fn windows_restricted_token_runs_for_legacy_restricted_policies() {
let policy = SandboxPolicy::new_read_only_policy();
let file_system_policy = FileSystemSandboxPolicy::from(&policy);
let permission_profile = PermissionProfile::read_only();
let file_system_policy = permission_profile.file_system_sandbox_policy();
assert_eq!(
should_use_windows_restricted_token_sandbox(
SandboxType::WindowsRestrictedToken,
&policy,
&file_system_policy,
),
true
@@ -426,37 +424,38 @@ fn windows_proxy_enforcement_uses_elevated_backend() {
#[test]
fn windows_restricted_token_rejects_network_only_restrictions() {
let policy = SandboxPolicy::ExternalSandbox {
network_access: codex_protocol::protocol::NetworkAccess::Restricted,
};
let permission_profile = PermissionProfile::from_runtime_permissions(
&FileSystemSandboxPolicy::unrestricted(),
NetworkSandboxPolicy::Restricted,
);
let file_system_policy = FileSystemSandboxPolicy::unrestricted();
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
assert_eq!(
unsupported_windows_restricted_token_sandbox_reason(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&sandbox_policy_cwd,
WindowsSandboxLevel::RestrictedToken,
),
Some(
"windows sandbox backend cannot enforce file_system=Unrestricted, network=Restricted, legacy_policy=ExternalSandbox { network_access: Restricted }; refusing to run unsandboxed".to_string()
"windows sandbox backend cannot enforce file_system=Unrestricted, network=Restricted, permission_profile=Managed { file_system: Unrestricted, network: Restricted }; refusing to run unsandboxed".to_string()
)
);
}
#[test]
fn windows_restricted_token_allows_legacy_restricted_policies() {
let policy = SandboxPolicy::new_read_only_policy();
let file_system_policy = FileSystemSandboxPolicy::from(&policy);
let permission_profile = PermissionProfile::read_only();
let file_system_policy = permission_profile.file_system_sandbox_policy();
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
assert_eq!(
unsupported_windows_restricted_token_sandbox_reason(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&sandbox_policy_cwd,
@@ -468,19 +467,19 @@ fn windows_restricted_token_allows_legacy_restricted_policies() {
#[test]
fn windows_restricted_token_allows_legacy_workspace_write_policies() {
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::from(&policy);
let permission_profile = PermissionProfile::workspace_write_with(
&[],
NetworkSandboxPolicy::Restricted,
/*exclude_tmpdir_env_var*/ true,
/*exclude_slash_tmp*/ true,
);
let file_system_policy = permission_profile.file_system_sandbox_policy();
let sandbox_policy_cwd = AbsolutePathBuf::current_dir().expect("cwd");
assert_eq!(
unsupported_windows_restricted_token_sandbox_reason(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&sandbox_policy_cwd,
@@ -498,20 +497,21 @@ fn windows_elevated_allows_split_restricted_read_policies() {
)
.expect("absolute docs");
std::fs::create_dir_all(docs.as_path()).expect("create docs");
let policy = SandboxPolicy::ReadOnly {
network_access: false,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Path { path: docs },
access: codex_protocol::permissions::FileSystemAccessMode::Read,
},
]);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_policy,
NetworkSandboxPolicy::Restricted,
);
assert_eq!(
unsupported_windows_restricted_token_sandbox_reason(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&temp_dir.path().abs(),
@@ -526,12 +526,6 @@ fn windows_restricted_token_rejects_split_only_filesystem_policies() {
let temp_dir = tempfile::TempDir::new().expect("tempdir");
let docs = temp_dir.path().join("docs");
std::fs::create_dir_all(&docs).expect("create docs");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Special {
@@ -549,11 +543,15 @@ fn windows_restricted_token_rejects_split_only_filesystem_policies() {
access: codex_protocol::permissions::FileSystemAccessMode::Read,
},
]);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_policy,
NetworkSandboxPolicy::Restricted,
);
assert_eq!(
unsupported_windows_restricted_token_sandbox_reason(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&temp_dir.path().abs(),
@@ -571,12 +569,6 @@ fn windows_restricted_token_rejects_root_write_read_only_carveouts() {
let temp_dir = tempfile::TempDir::new().expect("tempdir");
let docs = temp_dir.path().join("docs");
std::fs::create_dir_all(&docs).expect("create docs");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Special {
@@ -592,11 +584,15 @@ fn windows_restricted_token_rejects_root_write_read_only_carveouts() {
access: codex_protocol::permissions::FileSystemAccessMode::Read,
},
]);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_policy,
NetworkSandboxPolicy::Restricted,
);
assert_eq!(
unsupported_windows_restricted_token_sandbox_reason(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&temp_dir.path().abs(),
@@ -617,12 +613,6 @@ fn windows_restricted_token_supports_full_read_split_write_read_carveouts() {
.abs();
let docs = cwd.join("docs");
std::fs::create_dir_all(docs.as_path()).expect("create docs");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Special {
@@ -643,6 +633,10 @@ fn windows_restricted_token_supports_full_read_split_write_read_carveouts() {
access: codex_protocol::permissions::FileSystemAccessMode::Read,
},
]);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_policy,
NetworkSandboxPolicy::Restricted,
);
// The legacy workspace-write root already protects top-level `.codex`, so
// the restricted-token overlay only needs the extra read-only docs carveout.
@@ -651,7 +645,7 @@ fn windows_restricted_token_supports_full_read_split_write_read_carveouts() {
assert_eq!(
resolve_windows_restricted_token_filesystem_overrides(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&cwd,
@@ -672,9 +666,6 @@ fn windows_elevated_supports_split_restricted_read_roots() {
let docs = temp_dir.path().join("docs");
std::fs::create_dir_all(&docs).expect("create docs");
let expected_docs = dunce::canonicalize(&docs).expect("canonical docs");
let policy = SandboxPolicy::ReadOnly {
network_access: false,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Path {
@@ -684,11 +675,15 @@ fn windows_elevated_supports_split_restricted_read_roots() {
access: codex_protocol::permissions::FileSystemAccessMode::Read,
},
]);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_policy,
NetworkSandboxPolicy::Restricted,
);
assert_eq!(
resolve_windows_elevated_filesystem_overrides(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&temp_dir.path().abs(),
@@ -709,12 +704,6 @@ fn windows_elevated_supports_split_write_read_carveouts() {
let docs = temp_dir.path().join("docs");
std::fs::create_dir_all(&docs).expect("create docs");
let expected_docs = dunce::canonicalize(&docs).expect("canonical docs");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Special {
@@ -738,11 +727,15 @@ fn windows_elevated_supports_split_write_read_carveouts() {
access: codex_protocol::permissions::FileSystemAccessMode::Read,
},
]);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_policy,
NetworkSandboxPolicy::Restricted,
);
assert_eq!(
resolve_windows_elevated_filesystem_overrides(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&temp_dir.path().abs(),
@@ -765,12 +758,6 @@ fn windows_elevated_rejects_unreadable_split_carveouts() {
let temp_dir = tempfile::TempDir::new().expect("tempdir");
let blocked = temp_dir.path().join("blocked");
std::fs::create_dir_all(&blocked).expect("create blocked");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Special {
@@ -794,11 +781,15 @@ fn windows_elevated_rejects_unreadable_split_carveouts() {
access: codex_protocol::permissions::FileSystemAccessMode::None,
},
]);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_policy,
NetworkSandboxPolicy::Restricted,
);
assert_eq!(
unsupported_windows_restricted_token_sandbox_reason(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&temp_dir.path().abs(),
@@ -814,12 +805,6 @@ fn windows_elevated_rejects_unreadable_split_carveouts() {
#[test]
fn windows_elevated_rejects_unreadable_globs() {
let temp_dir = tempfile::TempDir::new().expect("tempdir");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Special {
@@ -842,11 +827,15 @@ fn windows_elevated_rejects_unreadable_globs() {
access: codex_protocol::permissions::FileSystemAccessMode::None,
},
]);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_policy,
NetworkSandboxPolicy::Restricted,
);
assert_eq!(
unsupported_windows_restricted_token_sandbox_reason(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&temp_dir.path().abs(),
@@ -865,12 +854,6 @@ fn windows_elevated_rejects_reopened_writable_descendants() {
let docs = temp_dir.path().join("docs");
let nested = docs.join("nested");
std::fs::create_dir_all(&nested).expect("create nested");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let file_system_policy = FileSystemSandboxPolicy::restricted(vec![
codex_protocol::permissions::FileSystemSandboxEntry {
path: codex_protocol::permissions::FileSystemPath::Special {
@@ -901,11 +884,15 @@ fn windows_elevated_rejects_reopened_writable_descendants() {
access: codex_protocol::permissions::FileSystemAccessMode::Write,
},
]);
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_policy,
NetworkSandboxPolicy::Restricted,
);
assert_eq!(
unsupported_windows_restricted_token_sandbox_reason(
SandboxType::WindowsRestrictedToken,
&policy,
&permission_profile,
&file_system_policy,
NetworkSandboxPolicy::Restricted,
&temp_dir.path().abs(),
+4 -1
View File
@@ -22,9 +22,11 @@ use codex_protocol::models::PermissionProfile;
pub use codex_protocol::models::SandboxPermissions;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy;
#[cfg(target_os = "windows")]
use codex_protocol::protocol::SandboxPolicy;
use codex_sandboxing::SandboxExecRequest;
use codex_sandboxing::SandboxType;
#[cfg(target_os = "windows")]
use codex_sandboxing::compatibility_sandbox_policy_for_permission_profile;
use codex_utils_absolute_path::AbsolutePathBuf;
use std::collections::HashMap;
@@ -99,7 +101,8 @@ impl ExecRequest {
}
}
pub(crate) fn compatibility_sandbox_policy(&self) -> SandboxPolicy {
#[cfg(target_os = "windows")]
pub(crate) fn windows_compatibility_sandbox_policy(&self) -> SandboxPolicy {
compatibility_sandbox_policy_for_permission_profile(
&self.permission_profile,
&self.file_system_sandbox_policy,
@@ -877,7 +877,7 @@ impl UnifiedExecProcessManager {
#[cfg(target_os = "windows")]
if request.sandbox == codex_sandboxing::SandboxType::WindowsRestrictedToken {
let sandbox_policy = request.compatibility_sandbox_policy();
let sandbox_policy = request.windows_compatibility_sandbox_policy();
let policy_json = serde_json::to_string(&sandbox_policy).map_err(|err| {
UnifiedExecError::create_process(format!(
"failed to serialize Windows sandbox policy: {err}"