Skip WSL UNC ACL refresh roots

This commit is contained in:
David Wiesen
2026-05-22 09:56:39 -07:00
parent 0035d7bd18
commit a6cfdbf748

View File

@@ -192,8 +192,11 @@ fn run_setup_refresh_inner(
let exe = find_setup_exe();
// Refresh should never request elevation; ensure verb isn't set and we don't trigger UAC.
let mut cmd = Command::new(&exe);
cmd.arg(&b64).stdout(Stdio::null()).stderr(Stdio::null());
let cwd = std::env::current_dir().unwrap_or_else(|_| request.codex_home.to_path_buf());
let cwd = request.codex_home.to_path_buf();
cmd.arg(&b64)
.current_dir(&cwd)
.stdout(Stdio::null())
.stderr(Stdio::null());
log_note(
&format!(
"setup refresh: spawning {} (cwd={}, payload_len={})",
@@ -767,6 +770,7 @@ fn build_payload_roots(
let write_roots = filter_user_profile_root_exclusions(write_roots);
let write_roots = filter_ssh_config_dependency_roots(write_roots);
let write_roots = filter_sensitive_write_roots(write_roots, request.codex_home);
let write_roots = filter_acl_unsupported_roots(write_roots);
let mut read_roots = if let Some(roots) = overrides.read_roots.as_deref() {
// An explicit override is the split policy's complete readable set. Keep only the
// helper/platform roots the elevated setup needs; do not re-add legacy cwd/full-read roots.
@@ -814,6 +818,7 @@ fn build_payload_deny_write_paths(
})
.collect();
deny_write_paths.extend(allow_deny_paths.deny);
deny_write_paths.retain(|path| !is_acl_unsupported_root(path));
deny_write_paths
}
@@ -940,6 +945,21 @@ fn filter_sensitive_write_roots(mut roots: Vec<PathBuf>, codex_home: &Path) -> V
roots
}
fn filter_acl_unsupported_roots(roots: Vec<PathBuf>) -> Vec<PathBuf> {
roots
.into_iter()
.filter(|root| !is_acl_unsupported_root(root))
.collect()
}
fn is_acl_unsupported_root(path: &Path) -> bool {
let key = canonical_path_key(path);
key.starts_with("//wsl.localhost/")
|| key.starts_with("//wsl$/")
|| key.starts_with("//?/unc/wsl.localhost/")
|| key.starts_with("//?/unc/wsl$/")
}
#[cfg(test)]
mod tests {
use super::WINDOWS_PLATFORM_DEFAULT_READ_ROOTS;
@@ -957,6 +977,7 @@ mod tests {
use std::collections::HashMap;
use std::collections::HashSet;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
use tempfile::TempDir;
@@ -1438,6 +1459,71 @@ mod tests {
);
}
#[test]
fn acl_unsupported_root_detection_matches_wsl_unc_variants() {
assert!(super::is_acl_unsupported_root(Path::new(
r"\\wsl.localhost\Ubuntu\home\dev\repo"
)));
assert!(super::is_acl_unsupported_root(Path::new(
r"\\wsl$\Ubuntu\home\dev\repo"
)));
assert!(super::is_acl_unsupported_root(Path::new(
r"\\?\UNC\wsl.localhost\Ubuntu\home\dev\repo"
)));
assert!(!super::is_acl_unsupported_root(Path::new(
r"C:\Users\dev\repo"
)));
}
#[test]
fn filter_acl_unsupported_roots_drops_wsl_unc_entries() {
let local_root = PathBuf::from(r"C:\Users\dev\repo");
let roots = super::filter_acl_unsupported_roots(vec![
PathBuf::from(r"\\wsl.localhost\Ubuntu\home\dev\repo"),
PathBuf::from(r"\\?\UNC\wsl.localhost\Ubuntu\home\dev\repo"),
local_root.clone(),
]);
assert_eq!(vec![local_root], roots);
}
#[test]
fn payload_deny_write_paths_skip_acl_unsupported_entries() {
let tmp = TempDir::new().expect("tempdir");
let codex_home = tmp.path().join("codex-home");
let command_cwd = tmp.path().join("workspace");
fs::create_dir_all(&command_cwd).expect("create workspace");
let policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![],
network_access: false,
exclude_tmpdir_env_var: true,
exclude_slash_tmp: true,
};
let request = super::SandboxSetupRequest {
policy: &policy,
policy_cwd: &command_cwd,
command_cwd: &command_cwd,
env_map: &HashMap::new(),
codex_home: &codex_home,
proxy_enforced: false,
};
let deny_write_paths = super::build_payload_deny_write_paths(
&request,
Some(vec![
PathBuf::from(r"\\wsl.localhost\Ubuntu\home\dev\repo\.git"),
command_cwd.join(".git"),
]),
);
assert_eq!(
[dunce::canonicalize(command_cwd.join(".git")).expect("canonical .git")]
.into_iter()
.collect::<HashSet<PathBuf>>(),
deny_write_paths.into_iter().collect()
);
}
#[test]
fn full_read_roots_preserve_legacy_platform_defaults() {
let tmp = TempDir::new().expect("tempdir");