Improve TokenDefaultDacl buffer allocations
@@ -818,21 +818,47 @@ _Callback_ NTSTATUS PhStdGetObjectSecurity(
if (NT_SUCCESS(status))
{
+ ACL_SIZE_INFORMATION aclSizeInfo;
+
+ status = RtlQueryInformationAcl(
+ defaultDacl->DefaultDacl,
+ &aclSizeInfo,
+ sizeof(ACL_SIZE_INFORMATION),
+ AclSizeInformation
+ );
+
+ if (NT_SUCCESS(status))
+ {
+ ULONG allocationLength;
PSECURITY_DESCRIPTOR securityDescriptor;
PTOKEN_OWNER tokenOwner;
+ PSID tokenOwnerSid = NULL;
+
+ if (NT_SUCCESS(PhGetTokenOwner(handle, &tokenOwner)))
+ {
+ tokenOwnerSid = PhAllocateCopy(tokenOwner->Owner, RtlLengthSid(tokenOwner->Owner));
+ PhFree(tokenOwner);
+ }
- // Note: We should enumerate the DefaultDacl entires to calculate the length but it's easier to use PAGE_SIZE. (dmex)
- securityDescriptor = PhAllocateZero(PAGE_SIZE);
+ allocationLength = SECURITY_DESCRIPTOR_MIN_LENGTH +
+ aclSizeInfo.AclBytesInUse +
+ (tokenOwnerSid ? RtlLengthSid(tokenOwnerSid) : 0);
+
+ securityDescriptor = PhAllocateZero(allocationLength);
RtlCreateSecurityDescriptor(securityDescriptor, SECURITY_DESCRIPTOR_REVISION);
RtlSetDaclSecurityDescriptor(securityDescriptor, TRUE, defaultDacl->DefaultDacl, FALSE);
- if (NT_SUCCESS(PhGetTokenOwner(handle, &tokenOwner)))
+ if (tokenOwnerSid)
{
- RtlSetOwnerSecurityDescriptor(securityDescriptor, tokenOwner->Owner, FALSE);
- PhFree(tokenOwner);
+ RtlSetOwnerSecurityDescriptor(securityDescriptor, tokenOwnerSid, TRUE);
+ PhFree(tokenOwnerSid);
}
+ assert(allocationLength == RtlLengthSecurityDescriptor(securityDescriptor));
+
*SecurityDescriptor = securityDescriptor;
+ }
+
PhFree(defaultDacl);
}
