mirror of
https://github.com/openai/codex.git
synced 2026-05-17 20:06:25 +03:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87d2951cf2 |
@@ -179,10 +179,13 @@ pub fn run_elevated_setup(
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
) -> anyhow::Result<()> {
|
||||
let permissions =
|
||||
codex_windows_sandbox::ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(
|
||||
policy, policy_cwd,
|
||||
);
|
||||
codex_windows_sandbox::run_elevated_setup(
|
||||
codex_windows_sandbox::SandboxSetupRequest {
|
||||
policy,
|
||||
policy_cwd,
|
||||
permissions: &permissions,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::policy::SandboxPolicy;
|
||||
use crate::resolved_permissions::ResolvedWindowsSandboxPermissions;
|
||||
use dunce::canonicalize;
|
||||
use std::collections::HashMap;
|
||||
@@ -12,17 +11,6 @@ pub struct AllowDenyPaths {
|
||||
pub deny: HashSet<PathBuf>,
|
||||
}
|
||||
|
||||
pub(crate) fn compute_allow_paths(
|
||||
policy: &SandboxPolicy,
|
||||
policy_cwd: &Path,
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
) -> AllowDenyPaths {
|
||||
let permissions =
|
||||
ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(policy, policy_cwd);
|
||||
compute_allow_paths_for_permissions(&permissions, command_cwd, env_map)
|
||||
}
|
||||
|
||||
pub(crate) fn compute_allow_paths_for_permissions(
|
||||
permissions: &ResolvedWindowsSandboxPermissions,
|
||||
command_cwd: &Path,
|
||||
@@ -61,6 +49,17 @@ mod tests {
|
||||
use std::fs;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn compute_allow_paths(
|
||||
policy: &SandboxPolicy,
|
||||
policy_cwd: &Path,
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
) -> AllowDenyPaths {
|
||||
let permissions =
|
||||
ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(policy, policy_cwd);
|
||||
compute_allow_paths_for_permissions(&permissions, command_cwd, env_map)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn includes_additional_writable_roots() {
|
||||
let tmp = TempDir::new().expect("tempdir");
|
||||
|
||||
@@ -224,15 +224,33 @@ pub fn apply_world_writable_scan_and_denies(
|
||||
env_map: &std::collections::HashMap<String, String>,
|
||||
sandbox_policy: &SandboxPolicy,
|
||||
logs_base_dir: Option<&Path>,
|
||||
) -> Result<()> {
|
||||
let permissions =
|
||||
ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(sandbox_policy, cwd);
|
||||
apply_world_writable_scan_and_denies_for_permissions(
|
||||
codex_home,
|
||||
cwd,
|
||||
env_map,
|
||||
&permissions,
|
||||
logs_base_dir,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn apply_world_writable_scan_and_denies_for_permissions(
|
||||
codex_home: &Path,
|
||||
cwd: &Path,
|
||||
env_map: &std::collections::HashMap<String, String>,
|
||||
permissions: &ResolvedWindowsSandboxPermissions,
|
||||
logs_base_dir: Option<&Path>,
|
||||
) -> Result<()> {
|
||||
let flagged = audit_everyone_writable(cwd, env_map, logs_base_dir)?;
|
||||
if flagged.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
if let Err(err) = apply_capability_denies_for_world_writable(
|
||||
if let Err(err) = apply_capability_denies_for_world_writable_for_permissions(
|
||||
codex_home,
|
||||
&flagged,
|
||||
sandbox_policy,
|
||||
permissions,
|
||||
cwd,
|
||||
env_map,
|
||||
logs_base_dir,
|
||||
@@ -245,10 +263,10 @@ pub fn apply_world_writable_scan_and_denies(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn apply_capability_denies_for_world_writable(
|
||||
fn apply_capability_denies_for_world_writable_for_permissions(
|
||||
codex_home: &Path,
|
||||
flagged: &[PathBuf],
|
||||
sandbox_policy: &SandboxPolicy,
|
||||
permissions: &ResolvedWindowsSandboxPermissions,
|
||||
cwd: &Path,
|
||||
env_map: &std::collections::HashMap<String, String>,
|
||||
logs_base_dir: Option<&Path>,
|
||||
@@ -260,18 +278,13 @@ pub fn apply_capability_denies_for_world_writable(
|
||||
let cap_path = cap_sid_file(codex_home);
|
||||
let caps = load_or_create_cap_sids(codex_home)?;
|
||||
std::fs::write(&cap_path, serde_json::to_string(&caps)?)?;
|
||||
if matches!(
|
||||
sandbox_policy,
|
||||
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }
|
||||
) {
|
||||
if !permissions.is_enforceable_by_windows_sandbox() {
|
||||
return Ok(());
|
||||
}
|
||||
let permissions =
|
||||
ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(sandbox_policy, cwd);
|
||||
let (active_sids, workspace_roots): (Vec<LocalSid>, Vec<PathBuf>) =
|
||||
if permissions.uses_write_capabilities_for_cwd(cwd, env_map) {
|
||||
let roots = effective_write_roots_for_permissions(
|
||||
&permissions,
|
||||
permissions,
|
||||
cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
|
||||
@@ -97,8 +97,7 @@ mod windows_impl {
|
||||
let logs_base_dir: Option<&Path> = Some(sandbox_base.as_path());
|
||||
log_start(&command, logs_base_dir);
|
||||
let sandbox_creds = require_logon_sandbox_creds(
|
||||
&policy,
|
||||
sandbox_policy_cwd,
|
||||
&permissions,
|
||||
cwd,
|
||||
&env_map,
|
||||
codex_home,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::dpapi;
|
||||
use crate::logging::debug_log;
|
||||
use crate::policy::SandboxPolicy;
|
||||
use crate::resolved_permissions::ResolvedWindowsSandboxPermissions;
|
||||
use crate::setup::SandboxNetworkIdentity;
|
||||
use crate::setup::SandboxUserRecord;
|
||||
@@ -132,8 +131,7 @@ fn select_identity(
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn require_logon_sandbox_creds(
|
||||
policy: &SandboxPolicy,
|
||||
policy_cwd: &Path,
|
||||
permissions: &ResolvedWindowsSandboxPermissions,
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
@@ -144,16 +142,14 @@ pub fn require_logon_sandbox_creds(
|
||||
deny_write_paths_override: &[PathBuf],
|
||||
proxy_enforced: bool,
|
||||
) -> Result<SandboxCreds> {
|
||||
let permissions =
|
||||
ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(policy, policy_cwd);
|
||||
let sandbox_dir = crate::setup::sandbox_dir(codex_home);
|
||||
let needed_read = read_roots_override
|
||||
.map(<[PathBuf]>::to_vec)
|
||||
.unwrap_or_else(|| gather_read_roots(command_cwd, policy, codex_home));
|
||||
.unwrap_or_else(|| gather_read_roots(command_cwd, permissions, env_map, codex_home));
|
||||
let needed_write = write_roots_override
|
||||
.map(<[PathBuf]>::to_vec)
|
||||
.unwrap_or_else(|| gather_write_roots_for_permissions(&permissions, command_cwd, env_map));
|
||||
let network_identity = SandboxNetworkIdentity::from_permissions(&permissions, proxy_enforced);
|
||||
.unwrap_or_else(|| gather_write_roots_for_permissions(permissions, command_cwd, env_map));
|
||||
let network_identity = SandboxNetworkIdentity::from_permissions(permissions, proxy_enforced);
|
||||
let desired_offline_proxy_settings = offline_proxy_settings_from_env(env_map, network_identity);
|
||||
// NOTE: Do not add CODEX_HOME/.sandbox to `needed_write`; it must remain non-writable by the
|
||||
// restricted capability token. The setup helper's `lock_sandbox_dir` is responsible for
|
||||
@@ -194,8 +190,7 @@ pub fn require_logon_sandbox_creds(
|
||||
}
|
||||
run_elevated_setup(
|
||||
crate::setup::SandboxSetupRequest {
|
||||
policy,
|
||||
policy_cwd,
|
||||
permissions,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
@@ -214,8 +209,7 @@ pub fn require_logon_sandbox_creds(
|
||||
// Always refresh ACLs (non-elevated) for current roots via the setup binary.
|
||||
run_setup_refresh_with_overrides(
|
||||
crate::setup::SandboxSetupRequest {
|
||||
policy,
|
||||
policy_cwd,
|
||||
permissions,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
|
||||
@@ -108,6 +108,8 @@ pub use acl::path_mask_allows;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use audit::apply_world_writable_scan_and_denies;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use audit::apply_world_writable_scan_and_denies_for_permissions;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use cap::load_or_create_cap_sids;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use cap::workspace_cap_sid_for_cwd;
|
||||
@@ -197,6 +199,8 @@ pub use process::read_handle_loop;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use process::spawn_process_with_pipes;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use resolved_permissions::ResolvedWindowsSandboxPermissions;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use resolved_permissions::WindowsSandboxTokenMode;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use resolved_permissions::token_mode_for_permission_profile;
|
||||
@@ -290,6 +294,7 @@ mod windows_impl {
|
||||
use super::logging::log_success;
|
||||
use super::policy::SandboxPolicy;
|
||||
use super::process::create_process_as_user;
|
||||
use super::resolved_permissions::ResolvedWindowsSandboxPermissions;
|
||||
use super::sandbox_utils::ensure_codex_home_exists;
|
||||
use super::spawn_prep::LegacyAclSids;
|
||||
use super::spawn_prep::SpawnPrepOptions;
|
||||
@@ -412,6 +417,7 @@ mod windows_impl {
|
||||
},
|
||||
)?;
|
||||
let policy = common.policy;
|
||||
let permissions = common.permissions;
|
||||
let current_dir = common.current_dir;
|
||||
let logs_base_dir = common.logs_base_dir.as_deref();
|
||||
let uses_write_capabilities = common.uses_write_capabilities;
|
||||
@@ -436,8 +442,7 @@ mod windows_impl {
|
||||
allow_null_device_for_workspace_write(uses_write_capabilities);
|
||||
let persist_aces = uses_write_capabilities;
|
||||
let guards = apply_legacy_session_acl_rules(
|
||||
&policy,
|
||||
sandbox_policy_cwd,
|
||||
&permissions,
|
||||
codex_home,
|
||||
¤t_dir,
|
||||
&env_map,
|
||||
@@ -620,8 +625,10 @@ mod windows_impl {
|
||||
);
|
||||
let write_root_sids = root_capability_sids(codex_home, cwd, capability_roots)?;
|
||||
let _guards = apply_legacy_session_acl_rules(
|
||||
sandbox_policy,
|
||||
sandbox_policy_cwd,
|
||||
&ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(
|
||||
sandbox_policy,
|
||||
sandbox_policy_cwd,
|
||||
),
|
||||
codex_home,
|
||||
¤t_dir,
|
||||
env_map,
|
||||
|
||||
@@ -17,7 +17,7 @@ use std::path::PathBuf;
|
||||
/// Windows-specific path conventions, not the user/config-facing
|
||||
/// `PermissionProfile` enum itself.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(crate) struct ResolvedWindowsSandboxPermissions {
|
||||
pub struct ResolvedWindowsSandboxPermissions {
|
||||
file_system: FileSystemSandboxPolicy,
|
||||
network: NetworkSandboxPolicy,
|
||||
}
|
||||
@@ -56,7 +56,7 @@ pub fn token_mode_for_permission_profile(
|
||||
}
|
||||
|
||||
impl ResolvedWindowsSandboxPermissions {
|
||||
pub(crate) fn from_legacy_policy_for_cwd(policy: &SandboxPolicy, cwd: &Path) -> Self {
|
||||
pub fn from_legacy_policy_for_cwd(policy: &SandboxPolicy, cwd: &Path) -> Self {
|
||||
Self {
|
||||
file_system: FileSystemSandboxPolicy::from_legacy_sandbox_policy_for_cwd(policy, cwd)
|
||||
.materialize_project_roots_with_cwd(cwd),
|
||||
@@ -64,9 +64,7 @@ impl ResolvedWindowsSandboxPermissions {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn try_from_permission_profile(
|
||||
permission_profile: &PermissionProfile,
|
||||
) -> Result<Self> {
|
||||
pub fn try_from_permission_profile(permission_profile: &PermissionProfile) -> Result<Self> {
|
||||
if !matches!(permission_profile, PermissionProfile::Managed { .. }) {
|
||||
anyhow::bail!(
|
||||
"only managed permission profiles can be enforced by the Windows sandbox"
|
||||
@@ -92,6 +90,26 @@ impl ResolvedWindowsSandboxPermissions {
|
||||
self.network
|
||||
}
|
||||
|
||||
pub(crate) fn is_enforceable_by_windows_sandbox(&self) -> bool {
|
||||
matches!(self.file_system.kind, FileSystemSandboxKind::Restricted)
|
||||
}
|
||||
|
||||
pub(crate) fn has_full_disk_read_access(&self) -> bool {
|
||||
self.file_system.has_full_disk_read_access()
|
||||
}
|
||||
|
||||
pub(crate) fn include_platform_defaults(&self) -> bool {
|
||||
self.file_system.include_platform_defaults()
|
||||
}
|
||||
|
||||
pub(crate) fn readable_roots_for_cwd(&self, cwd: &Path) -> Vec<PathBuf> {
|
||||
self.file_system
|
||||
.get_readable_roots_with_cwd(cwd)
|
||||
.into_iter()
|
||||
.map(AbsolutePathBuf::into_path_buf)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn uses_write_capabilities_for_cwd(
|
||||
&self,
|
||||
cwd: &Path,
|
||||
|
||||
@@ -11,7 +11,7 @@ use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
|
||||
use crate::allow::AllowDenyPaths;
|
||||
use crate::allow::compute_allow_paths;
|
||||
use crate::allow::compute_allow_paths_for_permissions;
|
||||
use crate::helper_materialization::helper_bin_dir;
|
||||
use crate::logging::log_note;
|
||||
use crate::path_normalization::canonical_path_key;
|
||||
@@ -85,8 +85,7 @@ pub fn sandbox_users_path(codex_home: &Path) -> PathBuf {
|
||||
}
|
||||
|
||||
pub struct SandboxSetupRequest<'a> {
|
||||
pub policy: &'a SandboxPolicy,
|
||||
pub policy_cwd: &'a Path,
|
||||
pub permissions: &'a ResolvedWindowsSandboxPermissions,
|
||||
pub command_cwd: &'a Path,
|
||||
pub env_map: &'a HashMap<String, String>,
|
||||
pub codex_home: &'a Path,
|
||||
@@ -110,10 +109,17 @@ pub fn run_setup_refresh(
|
||||
codex_home: &Path,
|
||||
proxy_enforced: bool,
|
||||
) -> Result<()> {
|
||||
if matches!(
|
||||
policy,
|
||||
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }
|
||||
) {
|
||||
return Ok(());
|
||||
}
|
||||
let permissions =
|
||||
ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(policy, policy_cwd);
|
||||
run_setup_refresh_inner(
|
||||
SandboxSetupRequest {
|
||||
policy,
|
||||
policy_cwd,
|
||||
permissions: &permissions,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
@@ -139,12 +145,19 @@ pub fn run_setup_refresh_with_extra_read_roots(
|
||||
extra_read_roots: Vec<PathBuf>,
|
||||
proxy_enforced: bool,
|
||||
) -> Result<()> {
|
||||
let mut read_roots = gather_read_roots(command_cwd, policy, codex_home);
|
||||
if matches!(
|
||||
policy,
|
||||
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }
|
||||
) {
|
||||
return Ok(());
|
||||
}
|
||||
let permissions =
|
||||
ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(policy, policy_cwd);
|
||||
let mut read_roots = gather_read_roots(command_cwd, &permissions, env_map, codex_home);
|
||||
read_roots.extend(extra_read_roots);
|
||||
run_setup_refresh_inner(
|
||||
SandboxSetupRequest {
|
||||
policy,
|
||||
policy_cwd,
|
||||
permissions: &permissions,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
@@ -164,22 +177,14 @@ fn run_setup_refresh_inner(
|
||||
request: SandboxSetupRequest<'_>,
|
||||
overrides: SetupRootOverrides,
|
||||
) -> Result<()> {
|
||||
// Skip in danger-full-access.
|
||||
if matches!(
|
||||
request.policy,
|
||||
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }
|
||||
) {
|
||||
return Ok(());
|
||||
if !request.permissions.is_enforceable_by_windows_sandbox() {
|
||||
anyhow::bail!("unsupported filesystem permissions for Windows sandbox setup");
|
||||
}
|
||||
let (read_roots, write_roots) = build_payload_roots(&request, &overrides);
|
||||
let deny_read_paths = build_payload_deny_read_paths(overrides.deny_read_paths);
|
||||
let deny_write_paths = build_payload_deny_write_paths(&request, overrides.deny_write_paths);
|
||||
let permissions = ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(
|
||||
request.policy,
|
||||
request.policy_cwd,
|
||||
);
|
||||
let network_identity =
|
||||
SandboxNetworkIdentity::from_permissions(&permissions, request.proxy_enforced);
|
||||
SandboxNetworkIdentity::from_permissions(request.permissions, request.proxy_enforced);
|
||||
let offline_proxy_settings = offline_proxy_settings_from_env(request.env_map, network_identity);
|
||||
let payload = ElevationPayload {
|
||||
version: SETUP_VERSION,
|
||||
@@ -363,9 +368,10 @@ fn gather_helper_read_roots(codex_home: &Path) -> Vec<PathBuf> {
|
||||
vec![helper_dir]
|
||||
}
|
||||
|
||||
fn gather_legacy_full_read_roots(
|
||||
fn gather_full_read_roots_for_permissions(
|
||||
command_cwd: &Path,
|
||||
policy: &SandboxPolicy,
|
||||
permissions: &ResolvedWindowsSandboxPermissions,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
) -> Vec<PathBuf> {
|
||||
let mut roots = gather_helper_read_roots(codex_home);
|
||||
@@ -378,20 +384,40 @@ fn gather_legacy_full_read_roots(
|
||||
roots.extend(profile_read_roots(Path::new(&up)));
|
||||
}
|
||||
roots.push(command_cwd.to_path_buf());
|
||||
if let SandboxPolicy::WorkspaceWrite { writable_roots, .. } = policy {
|
||||
for root in writable_roots {
|
||||
roots.push(root.to_path_buf());
|
||||
}
|
||||
}
|
||||
roots.extend(
|
||||
permissions
|
||||
.writable_roots_for_cwd(command_cwd, env_map)
|
||||
.into_iter()
|
||||
.map(|root| root.root),
|
||||
);
|
||||
canonical_existing(&roots)
|
||||
}
|
||||
|
||||
pub(crate) fn gather_read_roots(
|
||||
command_cwd: &Path,
|
||||
policy: &SandboxPolicy,
|
||||
permissions: &ResolvedWindowsSandboxPermissions,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
) -> Vec<PathBuf> {
|
||||
gather_legacy_full_read_roots(command_cwd, policy, codex_home)
|
||||
if permissions.has_full_disk_read_access() {
|
||||
return gather_full_read_roots_for_permissions(
|
||||
command_cwd,
|
||||
permissions,
|
||||
env_map,
|
||||
codex_home,
|
||||
);
|
||||
}
|
||||
|
||||
let mut roots = gather_helper_read_roots(codex_home);
|
||||
if permissions.include_platform_defaults() {
|
||||
roots.extend(
|
||||
WINDOWS_PLATFORM_DEFAULT_READ_ROOTS
|
||||
.iter()
|
||||
.map(PathBuf::from),
|
||||
);
|
||||
}
|
||||
roots.extend(permissions.readable_roots_for_cwd(command_cwd));
|
||||
canonical_existing(&roots)
|
||||
}
|
||||
|
||||
pub(crate) fn gather_write_roots_for_permissions(
|
||||
@@ -415,17 +441,14 @@ pub(crate) fn gather_write_roots_for_permissions(
|
||||
}
|
||||
|
||||
pub(crate) fn effective_write_roots_for_setup(
|
||||
policy: &SandboxPolicy,
|
||||
policy_cwd: &Path,
|
||||
permissions: &ResolvedWindowsSandboxPermissions,
|
||||
command_cwd: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
codex_home: &Path,
|
||||
write_roots_override: Option<&[PathBuf]>,
|
||||
) -> Vec<PathBuf> {
|
||||
let permissions =
|
||||
ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(policy, policy_cwd);
|
||||
effective_write_roots_for_permissions(
|
||||
&permissions,
|
||||
permissions,
|
||||
command_cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
@@ -760,6 +783,9 @@ pub fn run_elevated_setup(
|
||||
request: SandboxSetupRequest<'_>,
|
||||
overrides: SetupRootOverrides,
|
||||
) -> Result<()> {
|
||||
if !request.permissions.is_enforceable_by_windows_sandbox() {
|
||||
anyhow::bail!("unsupported filesystem permissions for Windows sandbox setup");
|
||||
}
|
||||
// Ensure the shared sandbox directory exists before we send it to the elevated helper.
|
||||
let sbx_dir = sandbox_dir(request.codex_home);
|
||||
std::fs::create_dir_all(&sbx_dir).map_err(|err| {
|
||||
@@ -771,12 +797,8 @@ pub fn run_elevated_setup(
|
||||
let (read_roots, write_roots) = build_payload_roots(&request, &overrides);
|
||||
let deny_read_paths = build_payload_deny_read_paths(overrides.deny_read_paths);
|
||||
let deny_write_paths = build_payload_deny_write_paths(&request, overrides.deny_write_paths);
|
||||
let permissions = ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(
|
||||
request.policy,
|
||||
request.policy_cwd,
|
||||
);
|
||||
let network_identity =
|
||||
SandboxNetworkIdentity::from_permissions(&permissions, request.proxy_enforced);
|
||||
SandboxNetworkIdentity::from_permissions(request.permissions, request.proxy_enforced);
|
||||
let offline_proxy_settings = offline_proxy_settings_from_env(request.env_map, network_identity);
|
||||
let payload = ElevationPayload {
|
||||
version: SETUP_VERSION,
|
||||
@@ -808,8 +830,7 @@ fn build_payload_roots(
|
||||
overrides: &SetupRootOverrides,
|
||||
) -> (Vec<PathBuf>, Vec<PathBuf>) {
|
||||
let write_roots = effective_write_roots_for_setup(
|
||||
request.policy,
|
||||
request.policy_cwd,
|
||||
request.permissions,
|
||||
request.command_cwd,
|
||||
request.env_map,
|
||||
request.codex_home,
|
||||
@@ -829,7 +850,12 @@ fn build_payload_roots(
|
||||
read_roots.extend(roots.iter().cloned());
|
||||
canonical_existing(&read_roots)
|
||||
} else {
|
||||
gather_read_roots(request.command_cwd, request.policy, request.codex_home)
|
||||
gather_read_roots(
|
||||
request.command_cwd,
|
||||
request.permissions,
|
||||
request.env_map,
|
||||
request.codex_home,
|
||||
)
|
||||
};
|
||||
read_roots = expand_user_profile_root(read_roots);
|
||||
read_roots = filter_user_profile_root(read_roots);
|
||||
@@ -844,9 +870,8 @@ fn build_payload_deny_write_paths(
|
||||
request: &SandboxSetupRequest<'_>,
|
||||
explicit_deny_write_paths: Option<Vec<PathBuf>>,
|
||||
) -> Vec<PathBuf> {
|
||||
let allow_deny_paths: AllowDenyPaths = compute_allow_paths(
|
||||
request.policy,
|
||||
request.policy_cwd,
|
||||
let allow_deny_paths: AllowDenyPaths = compute_allow_paths_for_permissions(
|
||||
request.permissions,
|
||||
request.command_cwd,
|
||||
request.env_map,
|
||||
);
|
||||
@@ -992,7 +1017,7 @@ fn filter_sensitive_write_roots(mut roots: Vec<PathBuf>, codex_home: &Path) -> V
|
||||
mod tests {
|
||||
use super::WINDOWS_PLATFORM_DEFAULT_READ_ROOTS;
|
||||
use super::build_payload_roots;
|
||||
use super::gather_legacy_full_read_roots;
|
||||
use super::gather_full_read_roots_for_permissions;
|
||||
use super::gather_read_roots;
|
||||
use super::loopback_proxy_port_from_url;
|
||||
use super::offline_proxy_settings_from_env;
|
||||
@@ -1000,6 +1025,7 @@ mod tests {
|
||||
use super::proxy_ports_from_env;
|
||||
use crate::helper_materialization::helper_bin_dir;
|
||||
use crate::policy::SandboxPolicy;
|
||||
use crate::resolved_permissions::ResolvedWindowsSandboxPermissions;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::collections::HashMap;
|
||||
@@ -1015,6 +1041,13 @@ mod tests {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn permissions_for(
|
||||
policy: &SandboxPolicy,
|
||||
policy_cwd: &std::path::Path,
|
||||
) -> ResolvedWindowsSandboxPermissions {
|
||||
ResolvedWindowsSandboxPermissions::from_legacy_policy_for_cwd(policy, policy_cwd)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn loopback_proxy_url_parsing_supports_common_forms() {
|
||||
assert_eq!(
|
||||
@@ -1315,8 +1348,9 @@ mod tests {
|
||||
let command_cwd = tmp.path().join("workspace");
|
||||
fs::create_dir_all(&command_cwd).expect("create workspace");
|
||||
let policy = SandboxPolicy::new_read_only_policy();
|
||||
let permissions = permissions_for(&policy, &command_cwd);
|
||||
|
||||
let roots = gather_read_roots(&command_cwd, &policy, &codex_home);
|
||||
let roots = gather_read_roots(&command_cwd, &permissions, &HashMap::new(), &codex_home);
|
||||
let expected =
|
||||
dunce::canonicalize(helper_bin_dir(&codex_home)).expect("canonical helper dir");
|
||||
|
||||
@@ -1340,8 +1374,9 @@ mod tests {
|
||||
exclude_tmpdir_env_var: true,
|
||||
exclude_slash_tmp: true,
|
||||
};
|
||||
let permissions = permissions_for(&policy, &command_cwd);
|
||||
|
||||
let roots = gather_read_roots(&command_cwd, &policy, &codex_home);
|
||||
let roots = gather_read_roots(&command_cwd, &permissions, &HashMap::new(), &codex_home);
|
||||
let expected_writable =
|
||||
dunce::canonicalize(&writable_root).expect("canonical writable root");
|
||||
|
||||
@@ -1361,11 +1396,11 @@ mod tests {
|
||||
let policy = SandboxPolicy::ReadOnly {
|
||||
network_access: false,
|
||||
};
|
||||
let permissions = permissions_for(&policy, &policy_cwd);
|
||||
|
||||
let (read_roots, write_roots) = build_payload_roots(
|
||||
&super::SandboxSetupRequest {
|
||||
policy: &policy,
|
||||
policy_cwd: &policy_cwd,
|
||||
permissions: &permissions,
|
||||
command_cwd: &command_cwd,
|
||||
env_map: &HashMap::new(),
|
||||
codex_home: &codex_home,
|
||||
@@ -1409,11 +1444,11 @@ mod tests {
|
||||
let policy = SandboxPolicy::ReadOnly {
|
||||
network_access: false,
|
||||
};
|
||||
let permissions = permissions_for(&policy, &policy_cwd);
|
||||
|
||||
let (read_roots, write_roots) = build_payload_roots(
|
||||
&super::SandboxSetupRequest {
|
||||
policy: &policy,
|
||||
policy_cwd: &policy_cwd,
|
||||
permissions: &permissions,
|
||||
command_cwd: &command_cwd,
|
||||
env_map: &HashMap::new(),
|
||||
codex_home: &codex_home,
|
||||
@@ -1461,6 +1496,7 @@ mod tests {
|
||||
exclude_tmpdir_env_var: true,
|
||||
exclude_slash_tmp: true,
|
||||
};
|
||||
let permissions = permissions_for(&policy, &command_cwd);
|
||||
let override_roots = vec![
|
||||
command_cwd.clone(),
|
||||
extra_root.clone(),
|
||||
@@ -1468,8 +1504,7 @@ mod tests {
|
||||
sandbox_root.clone(),
|
||||
];
|
||||
let request = super::SandboxSetupRequest {
|
||||
policy: &policy,
|
||||
policy_cwd: &command_cwd,
|
||||
permissions: &permissions,
|
||||
command_cwd: &command_cwd,
|
||||
env_map: &HashMap::new(),
|
||||
codex_home: &codex_home,
|
||||
@@ -1484,8 +1519,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let effective_write_roots = super::effective_write_roots_for_setup(
|
||||
&policy,
|
||||
&command_cwd,
|
||||
&permissions,
|
||||
&command_cwd,
|
||||
&HashMap::new(),
|
||||
&codex_home,
|
||||
@@ -1519,10 +1553,10 @@ mod tests {
|
||||
exclude_tmpdir_env_var: true,
|
||||
exclude_slash_tmp: true,
|
||||
};
|
||||
let permissions = permissions_for(&policy, &policy_cwd);
|
||||
|
||||
let effective_write_roots = super::effective_write_roots_for_setup(
|
||||
&policy,
|
||||
&policy_cwd,
|
||||
&permissions,
|
||||
&command_cwd,
|
||||
&HashMap::new(),
|
||||
&codex_home,
|
||||
@@ -1555,9 +1589,9 @@ mod tests {
|
||||
exclude_tmpdir_env_var: true,
|
||||
exclude_slash_tmp: true,
|
||||
};
|
||||
let permissions = permissions_for(&policy, &command_cwd);
|
||||
let request = super::SandboxSetupRequest {
|
||||
policy: &policy,
|
||||
policy_cwd: &command_cwd,
|
||||
permissions: &permissions,
|
||||
command_cwd: &command_cwd,
|
||||
env_map: &HashMap::new(),
|
||||
codex_home: &codex_home,
|
||||
@@ -1586,8 +1620,14 @@ mod tests {
|
||||
let command_cwd = tmp.path().join("workspace");
|
||||
fs::create_dir_all(&command_cwd).expect("create workspace");
|
||||
let policy = SandboxPolicy::new_read_only_policy();
|
||||
let permissions = permissions_for(&policy, &command_cwd);
|
||||
|
||||
let roots = gather_legacy_full_read_roots(&command_cwd, &policy, &codex_home);
|
||||
let roots = gather_full_read_roots_for_permissions(
|
||||
&command_cwd,
|
||||
&permissions,
|
||||
&HashMap::new(),
|
||||
&codex_home,
|
||||
);
|
||||
|
||||
assert!(
|
||||
canonical_windows_platform_default_roots()
|
||||
|
||||
@@ -2,7 +2,6 @@ use crate::acl::add_allow_ace;
|
||||
use crate::acl::add_deny_write_ace;
|
||||
use crate::acl::allow_null_device;
|
||||
use crate::allow::AllowDenyPaths;
|
||||
use crate::allow::compute_allow_paths;
|
||||
use crate::allow::compute_allow_paths_for_permissions;
|
||||
use crate::cap::load_or_create_cap_sids;
|
||||
use crate::cap::workspace_write_cap_sid_for_root;
|
||||
@@ -284,8 +283,7 @@ pub(crate) fn allow_null_device_for_workspace_write(is_workspace_write: bool) {
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn apply_legacy_session_acl_rules(
|
||||
policy: &SandboxPolicy,
|
||||
sandbox_policy_cwd: &Path,
|
||||
permissions: &ResolvedWindowsSandboxPermissions,
|
||||
codex_home: &Path,
|
||||
current_dir: &Path,
|
||||
env_map: &HashMap<String, String>,
|
||||
@@ -295,7 +293,7 @@ pub(crate) fn apply_legacy_session_acl_rules(
|
||||
persist_aces: bool,
|
||||
) -> Result<Vec<(PathBuf, String)>> {
|
||||
let AllowDenyPaths { allow, mut deny } =
|
||||
compute_allow_paths(policy, sandbox_policy_cwd, current_dir, env_map);
|
||||
compute_allow_paths_for_permissions(permissions, current_dir, env_map);
|
||||
let mut guards: Vec<(PathBuf, String)> = Vec::new();
|
||||
unsafe {
|
||||
for path in additional_deny_write_paths {
|
||||
@@ -455,8 +453,7 @@ pub(crate) fn prepare_elevated_spawn_context(
|
||||
write_roots_override
|
||||
};
|
||||
let sandbox_creds = require_logon_sandbox_creds(
|
||||
&common.policy,
|
||||
sandbox_policy_cwd,
|
||||
&common.permissions,
|
||||
cwd,
|
||||
env_map,
|
||||
codex_home,
|
||||
|
||||
@@ -331,8 +331,7 @@ pub(crate) async fn spawn_windows_sandbox_session_legacy(
|
||||
|
||||
let persist_aces = common.uses_write_capabilities;
|
||||
let guards = apply_legacy_session_acl_rules(
|
||||
&common.policy,
|
||||
sandbox_policy_cwd,
|
||||
&common.permissions,
|
||||
codex_home,
|
||||
&common.current_dir,
|
||||
&env_map,
|
||||
|
||||
Reference in New Issue
Block a user