[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.
This commit is contained in:
George Bișoc 2023-06-21 17:56:12 +02:00 committed by unknown
parent 8289de6ef7
commit c175c4f47d
No known key found for this signature in database
GPG key ID: 688C4FBE25D7DEF6

View file

@ -839,6 +839,9 @@ RtlValidAcl(IN PACL Acl)
PACE_HEADER Ace; PACE_HEADER Ace;
PISID Sid; PISID Sid;
ULONG i; ULONG i;
USHORT RequiredObjectAceSize;
PULONG Flags;
ULONG GuidSize;
PAGED_CODE_RTL(); PAGED_CODE_RTL();
_SEH2_TRY _SEH2_TRY
@ -929,6 +932,68 @@ RtlValidAcl(IN PACL Acl)
_SEH2_YIELD(return FALSE); _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) else if (Ace->AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE)
{ {
DPRINT1("Unsupported ACE in ReactOS, assuming valid\n"); DPRINT1("Unsupported ACE in ReactOS, assuming valid\n");