Preserve SystemRoot for Windows sandbox wrapper setup (#42833)

## Why

`ShellExecuteExW` needs `SystemRoot` to elevate the Windows sandbox setup helper.

## What changed

Add `SYSTEMROOT` to the environment variables copied from the host for wrapper
setup. Keep the serialized inner command environment unchanged so the host value
is available only to the wrapper.

## Testing

Extend Windows sandbox manager tests to cover case-insensitive replacement of
`SystemRoot` and verify that it is excluded from the inner command environment.

GitOrigin-RevId: c69f9f92665e97a178e2de488fbb9fd6b7ff7ac6
This commit is contained in:
zm-oai
2026-09-04 19:22:34 +00:00
committed by copyberry
parent 87628df77a
commit f1aac1e885
2 changed files with 22 additions and 2 deletions
+6 -1
View File
@@ -31,7 +31,12 @@ use std::io;
use std::path::Path;
#[cfg(target_os = "windows")]
const WINDOWS_SANDBOX_WRAPPER_SETUP_ENV_ALLOWLIST: &[&str] = &["USERNAME", "USERPROFILE"];
const WINDOWS_SANDBOX_WRAPPER_SETUP_ENV_ALLOWLIST: &[&str] = &[
"USERNAME",
"USERPROFILE",
// ShellExecuteExW needs SystemRoot to elevate the setup helper.
"SYSTEMROOT",
];
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SandboxType {
+16 -1
View File
@@ -490,11 +490,12 @@ fn transform_linux_seccomp_uses_helper_alias_when_launcher_is_not_helper_path()
#[cfg(target_os = "windows")]
#[test]
fn transform_for_direct_spawn_windows_preserves_only_wrapper_setup_identity() {
fn transform_for_direct_spawn_windows_preserves_only_wrapper_setup_environment() {
let mut env = HashMap::from([
("Path".to_string(), r"C:\Windows\System32".to_string()),
("username".to_string(), "wrong-user".to_string()),
("UserProfile".to_string(), r"C:\wrong".to_string()),
("SYSTEMROOT".to_string(), r"C:\wrong".to_string()),
]);
super::add_windows_sandbox_wrapper_setup_env_from_vars(
@@ -502,7 +503,9 @@ fn transform_for_direct_spawn_windows_preserves_only_wrapper_setup_identity() {
[
("USERNAME", "alice"),
("USERPROFILE", r"C:\Users\alice"),
("SystemRoot", r"C:\Windows"),
("OPENAI_API_KEY", "secret"),
("HTTP_PROXY", "http://127.0.0.1:7890"),
]
.map(|(key, value)| {
(
@@ -518,6 +521,7 @@ fn transform_for_direct_spawn_windows_preserves_only_wrapper_setup_identity() {
("Path".to_string(), r"C:\Windows\System32".to_string()),
("USERNAME".to_string(), "alice".to_string()),
("USERPROFILE".to_string(), r"C:\Users\alice".to_string()),
("SystemRoot".to_string(), r"C:\Windows".to_string()),
])
);
}
@@ -596,6 +600,17 @@ fn transform_for_direct_spawn_windows_materializes_inner_helper() {
)
.expect("transform for direct spawn");
let inner_env_json = exec_request
.command
.windows(2)
.find(|args| args[0] == "--env-json")
.expect("inner command environment");
assert_eq!(
serde_json::from_str::<HashMap<String, String>>(&inner_env_json[1])
.expect("decode inner command environment"),
HashMap::from([("Path".to_string(), r"C:\Windows\System32".to_string())])
);
let separator_index = exec_request
.command
.iter()