Fix native Windows policy fixtures

This commit is contained in:
Chris Bookholt
2026-07-03 10:38:38 -07:00
parent 387e083154
commit b4317f4cc7
4 changed files with 87 additions and 18 deletions

View File

@@ -27,6 +27,14 @@ fn untrusted_powershell_command(script: &str) -> Vec<String> {
]
}
fn absolute_untrusted_powershell_command(script: &str) -> Vec<String> {
vec![
r"C:\workspace\powershell.exe".to_string(),
"-Command".to_string(),
script.to_string(),
]
}
fn prefix_rule_for(command: &[String], decision: &str) -> String {
let pattern = command
.iter()
@@ -479,7 +487,7 @@ fn untrusted_permission_and_windows_backend_gates_require_composed_authority() {
use SandboxPermissions as SP;
use WindowsSandboxLevel as WSL;
let outer = untrusted_powershell_command("Get-Content Cargo.toml");
let outer = absolute_untrusted_powershell_command("Get-Content Cargo.toml");
let inner = vec_str(&["Get-Content", "Cargo.toml"]);
let partial_policy = format!(
"{}\n{}",
@@ -686,7 +694,7 @@ fn untrusted_wrapper_identity_uses_exact_outer_and_restrictive_basename_rules()
#[tokio::test]
async fn untrusted_parsed_results_ignore_requested_amendments() {
let command = untrusted_powershell_command("echo allowed");
let command = absolute_untrusted_powershell_command("echo allowed");
let inner_allow = prefix_rule_for(&vec_str(&["echo"]), "allow");
let requested_prefix = Some(vec_str(&["echo"]));
@@ -837,7 +845,7 @@ async fn dangerous_trusted_unsupported_scripts_keep_generic_policy_protections()
}
#[tokio::test]
async fn sandbox_override_on_trusted_unsupported_script_uses_outer_argv() {
async fn sandbox_override_on_trusted_unsupported_script_does_not_offer_amendment() {
let command = powershell_command("Write-Output 'confusing but inert'");
for (approval_policy, permits_prompt) in [
@@ -855,7 +863,10 @@ async fn sandbox_override_on_trusted_unsupported_script_uses_outer_argv() {
)
.await,
if permits_prompt {
outer_result(&command, true)
ExecApprovalRequirement::NeedsApproval {
reason: None,
proposed_execpolicy_amendment: None,
}
} else {
ExecApprovalRequirement::Forbidden {
reason: REJECT_SANDBOX_APPROVAL_REASON.to_string(),

View File

@@ -79,6 +79,10 @@ fn host_program_path(name: &str) -> String {
host_absolute_path(&["usr", "bin", &executable_name])
}
fn posix_script_program_path(name: &str) -> String {
host_program_path(name).replace('\\', "/")
}
fn starlark_string(value: &str) -> String {
value.replace('\\', "\\\\").replace('"', "\\\"")
}
@@ -1712,7 +1716,10 @@ async fn configured_delegators_without_rules_preserve_legacy_sandboxed_behavior(
#[tokio::test]
async fn configured_exact_allow_can_authorize_an_opaque_nested_shell_only() {
let inner = vec![host_program_path("sh"), "/tmp/approved-script".to_string()];
let inner = vec![
posix_script_program_path("sh"),
"/tmp/approved-script".to_string(),
];
let command = vec![
host_program_path("zsh"),
"-lc".to_string(),
@@ -1849,7 +1856,7 @@ async fn bare_nested_shell_allow_never_establishes_wrapper_authority() {
);
let absolute_wrapper = vec![
host_program_path("bash"),
posix_script_program_path("bash"),
"-lc".to_string(),
"echo hello".to_string(),
];

View File

@@ -180,31 +180,41 @@ async fn full_outer_allow_does_not_bypass_extended_unsupported_wrapper() {
let mut extended = command.clone();
extended.push("trailing-runtime-argument".to_string());
for (profile, level, permissions, prompts) in [
for (profile, level, permissions, prompts, offers_amendment) in [
(
PermissionProfile::read_only(),
RestrictedToken,
UseDefault,
false,
true,
),
(
PermissionProfile::read_only(),
RestrictedToken,
RequireEscalated,
true,
false,
),
(
PermissionProfile::read_only(),
RestrictedToken,
WithAdditionalPermissions,
true,
false,
),
(
PermissionProfile::read_only(),
Disabled,
UseDefault,
true,
true,
),
(PermissionProfile::read_only(), Disabled, UseDefault, true),
(
PermissionProfile::Disabled,
RestrictedToken,
UseDefault,
false,
true,
),
] {
assert_eq!(
@@ -218,9 +228,21 @@ async fn full_outer_allow_does_not_bypass_extended_unsupported_wrapper() {
)
.await,
if prompts {
prompt_outer(&extended)
} else {
if offers_amendment {
prompt_outer(&extended)
} else {
ExecApprovalRequirement::NeedsApproval {
reason: None,
proposed_execpolicy_amendment: None,
}
}
} else if offers_amendment {
skip_outer(&extended, false)
} else {
ExecApprovalRequirement::Skip {
bypass_sandbox: false,
proposed_execpolicy_amendment: None,
}
},
);
}
@@ -296,45 +318,63 @@ async fn outer_authority_tracks_permission_deltas_and_missing_managed_sandbox()
NetworkSandboxPolicy::Restricted,
);
for (profile, level, permissions, prompts) in [
for (profile, level, permissions, prompts, offers_amendment) in [
(
PermissionProfile::read_only(),
RestrictedToken,
RequireEscalated,
true,
false,
),
(
PermissionProfile::read_only(),
Disabled,
UseDefault,
true,
true,
),
(PermissionProfile::read_only(), Disabled, UseDefault, true),
(
denied_read_profile,
RestrictedToken,
RequireEscalated,
false,
false,
),
(
PermissionProfile::read_only(),
RestrictedToken,
WithAdditionalPermissions,
true,
false,
),
(
PermissionProfile::Disabled,
RestrictedToken,
RequireEscalated,
false,
false,
),
(
PermissionProfile::Disabled,
RestrictedToken,
WithAdditionalPermissions,
false,
false,
),
(external_profile(), RestrictedToken, UseDefault, false, true),
(
external_profile(),
RestrictedToken,
RequireEscalated,
true,
false,
),
(external_profile(), RestrictedToken, UseDefault, false),
(external_profile(), RestrictedToken, RequireEscalated, true),
(
external_profile(),
RestrictedToken,
WithAdditionalPermissions,
true,
false,
),
] {
assert_eq!(
@@ -348,9 +388,21 @@ async fn outer_authority_tracks_permission_deltas_and_missing_managed_sandbox()
)
.await,
if prompts {
prompt_outer(&command)
} else {
if offers_amendment {
prompt_outer(&command)
} else {
ExecApprovalRequirement::NeedsApproval {
reason: None,
proposed_execpolicy_amendment: None,
}
}
} else if offers_amendment {
skip_outer(&command, false)
} else {
ExecApprovalRequirement::Skip {
bypass_sandbox: false,
proposed_execpolicy_amendment: None,
}
},
);
}

View File

@@ -2333,7 +2333,7 @@ async fn write_stdin_ctrl_c_reports_unsupported_interrupt_to_model_on_windows()
let server = start_mock_server().await;
let mut builder = test_codex().with_config(|config| {
let mut builder = test_codex().with_windows_cmd_shell().with_config(|config| {
config
.features
.enable(Feature::UnifiedExec)
@@ -2345,7 +2345,6 @@ async fn write_stdin_ctrl_c_reports_unsupported_interrupt_to_model_on_windows()
let interrupt_call_id = "uexec-windows-interrupt";
let start_args = serde_json::json!({
"shell": "cmd",
"cmd": "echo READY && ping -n 30 127.0.0.1 >NUL",
"yield_time_ms": 250,
"tty": false,