Fix Windows sandbox setup helper launch path

This commit is contained in:
David Wiesen
2026-06-09 17:20:09 -07:00
parent 51fc4b0559
commit a63f446ce9
2 changed files with 30 additions and 40 deletions

View File

@@ -22,18 +22,29 @@ pub(crate) const RESOURCES_DIRNAME: &str = "codex-resources";
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub(crate) enum HelperExecutable {
CommandRunner,
WindowsSandboxSetup,
}
impl HelperExecutable {
fn file_name(self) -> &'static str {
match self {
Self::CommandRunner => "codex-command-runner.exe",
Self::WindowsSandboxSetup => "codex-windows-sandbox-setup.exe",
}
}
fn label(self) -> &'static str {
match self {
Self::CommandRunner => "command-runner",
Self::WindowsSandboxSetup => "windows-sandbox-setup",
}
}
fn materialized_stem(self) -> &'static str {
match self {
Self::CommandRunner => "codex-command-runner",
// Avoid copied helper names that trigger Windows installer/UAC heuristics.
Self::WindowsSandboxSetup => "codex-windows-sandbox-helper",
}
}
}
@@ -220,10 +231,7 @@ fn helper_destination_for_source(
fn materialized_file_name(kind: HelperExecutable, suffix: &str) -> String {
let source_name = kind.file_name();
let path = Path::new(source_name);
let stem = path
.file_stem()
.and_then(|stem| stem.to_str())
.unwrap_or(source_name);
let stem = kind.materialized_stem();
let extension = path
.extension()
.and_then(|ext| ext.to_str())
@@ -559,4 +567,12 @@ mod tests {
assert_eq!(file_name, "codex-command-runner-test-suffix.exe");
}
#[test]
fn setup_helper_materialized_name_avoids_setup_suffix() {
let file_name =
materialized_file_name(HelperExecutable::WindowsSandboxSetup, "test-suffix");
assert_eq!(file_name, "codex-windows-sandbox-helper-test-suffix.exe");
}
}

View File

@@ -12,8 +12,9 @@ use std::process::Stdio;
use crate::allow::AllowDenyPaths;
use crate::allow::compute_allow_paths_for_permissions;
use crate::helper_materialization::bundled_executable_path_for_exe;
use crate::helper_materialization::HelperExecutable;
use crate::helper_materialization::helper_bin_dir;
use crate::helper_materialization::resolve_helper_for_launch;
use crate::identity::sandbox_setup_is_complete;
use crate::logging::current_log_file_path;
use crate::logging::log_note;
@@ -46,7 +47,6 @@ pub const ONLINE_USERNAME: &str = "CodexSandboxOnline";
const ERROR_CANCELLED: u32 = 1223;
const SECURITY_BUILTIN_DOMAIN_RID: u32 = 0x0000_0020;
const DOMAIN_ALIAS_RID_ADMINS: u32 = 0x0000_0220;
const SETUP_EXE_FILENAME: &str = "codex-windows-sandbox-setup.exe";
const USERPROFILE_ROOT_EXCLUSIONS: &[&str] = &[
".ssh",
".tsh",
@@ -209,7 +209,7 @@ fn run_setup_refresh_inner(
};
let json = serde_json::to_vec(&payload)?;
let b64 = BASE64_STANDARD.encode(json);
let exe = find_setup_exe();
let exe = find_setup_exe(request.codex_home);
let sbx_dir = sandbox_dir(request.codex_home);
let log_path = current_log_file_path(&sbx_dir);
let cleared_report = match clear_setup_error_report(request.codex_home) {
@@ -662,17 +662,12 @@ fn quote_arg(arg: &str) -> String {
out
}
fn find_setup_exe() -> PathBuf {
if let Ok(exe) = std::env::current_exe()
&& let Some(setup_exe) = find_setup_exe_for_current_exe(&exe)
{
return setup_exe;
}
PathBuf::from(SETUP_EXE_FILENAME)
}
fn find_setup_exe_for_current_exe(exe: &Path) -> Option<PathBuf> {
bundled_executable_path_for_exe(exe, SETUP_EXE_FILENAME)
fn find_setup_exe(codex_home: &Path) -> PathBuf {
resolve_helper_for_launch(
HelperExecutable::WindowsSandboxSetup,
codex_home,
Some(&sandbox_dir(codex_home)),
)
}
fn report_helper_failure(
@@ -716,7 +711,7 @@ fn run_setup_exe(
use windows_sys::Win32::UI::Shell::SEE_MASK_NOCLOSEPROCESS;
use windows_sys::Win32::UI::Shell::SHELLEXECUTEINFOW;
use windows_sys::Win32::UI::Shell::ShellExecuteExW;
let exe = find_setup_exe();
let exe = find_setup_exe(codex_home);
let payload_json = serde_json::to_string(payload).map_err(|err| {
failure(
SetupErrorCode::OrchestratorPayloadSerializeFailed,
@@ -1096,7 +1091,6 @@ 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::find_setup_exe_for_current_exe;
use super::gather_full_read_roots_for_permissions;
use super::gather_read_roots;
use super::loopback_proxy_port_from_url;
@@ -1104,8 +1098,6 @@ mod tests {
use super::profile_read_roots;
use super::proxy_ports_from_env;
use super::verify_setup_completed;
use crate::helper_materialization::BIN_DIRNAME;
use crate::helper_materialization::RESOURCES_DIRNAME;
use crate::helper_materialization::helper_bin_dir;
use crate::resolved_permissions::ResolvedWindowsSandboxPermissions;
use crate::setup_error::SetupErrorCode;
@@ -1281,24 +1273,6 @@ mod tests {
);
}
#[test]
fn setup_exe_lookup_checks_package_resource_dir_for_bin_exe() {
let tmp = TempDir::new().expect("tempdir");
let package_dir = tmp.path().join("package");
let bin_dir = package_dir.join(BIN_DIRNAME);
let resources_dir = package_dir.join(RESOURCES_DIRNAME);
fs::create_dir_all(&bin_dir).expect("create bin dir");
fs::create_dir_all(&resources_dir).expect("create resources dir");
let exe = bin_dir.join("codex.exe");
let setup_exe = resources_dir.join("codex-windows-sandbox-setup.exe");
fs::write(&exe, b"codex").expect("write exe");
fs::write(&setup_exe, b"setup").expect("write setup");
let resolved = find_setup_exe_for_current_exe(&exe).expect("setup exe");
assert_eq!(resolved, setup_exe);
}
#[test]
fn loopback_proxy_url_parsing_rejects_non_loopback_and_zero_port() {
assert_eq!(