diff --git a/codex-rs/windows-sandbox-rs/src/acl.rs b/codex-rs/windows-sandbox-rs/src/acl.rs index f351dba190..a752e291c3 100644 --- a/codex-rs/windows-sandbox-rs/src/acl.rs +++ b/codex-rs/windows-sandbox-rs/src/acl.rs @@ -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::() + std::mem::size_of::()) 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 { 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); + } +}