Grant Windows legacy Git read roots

This commit is contained in:
Eva Wong
2026-05-05 03:35:15 -07:00
parent 29723ac37c
commit 86c1ad7b84
3 changed files with 66 additions and 0 deletions
+33
View File
@@ -267,6 +267,8 @@ mod windows_impl {
use super::acl::add_deny_write_ace;
use super::acl::allow_named_pipe_device;
use super::acl::allow_null_device;
use super::acl::ensure_allow_mask_aces;
use super::acl::ensure_allow_mask_aces_with_inheritance;
use super::acl::revoke_ace;
use super::allow::AllowDenyPaths;
use super::allow::compute_allow_paths;
@@ -279,6 +281,8 @@ mod windows_impl {
use super::process::create_process_as_user;
use super::protected_metadata::prepare_protected_metadata_targets;
use super::sandbox_utils::ensure_codex_home_exists;
use super::spawn_prep::legacy_session_direct_read_paths;
use super::spawn_prep::legacy_session_executable_read_roots;
use super::spawn_prep::prepare_legacy_spawn_context;
use super::token::convert_string_sid_to_sid;
use super::token::create_workspace_write_token_with_caps_from;
@@ -295,6 +299,8 @@ mod windows_impl {
use windows_sys::Win32::Foundation::HANDLE;
use windows_sys::Win32::Foundation::HANDLE_FLAG_INHERIT;
use windows_sys::Win32::Foundation::SetHandleInformation;
use windows_sys::Win32::Storage::FileSystem::FILE_GENERIC_EXECUTE;
use windows_sys::Win32::Storage::FileSystem::FILE_GENERIC_READ;
use windows_sys::Win32::System::Pipes::CreatePipe;
use windows_sys::Win32::System::Threading::GetExitCodeProcess;
use windows_sys::Win32::System::Threading::INFINITE;
@@ -443,6 +449,8 @@ mod windows_impl {
let persist_aces = is_workspace_write;
let AllowDenyPaths { allow, mut deny } =
compute_allow_paths(&policy, sandbox_policy_cwd, &current_dir, &env_map);
let read_roots = legacy_session_executable_read_roots(&env_map, &command);
let direct_read_paths = legacy_session_direct_read_paths(&env_map);
let protected_metadata_guard =
prepare_protected_metadata_targets(protected_metadata_targets);
for path in protected_metadata_guard.deny_paths() {
@@ -455,7 +463,32 @@ mod windows_impl {
}
let canonical_cwd = canonicalize_path(&current_dir);
let mut guards: Vec<(PathBuf, *mut c_void)> = Vec::new();
let read_execute_mask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
unsafe {
let read_execute_sids: Vec<*mut c_void> = match psid_workspace {
Some(psid) => vec![psid_generic, psid],
None => vec![psid_generic],
};
for p in &read_roots {
if let Ok(added) = ensure_allow_mask_aces(p, &read_execute_sids, read_execute_mask)
&& added
&& !persist_aces
{
guards.push((p.clone(), psid_generic));
}
}
for p in &direct_read_paths {
if let Ok(added) = ensure_allow_mask_aces_with_inheritance(
p,
&read_execute_sids,
read_execute_mask,
/*inheritance*/ 0,
) && added
&& !persist_aces
{
guards.push((p.clone(), psid_generic));
}
}
for p in &allow {
let psid = if is_workspace_write && is_command_cwd_root(p, &canonical_cwd) {
psid_workspace.unwrap_or(psid_generic)
@@ -2,6 +2,8 @@ use crate::acl::add_allow_ace;
use crate::acl::add_deny_write_ace;
use crate::acl::allow_named_pipe_device;
use crate::acl::allow_null_device;
use crate::acl::ensure_allow_mask_aces;
use crate::acl::ensure_allow_mask_aces_with_inheritance;
use crate::allow::AllowDenyPaths;
use crate::allow::compute_allow_paths;
use crate::cap::load_or_create_cap_sids;
@@ -36,6 +38,8 @@ use windows_sys::Win32::Foundation::CloseHandle;
use windows_sys::Win32::Foundation::HANDLE;
use windows_sys::Win32::Foundation::HLOCAL;
use windows_sys::Win32::Foundation::LocalFree;
use windows_sys::Win32::Storage::FileSystem::FILE_GENERIC_EXECUTE;
use windows_sys::Win32::Storage::FileSystem::FILE_GENERIC_READ;
pub(crate) struct SpawnContext {
pub(crate) policy: SandboxPolicy,
@@ -219,6 +223,7 @@ pub(crate) fn apply_legacy_session_acl_rules(
sandbox_policy_cwd: &Path,
current_dir: &Path,
env_map: &HashMap<String, String>,
command: &[String],
psid_generic: &LocalSid,
psid_workspace: Option<&LocalSid>,
persist_aces: bool,
@@ -228,8 +233,35 @@ pub(crate) fn apply_legacy_session_acl_rules(
compute_allow_paths(policy, sandbox_policy_cwd, current_dir, env_map);
deny.extend(additional_deny_paths.iter().cloned());
let mut guards: Vec<PathBuf> = Vec::new();
let read_roots = legacy_session_executable_read_roots(env_map, command);
let direct_read_paths = legacy_session_direct_read_paths(env_map);
let read_execute_mask = FILE_GENERIC_READ | FILE_GENERIC_EXECUTE;
let canonical_cwd = canonicalize_path(current_dir);
unsafe {
let read_execute_sids: Vec<*mut std::ffi::c_void> = match psid_workspace {
Some(psid_workspace) => vec![psid_generic.as_ptr(), psid_workspace.as_ptr()],
None => vec![psid_generic.as_ptr()],
};
for p in &read_roots {
if let Ok(added) = ensure_allow_mask_aces(p, &read_execute_sids, read_execute_mask)
&& added
&& !persist_aces
{
guards.push(p.clone());
}
}
for p in &direct_read_paths {
if let Ok(added) = ensure_allow_mask_aces_with_inheritance(
p,
&read_execute_sids,
read_execute_mask,
/*inheritance*/ 0,
) && added
&& !persist_aces
{
guards.push(p.clone());
}
}
for p in &allow {
let psid = if matches!(policy, SandboxPolicy::WorkspaceWrite { .. })
&& is_command_cwd_root(p, &canonical_cwd)
@@ -337,6 +337,7 @@ pub(crate) async fn spawn_windows_sandbox_session_legacy(
sandbox_policy_cwd,
&common.current_dir,
&env_map,
&command,
&security.psid_generic,
security.psid_workspace.as_ref(),
persist_aces,