properly handle fragmented self-relative security descriptors in the 64
bit version of RtlSelfRelativeToAbsoluteSD2
Modified: trunk/reactos/lib/rtl/sd.c
_____
Modified: trunk/reactos/lib/rtl/sd.c
--- trunk/reactos/lib/rtl/sd.c 2005-11-01 21:53:36 UTC (rev 18938)
+++ trunk/reactos/lib/rtl/sd.c 2005-11-01 22:36:00 UTC (rev 18939)
@@ -735,8 +735,9 @@
PISECURITY_DESCRIPTOR AbsSD = SelfRelativeSecurityDescriptor;
PISECURITY_DESCRIPTOR_RELATIVE RelSD =
(PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSecurityDescriptor;
#ifdef _WIN64
- PVOID DataStart;
+ PVOID DataStart, DataEnd;
ULONG DataSize;
+ LONG MoveDelta;
ULONG OwnerLength;
ULONG GroupLength;
ULONG DaclLength;
@@ -784,7 +785,37 @@
ASSERT(sizeof(SECURITY_DESCRIPTOR) >
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
- DataSize = OwnerLength + GroupLength + DaclLength + SaclLength;
+ /* calculate the start and end of the data area, we simply just
move the
+ data by the difference between the size of the relative and
absolute
+ security descriptor structure */
+ DataStart = pOwner;
+ DataEnd = (PVOID)((ULONG_PTR)pOwner + OwnerLength);
+ if (pGroup != NULL)
+ {
+ if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || DataStart ==
NULL)
+ DataStart = pGroup;
+ if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) ||
DataEnd == NULL)
+ DataEnd = (PVOID)((ULONG_PTR)pGroup + GroupLength);
+ }
+ if (pDacl != NULL)
+ {
+ if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || DataStart ==
NULL)
+ DataStart = pDacl;
+ if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) ||
DataEnd == NULL)
+ DataEnd = (PVOID)((ULONG_PTR)pDacl + DaclLength);
+ }
+ if (pSacl != NULL)
+ {
+ if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || DataStart ==
NULL)
+ DataStart = pSacl;
+ if (((ULONG_PTR)pSacl + DaclLength > (ULONG_PTR)DataEnd) ||
DataEnd == NULL)
+ DataEnd = (PVOID)((ULONG_PTR)pSacl + SaclLength);
+ }
+
+ ASSERT((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart);
+
+ DataSize = (ULONG)((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart);
+
if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize)
{
*BufferSize = sizeof(SECURITY_DESCRIPTOR) + DataSize;
@@ -793,17 +824,6 @@
if (DataSize != 0)
{
- /* calculate the start of the data area, we simply just move
the data by
- the difference between the size of the relative and absolute
security
- descriptor structure */
- DataStart = pOwner;
- if ((pGroup != NULL && (ULONG_PTR)pGroup <
(ULONG_PTR)DataStart) || DataStart == NULL)
- DataStart = pGroup;
- if ((pDacl != NULL && (ULONG_PTR)pDacl < (ULONG_PTR)DataStart)
|| DataStart == NULL)
- DataStart = pDacl;
- if ((pSacl != NULL && (ULONG_PTR)pSacl < (ULONG_PTR)DataStart)
|| DataStart == NULL)
- DataStart = pSacl;
-
/* if DataSize != 0 ther must be at least one SID or ACL in the
security
descriptor! Also the data area must be located somewhere
after the
end of the SECURITY_DESCRIPTOR_RELATIVE structure */
@@ -815,28 +835,26 @@
DataStart,
DataSize);
+ MoveDelta = (LONG)((LONG_PTR)(AbsSD + 1) -
(LONG_PTR)DataStart);
+
/* adjust the pointers if neccessary */
if (pOwner != NULL)
- AbsSD->Owner = (PSID)((ULONG_PTR)pOwner +
- sizeof(SECURITY_DESCRIPTOR) -
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+ AbsSD->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta);
else
AbsSD->Owner = NULL;
if (pGroup != NULL)
- AbsSD->Group = (PSID)((ULONG_PTR)pGroup +
- sizeof(SECURITY_DESCRIPTOR) -
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+ AbsSD->Group = (PSID)((LONG_PTR)pGroup + MoveDelta);
else
AbsSD->Group = NULL;
if (pSacl != NULL)
- AbsSD->Sacl = (PACL)((ULONG_PTR)pSacl +
- sizeof(SECURITY_DESCRIPTOR) -
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+ AbsSD->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta);
else
AbsSD->Sacl = NULL;
if (pDacl != NULL)
- AbsSD->Dacl = (PACL)((ULONG_PTR)pDacl +
- sizeof(SECURITY_DESCRIPTOR) -
sizeof(SECURITY_DESCRIPTOR_RELATIVE));
+ AbsSD->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta);
else
AbsSD->Dacl = NULL;
}