From b2344d8fbc2b5b07b9eb06757fe5bbdecbb3107d Mon Sep 17 00:00:00 2001 From: iceweasel-oai Date: Wed, 3 Jun 2026 09:21:24 -0700 Subject: [PATCH] [codex] Restore setup helper UAC manifest (#25949) ## Why #23764 removed Windows resource stamping from `codex-windows-sandbox`, but it also removed the setup helper's UAC manifest. That manifest was doing more than cosmetic version metadata: Microsoft documents `requestedExecutionLevel level="asInvoker"` as the setting that makes an executable run at the same permission level as the process that started it: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests#trustinfo In the reported session, `codex-windows-sandbox-setup.exe` was launched for a non-elevated setup refresh and `CreateProcess` failed with `os error 740` (`The requested operation requires elevation`). Restoring an explicit `asInvoker` manifest records the helper's intended default launch contract: normal launches inherit the caller's token, and elevation only happens through the code paths that request it explicitly. The setup helper has two launch modes: - setup refresh uses a normal `Command::new(...)` spawn and should never trigger UAC - full setup explicitly uses `ShellExecuteExW` with the `runas` verb when elevation is required Restoring `asInvoker` keeps refresh non-elevated by default while preserving the explicit elevated path for full setup. ## What changed - Restored a minimal `codex-windows-sandbox-setup.manifest` containing only `requestedExecutionLevel level="asInvoker"`. - Added a small build script that passes setup-helper-scoped manifest linker args for MSVC and the Windows GNU/LLVM target used by Bazel. - Wired the manifest into Bazel build-script data. This does not restore `winres`, `FileDescription`, `ProductName`, or package-wide resource stamping, so other Codex binaries that link `codex-windows-sandbox` do not inherit metadata from this package. ## Verification - `cargo fmt -p codex-windows-sandbox` - `cargo build -p codex-windows-sandbox --bin codex-windows-sandbox-setup` - `cargo build -p codex-windows-sandbox --bin codex-command-runner` - `cargo build -p codex-windows-sandbox --lib` - Build-script output simulation for `CARGO_CFG_TARGET_ENV=msvc` emits `/MANIFEST:EMBED` and `/MANIFESTINPUT:`. - Build-script output simulation for `CARGO_CFG_TARGET_ENV=gnu` + `CARGO_CFG_TARGET_ABI=llvm` emits `-Wl,-Xlink=/manifest:embed` and `-Wl,-Xlink=/manifestinput:`. - Inspected the built binaries and confirmed: - `codex-windows-sandbox-setup.exe` contains `requestedExecutionLevel` / `asInvoker` - `codex-command-runner.exe` does not contain those manifest strings - Windows `VersionInfo` remains blank for `FileDescription` / `ProductName` - `just test -p codex-windows-sandbox` ran through Nextest, with 114 passing, 2 skipped, and 1 existing Windows sandbox failure: `unified_exec::tests::legacy_non_tty_cmd_emits_output` fails with `CreateRestrictedToken failed: 87`. --- codex-rs/windows-sandbox-rs/BUILD.bazel | 3 ++ codex-rs/windows-sandbox-rs/Cargo.toml | 1 + codex-rs/windows-sandbox-rs/build.rs | 39 +++++++++++++++++++ .../codex-windows-sandbox-setup.manifest | 10 +++++ 4 files changed, 53 insertions(+) create mode 100644 codex-rs/windows-sandbox-rs/build.rs create mode 100644 codex-rs/windows-sandbox-rs/codex-windows-sandbox-setup.manifest diff --git a/codex-rs/windows-sandbox-rs/BUILD.bazel b/codex-rs/windows-sandbox-rs/BUILD.bazel index 31dbd3d24..7e0de41ec 100644 --- a/codex-rs/windows-sandbox-rs/BUILD.bazel +++ b/codex-rs/windows-sandbox-rs/BUILD.bazel @@ -3,4 +3,7 @@ load("//:defs.bzl", "codex_rust_crate") codex_rust_crate( name = "windows-sandbox-rs", crate_name = "codex_windows_sandbox", + build_script_data = [ + "codex-windows-sandbox-setup.manifest", + ], ) diff --git a/codex-rs/windows-sandbox-rs/Cargo.toml b/codex-rs/windows-sandbox-rs/Cargo.toml index 53c81f0b0..31df9ad39 100644 --- a/codex-rs/windows-sandbox-rs/Cargo.toml +++ b/codex-rs/windows-sandbox-rs/Cargo.toml @@ -1,4 +1,5 @@ [package] +build = "build.rs" edition.workspace = true license.workspace = true name = "codex-windows-sandbox" diff --git a/codex-rs/windows-sandbox-rs/build.rs b/codex-rs/windows-sandbox-rs/build.rs new file mode 100644 index 000000000..af5aec78c --- /dev/null +++ b/codex-rs/windows-sandbox-rs/build.rs @@ -0,0 +1,39 @@ +use std::env; +use std::path::PathBuf; + +const SETUP_BIN: &str = "codex-windows-sandbox-setup"; +const SETUP_MANIFEST: &str = "codex-windows-sandbox-setup.manifest"; + +fn main() { + println!("cargo:rerun-if-changed={SETUP_MANIFEST}"); + + if env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("windows") { + return; + } + + let manifest_path = PathBuf::from( + env::var_os("CARGO_MANIFEST_DIR") + .expect("CARGO_MANIFEST_DIR should be set for build scripts"), + ) + .join(SETUP_MANIFEST); + let manifest_path = manifest_path.display(); + + // Keep this scoped to the setup helper so Codex binaries that link the + // library do not inherit any resource metadata from this package. + match ( + env::var("CARGO_CFG_TARGET_ENV").as_deref(), + env::var("CARGO_CFG_TARGET_ABI").as_deref(), + ) { + (Ok("msvc"), _) => { + println!("cargo:rustc-link-arg-bin={SETUP_BIN}=/MANIFEST:EMBED"); + println!("cargo:rustc-link-arg-bin={SETUP_BIN}=/MANIFESTINPUT:{manifest_path}"); + } + (Ok("gnu"), Ok("llvm")) => { + println!("cargo:rustc-link-arg-bin={SETUP_BIN}=-Wl,-Xlink=/manifest:embed"); + println!( + "cargo:rustc-link-arg-bin={SETUP_BIN}=-Wl,-Xlink=/manifestinput:{manifest_path}" + ); + } + _ => {} + } +} diff --git a/codex-rs/windows-sandbox-rs/codex-windows-sandbox-setup.manifest b/codex-rs/windows-sandbox-rs/codex-windows-sandbox-setup.manifest new file mode 100644 index 000000000..14807962f --- /dev/null +++ b/codex-rs/windows-sandbox-rs/codex-windows-sandbox-setup.manifest @@ -0,0 +1,10 @@ + + + + + + + + + +