diff --git a/codex-rs/cli/src/debug_sandbox.rs b/codex-rs/cli/src/debug_sandbox.rs index aeed093cb9..35c1a4fafe 100644 --- a/codex-rs/cli/src/debug_sandbox.rs +++ b/codex-rs/cli/src/debug_sandbox.rs @@ -478,7 +478,7 @@ fn windows_debug_protected_metadata_targets( let mode = if std::fs::symlink_metadata(path.as_path()).is_ok() { codex_windows_sandbox::ProtectedMetadataMode::ExistingDeny } else { - codex_windows_sandbox::ProtectedMetadataMode::MissingCreationMonitor + codex_windows_sandbox::ProtectedMetadataMode::MissingDenySentinel }; targets.push(codex_windows_sandbox::ProtectedMetadataTarget { path: path.as_path().to_path_buf(), diff --git a/codex-rs/core/src/exec.rs b/codex-rs/core/src/exec.rs index a9f41295d1..cd67e1582b 100644 --- a/codex-rs/core/src/exec.rs +++ b/codex-rs/core/src/exec.rs @@ -121,13 +121,18 @@ pub(crate) struct WindowsProtectedMetadataTarget { pub(crate) mode: WindowsProtectedMetadataMode, } -/// Layer: Windows adapter layer. The enforcement layer needs to know why a -/// protected metadata path is absent instead of treating every missing path as -/// an existing filesystem object. +/// Layer: Windows adapter layer. The enforcement layer needs to know whether a +/// protected metadata path already exists or must be denied before the command +/// can create it. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub(crate) enum WindowsProtectedMetadataMode { + /// The protected metadata object exists before launch, so the Windows + /// sandbox should deny writes to the object and any canonical target. ExistingDeny, - MissingCreationMonitor, + /// The protected metadata object is absent before launch, so the Windows + /// sandbox should create and deny-list a temporary sentinel before command + /// execution can begin. + MissingDenySentinel, } fn windows_sandbox_uses_elevated_backend( @@ -666,8 +671,8 @@ async fn exec_windows_sandbox( WindowsProtectedMetadataMode::ExistingDeny => { codex_windows_sandbox::ProtectedMetadataMode::ExistingDeny } - WindowsProtectedMetadataMode::MissingCreationMonitor => { - codex_windows_sandbox::ProtectedMetadataMode::MissingCreationMonitor + WindowsProtectedMetadataMode::MissingDenySentinel => { + codex_windows_sandbox::ProtectedMetadataMode::MissingDenySentinel } }; codex_windows_sandbox::ProtectedMetadataTarget { @@ -1361,7 +1366,7 @@ fn windows_protected_metadata_mode(path: &AbsolutePathBuf) -> WindowsProtectedMe return WindowsProtectedMetadataMode::ExistingDeny; } - WindowsProtectedMetadataMode::MissingCreationMonitor + WindowsProtectedMetadataMode::MissingDenySentinel } fn has_reopened_writable_descendant( diff --git a/codex-rs/core/src/exec_tests.rs b/codex-rs/core/src/exec_tests.rs index 6bf9cbcfbb..3561d65de1 100644 --- a/codex-rs/core/src/exec_tests.rs +++ b/codex-rs/core/src/exec_tests.rs @@ -666,15 +666,15 @@ fn windows_restricted_token_supports_full_read_split_write_read_carveouts() { protected_metadata_targets: vec![ WindowsProtectedMetadataTarget { path: cwd.join(".agents"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: cwd.join(".codex"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: cwd.join(".git"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, ], })) @@ -778,15 +778,15 @@ fn windows_elevated_supports_split_write_read_carveouts() { protected_metadata_targets: vec![ WindowsProtectedMetadataTarget { path: expected_root.join(".agents"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: expected_root.join(".codex"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: expected_root.join(".git"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, ], })) @@ -840,11 +840,11 @@ fn windows_metadata_plan_marks_existing_metadata_for_deny() { protected_metadata_targets: vec![ WindowsProtectedMetadataTarget { path: cwd.join(".agents"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: cwd.join(".codex"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: cwd.join(".git"), @@ -856,7 +856,7 @@ fn windows_metadata_plan_marks_existing_metadata_for_deny() { } #[test] -fn windows_metadata_plan_does_not_materialize_nested_missing_git() { +fn windows_metadata_plan_uses_sentinel_for_nested_missing_git() { let temp_dir = tempfile::TempDir::new().expect("tempdir"); let repo = dunce::canonicalize(temp_dir.path()) .expect("canonical temp dir") @@ -904,15 +904,15 @@ fn windows_metadata_plan_does_not_materialize_nested_missing_git() { protected_metadata_targets: vec![ WindowsProtectedMetadataTarget { path: cwd.join(".agents"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: cwd.join(".codex"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: cwd.join(".git"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, ], })) @@ -973,15 +973,15 @@ fn windows_shell_runtime_path_resolves_metadata_overrides() { vec![ WindowsProtectedMetadataTarget { path: cwd.join(".agents"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: cwd.join(".codex"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, WindowsProtectedMetadataTarget { path: cwd.join(".git"), - mode: WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: WindowsProtectedMetadataMode::MissingDenySentinel, }, ] ); diff --git a/codex-rs/core/src/unified_exec/process_manager.rs b/codex-rs/core/src/unified_exec/process_manager.rs index f95fb9fc99..964328c356 100644 --- a/codex-rs/core/src/unified_exec/process_manager.rs +++ b/codex-rs/core/src/unified_exec/process_manager.rs @@ -190,8 +190,8 @@ fn protected_metadata_targets_for_windows_session( WindowsProtectedMetadataMode::ExistingDeny => { codex_windows_sandbox::ProtectedMetadataMode::ExistingDeny } - WindowsProtectedMetadataMode::MissingCreationMonitor => { - codex_windows_sandbox::ProtectedMetadataMode::MissingCreationMonitor + WindowsProtectedMetadataMode::MissingDenySentinel => { + codex_windows_sandbox::ProtectedMetadataMode::MissingDenySentinel } }; codex_windows_sandbox::ProtectedMetadataTarget { diff --git a/codex-rs/core/src/unified_exec/process_manager_tests.rs b/codex-rs/core/src/unified_exec/process_manager_tests.rs index a41f08b1d8..0125f1788e 100644 --- a/codex-rs/core/src/unified_exec/process_manager_tests.rs +++ b/codex-rs/core/src/unified_exec/process_manager_tests.rs @@ -183,15 +183,15 @@ fn open_session_prepares_windows_metadata_overrides_for_unified_exec() { vec![ crate::exec::WindowsProtectedMetadataTarget { path: cwd.join(".agents"), - mode: crate::exec::WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: crate::exec::WindowsProtectedMetadataMode::MissingDenySentinel, }, crate::exec::WindowsProtectedMetadataTarget { path: cwd.join(".codex"), - mode: crate::exec::WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: crate::exec::WindowsProtectedMetadataMode::MissingDenySentinel, }, crate::exec::WindowsProtectedMetadataTarget { path: cwd.join(".git"), - mode: crate::exec::WindowsProtectedMetadataMode::MissingCreationMonitor, + mode: crate::exec::WindowsProtectedMetadataMode::MissingDenySentinel, }, ] );