Repair legacy Windows sandbox bin permissions for SYSTEM (#59745)

## Why

Legacy `.sandbox-bin` ACLs grant `SYSTEM` Modify access without `WRITE_DAC`, preventing the provisioning service from reapplying the bin policy.

## What changed

- Grant `SYSTEM` inheritable `WRITE_DAC` access when protecting the sandbox bin so it can update permissions on the directory and its children.
- Before legacy provisioning, repair the old ACL through an authenticated owner handle when `SYSTEM` is denied access. Upgrade only the expected SYSTEM entry in a protected, allow-only ACL, reject unexpected permissions, and verify that `SYSTEM` can reopen the directory with `WRITE_DAC`.

## Testing

Extend ACL coverage to check `SYSTEM` permissions on the bin and existing and newly created runner files. Add an ignored Windows integration test requiring LocalSystem and user-owned legacy homes to cover successful repair, repeated repair, and rejection of an explicit SYSTEM deny entry.

GitOrigin-RevId: 2303cdf5182947c2d044c79ac7027a16f0373c7d
This commit is contained in:
zm-oai
2026-11-05 21:33:57 +00:00
committed by copyberry
parent af92ae158d
commit b93a7b1512
7 changed files with 176 additions and 25 deletions
@@ -370,22 +370,23 @@ fn lock_sandbox_dir(
let system_sid = resolve_sid("SYSTEM")?;
let admins_sid = resolve_sid("Administrators")?;
let real_sid = resolve_sid(real_user)?;
let modify = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE;
let (security_information, system_access) = match dacl_inheritance {
DaclInheritance::Inherited => (DACL_SECURITY_INFORMATION, modify),
// The SYSTEM helper must be able to reapply the bin policy to existing children.
DaclInheritance::Protected => (
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
modify | WRITE_DAC,
),
};
let entries = [
(
sandbox_group_sid.to_vec(),
sandbox_group_mask,
sandbox_group_access_mode,
),
(
system_sid,
FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE,
GRANT_ACCESS,
),
(
admins_sid,
FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE,
GRANT_ACCESS,
),
(system_sid, system_access, GRANT_ACCESS),
(admins_sid, modify, GRANT_ACCESS),
(real_sid, real_user_mask, GRANT_ACCESS),
];
unsafe {
@@ -427,12 +428,6 @@ fn lock_sandbox_dir(
"SetEntriesInAclW sandbox dir failed: {set}",
));
}
let security_information = match dacl_inheritance {
DaclInheritance::Inherited => DACL_SECURITY_INFORMATION,
DaclInheritance::Protected => {
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION
}
};
let (res, api) = match directory.as_ref() {
Some(directory) => (
SetSecurityInfo(
@@ -158,10 +158,21 @@ fn lock_sandbox_dir_blocks_inherited_write_for_runner_files() {
)
.expect("sandbox cannot change the bin DACL")
);
let system_sid = resolve_sid("SYSTEM").expect("resolve SYSTEM SID");
let system_psid = sid_bytes_to_psid(&system_sid).expect("convert SYSTEM SID");
let new_runner = sandbox_bin.join("new-runner.exe");
fs::write(&new_runner, b"new").expect("create new runner");
for path in [&sandbox_bin, &existing_runner, &new_runner] {
assert!(
path_mask_allows(
path,
&[system_psid],
WRITE_DAC,
/*require_all_bits*/ true
)
.expect("SYSTEM can reapply the bin policy")
);
assert!(
!path_mask_allows(
path,