Fix Windows sandbox rename ACLs

This commit is contained in:
David Wiesen
2026-05-11 09:08:34 -07:00
parent 0035d7bd18
commit 6241fcf230
+24 -3
View File
@@ -50,6 +50,8 @@ const SE_KERNEL_OBJECT: u32 = 6;
const INHERIT_ONLY_ACE: u8 = 0x08;
const GENERIC_WRITE_MASK: u32 = 0x4000_0000;
const DENY_ACCESS: i32 = 3;
const SANDBOX_ALLOW_MASK: u32 =
FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE | FILE_DELETE_CHILD;
/// Fetch DACL via handle-based query; caller must LocalFree the returned SD.
///
@@ -202,12 +204,19 @@ pub unsafe fn dacl_has_write_allow_for_sid(p_dacl: *mut ACL, psid: *mut c_void)
continue;
}
let ace = &*(p_ace as *const ACCESS_ALLOWED_ACE);
let mask = ace.Mask;
let mut mask = ace.Mask;
let mapping = GENERIC_MAPPING {
GenericRead: FILE_GENERIC_READ,
GenericWrite: FILE_GENERIC_WRITE,
GenericExecute: FILE_GENERIC_EXECUTE,
GenericAll: FILE_ALL_ACCESS,
};
MapGenericMask(&mut mask, &mapping);
let base = p_ace as usize;
let sid_ptr =
(base + std::mem::size_of::<ACE_HEADER>() + std::mem::size_of::<u32>()) as *mut c_void;
let eq = EqualSid(sid_ptr, psid);
if eq != 0 && (mask & FILE_GENERIC_WRITE) != 0 {
if eq != 0 && (mask & SANDBOX_ALLOW_MASK) == SANDBOX_ALLOW_MASK {
return true;
}
}
@@ -420,7 +429,7 @@ 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;
explicit.grfAccessPermissions = SANDBOX_ALLOW_MASK;
explicit.grfAccessMode = 2; // SET_ACCESS
explicit.grfInheritance = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
explicit.Trustee = trustee;
@@ -636,3 +645,15 @@ pub unsafe fn allow_null_device(psid: *mut c_void) {
}
const CONTAINER_INHERIT_ACE: u32 = 0x2;
const OBJECT_INHERIT_ACE: u32 = 0x1;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sandbox_allow_mask_includes_delete_and_rename_semantics() {
assert_ne!(SANDBOX_ALLOW_MASK & FILE_GENERIC_WRITE, 0);
assert_ne!(SANDBOX_ALLOW_MASK & DELETE, 0);
assert_ne!(SANDBOX_ALLOW_MASK & FILE_DELETE_CHILD, 0);
}
}