windows sandbox: preserve delete rights on stamped paths

This commit is contained in:
David Wiesen
2026-05-11 09:12:20 -07:00
parent 2229c8daf2
commit a48adb53fb
2 changed files with 40 additions and 1 deletions
@@ -328,6 +328,43 @@ def main() -> int:
rc, out, err = run_sbx("workspace-write", ["cmd", "/c", "del /q delme.txt"], WS_ROOT)
add("WS: delete succeeds (expected on this host)", rc == 0 and not target.exists(), f"rc={rc}, err={err}")
# 12b. WS: atomic replace inside workspace succeeds
replace_target = WS_ROOT / "replace.txt"
write_file(replace_target, "old")
rc, out, err = run_sbx(
"workspace-write",
[
"python",
"-c",
"from pathlib import Path; import os; p=Path('replace.txt'); t=Path('replace.txt.tmp'); t.write_text('new', encoding='utf-8'); os.replace(t, p); print(p.read_text(encoding='utf-8'))",
],
WS_ROOT,
)
add(
"WS: atomic replace in workspace allowed",
rc == 0 and replace_target.read_text(encoding='utf-8').strip() == "new",
f"rc={rc}, err={err}",
)
# 12c. WS: atomic replace in additional root succeeds
extra_replace_target = EXTRA_ROOT / "replace-extra.txt"
write_file(extra_replace_target, "old")
rc, out, err = run_sbx(
"workspace-write",
[
"python",
"-c",
f"from pathlib import Path; import os; p=Path(r'{extra_replace_target}'); t=Path(r'{extra_replace_target}.tmp'); t.write_text('new', encoding='utf-8'); os.replace(t, p); print(p.read_text(encoding='utf-8'))",
],
WS_ROOT,
additional_root=EXTRA_ROOT,
)
add(
"WS: atomic replace in additional root allowed",
rc == 0 and extra_replace_target.read_text(encoding='utf-8').strip() == "new",
f"rc={rc}, err={err}",
)
# 13. RO: python tries to write (denied)
pyfile = WS_ROOT / "py_should_fail.txt"; remove_if_exists(pyfile)
rc, out, err = run_sbx("read-only", ["python", "-c", "open('py_should_fail.txt','w').write('x')"], WS_ROOT)
+3 -1
View File
@@ -411,7 +411,9 @@ pub unsafe fn add_allow_ace(path: &Path, psid: *mut c_void) -> Result<bool> {
ptstrName: psid as *mut u16,
};
let mut explicit: EXPLICIT_ACCESS_W = std::mem::zeroed();
explicit.grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE;
// Keep legacy one-shot ACL grants aligned with the stronger write mask used by
// setup refresh so atomic replace/delete patterns work on stamped paths too.
explicit.grfAccessPermissions = WRITE_ALLOW_MASK;
explicit.grfAccessMode = 2; // SET_ACCESS
explicit.grfInheritance = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
explicit.Trustee = trustee;