https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c175c4f47df477846efda556476fba45f405b4d1
commit c175c4f47df477846efda556476fba45f405b4d1 Author: George Bișoc <george.bi...@reactos.org> AuthorDate: Wed Jun 21 17:56:12 2023 +0200 Commit: unknown <george.bi...@reactos.org> CommitDate: Tue Aug 22 17:54:18 2023 +0200 [SDK:RTL] Implement object type ACE validation checks Write the necessary ACL validation code for ACEs whose types are ACCESS_ALLOWED_OBJECT_ACE_TYPE or ACCESS_DENIED_OBJECT_ACE_TYPE. This ensures each created object type ACL has valid ACE contents. --- sdk/lib/rtl/acl.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/sdk/lib/rtl/acl.c b/sdk/lib/rtl/acl.c index e7fa8e3c7cf..afe41d0bcdb 100644 --- a/sdk/lib/rtl/acl.c +++ b/sdk/lib/rtl/acl.c @@ -839,6 +839,9 @@ RtlValidAcl(IN PACL Acl) PACE_HEADER Ace; PISID Sid; ULONG i; + USHORT RequiredObjectAceSize; + PULONG Flags; + ULONG GuidSize; PAGED_CODE_RTL(); _SEH2_TRY @@ -929,6 +932,68 @@ RtlValidAcl(IN PACL Acl) _SEH2_YIELD(return FALSE); } } + else if (Ace->AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE || + Ace->AceType == ACCESS_DENIED_OBJECT_ACE_TYPE) + { + /* Object ACEs are supported starting with Revision 4 */ + if (Acl->AclRevision < ACL_REVISION4) + { + DPRINT1("Invalid ACL revision for Object ACE: %u\n", Acl->AclRevision); + _SEH2_YIELD(return FALSE); + } + + /* Validate the length of this ACE */ + if (ROUND_DOWN(Ace->AceSize, sizeof(ULONG)) != Ace->AceSize) + { + DPRINT1("Misaligned Object ACE size: %lx\n", Ace->AceSize); + _SEH2_YIELD(return FALSE); + } + + /* The ACE size should at least have enough space for the known object ACE header */ + if (Ace->AceSize < sizeof(KNOWN_OBJECT_ACE)) + { + DPRINT1("Too small Object ACE size to hold KNOWN_OBJECT_ACE header: %lx\n", Ace->AceSize); + _SEH2_YIELD(return FALSE); + } + + /* This ACL may have multiple Object ACEs so reset the size counter */ + GuidSize = 0; + + /* If we have GUIDs include them */ + Flags = (PULONG)&((PKNOWN_OBJECT_ACE)Ace)->Flags; + if (*Flags & ACE_OBJECT_TYPE_PRESENT) + { + GuidSize += sizeof(GUID); + } + + if (*Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) + { + GuidSize += sizeof(GUID); + } + + /* Check if the SID revision is valid */ + Sid = (PISID)((ULONG_PTR)&((PKNOWN_OBJECT_ACE)Ace)->SidStart + GuidSize); + if (Sid->Revision != SID_REVISION) + { + DPRINT1("Object ACE SID has invalid revision: %u\n", Sid->Revision); + _SEH2_YIELD(return FALSE); + } + + /* Check if the SID is out of bounds */ + if (Sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) + { + DPRINT1("Object ACE SID's sub-authority count is out of bounds: %u\n", Sid->SubAuthorityCount); + _SEH2_YIELD(return FALSE); + } + + /* The ACE size should at least have enough space for the known object ACE header, GUIDs and the SID */ + RequiredObjectAceSize = (sizeof(KNOWN_OBJECT_ACE) - sizeof(ULONG)) + GuidSize + RtlLengthSid(Sid); + if (Ace->AceSize < RequiredObjectAceSize) + { + DPRINT1("Too small Object ACE size: AceSize %u RequiredSize %u\n", Ace->AceSize, RequiredObjectAceSize); + _SEH2_YIELD(return FALSE); + } + } else if (Ace->AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE) { DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");