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");

Reply via email to