mirror of
https://github.com/reactos/reactos.git
synced 2025-06-04 08:50:27 +00:00
- Make TOKEN pointer in OBJECT_HEADER a fast reference, just like on Windows.
- Update SD cache code to treat it as such. - Improves performance by 500% during security checks - noticeable impact during large file or registry transfer operations. svn path=/trunk/; revision=39876
This commit is contained in:
parent
78cc4931af
commit
d6b8e5ff23
2 changed files with 91 additions and 25 deletions
|
@ -181,19 +181,46 @@ ObpReferenceSecurityDescriptor(IN POBJECT_HEADER ObjectHeader)
|
||||||
{
|
{
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
PSECURITY_DESCRIPTOR_HEADER SdHeader;
|
PSECURITY_DESCRIPTOR_HEADER SdHeader;
|
||||||
|
PEX_FAST_REF FastRef;
|
||||||
|
EX_FAST_REF OldValue;
|
||||||
|
ULONG_PTR Count;
|
||||||
|
|
||||||
/* Get the SD */
|
/* Acquire a reference to the security descriptor */
|
||||||
SecurityDescriptor = ObjectHeader->SecurityDescriptor;
|
FastRef = (PEX_FAST_REF)&ObjectHeader->SecurityDescriptor;
|
||||||
if (!SecurityDescriptor)
|
OldValue = ExAcquireFastReference(FastRef);
|
||||||
|
|
||||||
|
/* Get the descriptor and reference count */
|
||||||
|
SecurityDescriptor = ExGetObjectFastReference(OldValue);
|
||||||
|
Count = ExGetCountFastReference(OldValue);
|
||||||
|
|
||||||
|
/* Check if there's no descriptor or if there's still cached references */
|
||||||
|
if ((Count >= 1) || !(SecurityDescriptor))
|
||||||
{
|
{
|
||||||
/* No SD, nothing to do */
|
/* Check if this is the last reference */
|
||||||
return NULL;
|
if (Count == 1)
|
||||||
|
{
|
||||||
|
/* Add the extra references that we'll take */
|
||||||
|
SdHeader = ObpGetHeaderForSd(SecurityDescriptor);
|
||||||
|
InterlockedExchangeAdd((PLONG)&SdHeader->RefCount, MAX_FAST_REFS);
|
||||||
|
|
||||||
|
/* Now insert them */
|
||||||
|
if (!ExInsertFastReference(FastRef, SecurityDescriptor))
|
||||||
|
{
|
||||||
|
/* Undo the references since we failed */
|
||||||
|
InterlockedExchangeAdd((PLONG)&SdHeader->RefCount,
|
||||||
|
-MAX_FAST_REFS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the SD */
|
||||||
|
return SecurityDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock the object */
|
/* Lock the object */
|
||||||
ObpAcquireObjectLockShared(ObjectHeader);
|
ObpAcquireObjectLockShared(ObjectHeader);
|
||||||
|
|
||||||
/* Get the object header */
|
/* Get the object header */
|
||||||
|
SecurityDescriptor = ExGetObjectFastReference(*FastRef);
|
||||||
SdHeader = ObpGetHeaderForSd(SecurityDescriptor);
|
SdHeader = ObpGetHeaderForSd(SecurityDescriptor);
|
||||||
|
|
||||||
/* Do the reference */
|
/* Do the reference */
|
||||||
|
|
|
@ -24,19 +24,23 @@ ObAssignObjectSecurityDescriptor(IN PVOID Object,
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PSECURITY_DESCRIPTOR NewSd;
|
PSECURITY_DESCRIPTOR NewSd;
|
||||||
|
PEX_FAST_REF FastRef;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Get the object header */
|
/* Get the object header */
|
||||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
|
||||||
|
FastRef = (PEX_FAST_REF)&ObjectHeader->SecurityDescriptor;
|
||||||
if (!SecurityDescriptor)
|
if (!SecurityDescriptor)
|
||||||
{
|
{
|
||||||
/* Nothing to assign */
|
/* Nothing to assign */
|
||||||
ObjectHeader->SecurityDescriptor = NULL;
|
ExInitializeFastReference(FastRef, NULL);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add it to our internal cache */
|
/* Add it to our internal cache */
|
||||||
Status = ObLogSecurityDescriptor(SecurityDescriptor, &NewSd, 1);
|
Status = ObLogSecurityDescriptor(SecurityDescriptor,
|
||||||
|
&NewSd,
|
||||||
|
MAX_FAST_REFS + 1);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Free the old copy */
|
/* Free the old copy */
|
||||||
|
@ -44,7 +48,7 @@ ObAssignObjectSecurityDescriptor(IN PVOID Object,
|
||||||
|
|
||||||
/* Set the new pointer */
|
/* Set the new pointer */
|
||||||
ASSERT(NewSd);
|
ASSERT(NewSd);
|
||||||
ObjectHeader->SecurityDescriptor = NewSd;
|
ExInitializeFastReference(FastRef, NewSd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return status */
|
/* Return status */
|
||||||
|
@ -55,12 +59,23 @@ NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ObDeassignSecurity(IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
|
ObDeassignSecurity(IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
|
||||||
{
|
{
|
||||||
/* Dereference it */
|
EX_FAST_REF FastRef;
|
||||||
ObDereferenceSecurityDescriptor(*SecurityDescriptor, 1);
|
ULONG_PTR Count;
|
||||||
|
PSECURITY_DESCRIPTOR OldSecurityDescriptor;
|
||||||
|
|
||||||
|
/* Get the fast reference and capture it */
|
||||||
|
FastRef = *(PEX_FAST_REF)SecurityDescriptor;
|
||||||
|
|
||||||
/* Don't free again later */
|
/* Don't free again later */
|
||||||
*SecurityDescriptor = NULL;
|
*SecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
/* Get the descriptor and reference count */
|
||||||
|
OldSecurityDescriptor = ExGetObjectFastReference(FastRef);
|
||||||
|
Count = ExGetCountFastReference(FastRef);
|
||||||
|
|
||||||
|
/* Dereference the descriptor */
|
||||||
|
ObDereferenceSecurityDescriptor(OldSecurityDescriptor, Count + 1);
|
||||||
|
|
||||||
/* All done */
|
/* All done */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +124,9 @@ ObSetSecurityDescriptorInfo(IN PVOID Object,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
POBJECT_HEADER ObjectHeader;
|
POBJECT_HEADER ObjectHeader;
|
||||||
PSECURITY_DESCRIPTOR OldDescriptor, NewDescriptor, CachedDescriptor;
|
PSECURITY_DESCRIPTOR OldDescriptor, NewDescriptor, CachedDescriptor;
|
||||||
|
PEX_FAST_REF FastRef;
|
||||||
|
EX_FAST_REF OldValue;
|
||||||
|
ULONG_PTR Count;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Get the object header */
|
/* Get the object header */
|
||||||
|
@ -129,7 +147,9 @@ ObSetSecurityDescriptorInfo(IN PVOID Object,
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Now add this to the cache */
|
/* Now add this to the cache */
|
||||||
Status = ObLogSecurityDescriptor(NewDescriptor, &CachedDescriptor, 1);
|
Status = ObLogSecurityDescriptor(NewDescriptor,
|
||||||
|
&CachedDescriptor,
|
||||||
|
MAX_FAST_REFS + 1);
|
||||||
|
|
||||||
/* Let go of our uncached copy */
|
/* Let go of our uncached copy */
|
||||||
ExFreePool(NewDescriptor);
|
ExFreePool(NewDescriptor);
|
||||||
|
@ -137,15 +157,34 @@ ObSetSecurityDescriptorInfo(IN PVOID Object,
|
||||||
/* Check for success */
|
/* Check for success */
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Dereference the old one */
|
/* Do the swap */
|
||||||
ASSERT(OldDescriptor == ObjectHeader->SecurityDescriptor);
|
FastRef = (PEX_FAST_REF)OutputSecurityDescriptor;
|
||||||
|
OldValue = ExCompareSwapFastReference(FastRef,
|
||||||
|
CachedDescriptor,
|
||||||
|
OldDescriptor);
|
||||||
|
|
||||||
/* Now set this as the new descriptor */
|
/* Get the security descriptor */
|
||||||
ObjectHeader->SecurityDescriptor = CachedDescriptor;
|
SecurityDescriptor = ExGetObjectFastReference(OldValue);
|
||||||
|
Count = ExGetCountFastReference(OldValue);
|
||||||
|
|
||||||
/* And dereference the old one */
|
/* Make sure the swap worked */
|
||||||
ObDereferenceSecurityDescriptor(OldDescriptor, 1);
|
if (SecurityDescriptor == OldDescriptor)
|
||||||
break;
|
{
|
||||||
|
/* Flush waiters */
|
||||||
|
ObpAcquireObjectLock(ObjectHeader);
|
||||||
|
ObpReleaseObjectLock(ObjectHeader);
|
||||||
|
|
||||||
|
/* And dereference the old one */
|
||||||
|
ObDereferenceSecurityDescriptor(OldDescriptor, Count + 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Someone changed it behind our back -- try again */
|
||||||
|
ObDereferenceSecurityDescriptor(OldDescriptor, 1);
|
||||||
|
ObDereferenceSecurityDescriptor(CachedDescriptor,
|
||||||
|
MAX_FAST_REFS + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue