- Fix ObGetObjectSecurity to use the object type's pool type instead of assuming PagedPool.

- Re-wrote the way ObInsertObject handles security as described in Chapters 6 and 9 of Gl00my (ie: made it use ObGetObjectSecurity and ObAssignObjectSecurity; ironically, these functions already existed/are exported and could've been used since the start instead of duplicating code).
- Fix ObpReferenceCachedSecurityDescriptor only to touch the cached entry if it actually gets a non-NULL descriptor. Also improved it to return the referenced SD, instead of requiring the caller to do it manually.

svn path=/trunk/; revision=22279
This commit is contained in:
Alex Ionescu 2006-06-08 05:41:39 +00:00
parent f96e25891f
commit 2173f9e4aa
4 changed files with 76 additions and 62 deletions

View file

@ -172,9 +172,11 @@ NTSTATUS
NTAPI
ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
VOID
PSECURITY_DESCRIPTOR
NTAPI
ObpReferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor);
ObpReferenceCachedSecurityDescriptor(
IN PSECURITY_DESCRIPTOR SecurityDescriptor
);
VOID
NTAPI

View file

@ -1167,8 +1167,8 @@ ObInsertObject(IN PVOID Object,
PVOID FoundObject = NULL;
POBJECT_HEADER FoundHeader = NULL;
NTSTATUS Status = STATUS_SUCCESS;
PSECURITY_DESCRIPTOR NewSecurityDescriptor = NULL;
SECURITY_SUBJECT_CONTEXT SubjectContext;
PSECURITY_DESCRIPTOR DirectorySd = NULL;
BOOLEAN SdAllocated;
OBP_LOOKUP_CONTEXT Context;
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
ACCESS_STATE AccessState;
@ -1252,48 +1252,58 @@ ObInsertObject(IN PVOID Object,
}
}
DPRINT("Security Assignment in progress\n");
SeCaptureSubjectContext(&SubjectContext);
/* Build the new security descriptor */
Status = SeAssignSecurity((FoundHeader != NULL) ? FoundHeader->SecurityDescriptor : NULL,
(ObjectCreateInfo != NULL) ? ObjectCreateInfo->SecurityDescriptor : NULL,
&NewSecurityDescriptor,
(Header->Type == ObDirectoryType),
&SubjectContext,
&Header->Type->TypeInfo.GenericMapping,
PagedPool);
if (NT_SUCCESS(Status))
/* Check if it's named or forces security */
if ((IsNamed) || (ObjectType->TypeInfo.SecurityRequired))
{
DPRINT("NewSecurityDescriptor %p\n", NewSecurityDescriptor);
if (Header->Type->TypeInfo.SecurityProcedure != NULL)
/* Make sure it's inserted into an object directory */
if ((ObjectNameInfo) && (ObjectNameInfo->Directory))
{
/* Call the security method */
Status = Header->Type->TypeInfo.SecurityProcedure(&Header->Body,
AssignSecurityDescriptor,
0,
NewSecurityDescriptor,
NULL,
NULL,
NonPagedPool,
NULL);
}
else
{
/* Assign the security descriptor to the object header */
Status = ObpAddSecurityDescriptor(NewSecurityDescriptor,
&Header->SecurityDescriptor);
DPRINT("Object security descriptor %p\n", Header->SecurityDescriptor);
/* Get the current descriptor */
ObGetObjectSecurity(ObjectNameInfo->Directory,
&DirectorySd,
&SdAllocated);
}
/* Release the new security descriptor */
SeDeassignSecurity(&NewSecurityDescriptor);
/* Now assign it */
Status = ObAssignSecurity(PassedAccessState,
DirectorySd,
Object,
ObjectType);
/* Check if we captured one */
if (DirectorySd)
{
/* We did, release it */
DPRINT1("Here\n");
ObReleaseObjectSecurity(DirectorySd, SdAllocated);
}
else if (NT_SUCCESS(Status))
{
/* Other we didn't, but we were able to use the current SD */
SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor,
ObjectCreateInfo->ProbeMode,
TRUE);
/* Clear the current one */
PassedAccessState->SecurityDescriptor =
ObjectCreateInfo->SecurityDescriptor = NULL;
}
}
DPRINT("Security Complete\n");
SeReleaseSubjectContext(&SubjectContext);
/* Check if anything until now failed */
if (!NT_SUCCESS(Status))
{
/* We failed, dereference the object and delete the access state */
ObDereferenceObject(Object);
if (PassedAccessState == &AccessState)
{
/* We used a local one; delete it */
SeDeleteAccessState(PassedAccessState);
}
/* Return failure code */
return Status;
}
/* HACKHACK: Because of ROS's incorrect startup, this can be called
* without a valid Process until I finalize the startup patch,
@ -1301,8 +1311,7 @@ ObInsertObject(IN PVOID Object,
* a handle if Handle is NULL when the Registry Code calls it, because
* the registry code totally bastardizes the Ob and needs to be fixed
*/
DPRINT("Creating handle\n");
if (Handle != NULL)
if (Handle)
{
/* Create the handle */
Status = ObpCreateHandle(OpenReason,
@ -1338,7 +1347,6 @@ ObInsertObject(IN PVOID Object,
}
/* Return failure code */
DPRINT("Status %x\n", Status);
return Status;
}

View file

@ -306,28 +306,32 @@ ObpRemoveSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
return STATUS_SUCCESS;
}
VOID
PSECURITY_DESCRIPTOR
NTAPI
ObpReferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
PSD_CACHE_ENTRY CacheEntry;
PSD_CACHE_ENTRY CacheEntry;
DPRINT("ObpReferenceCachedSecurityDescriptor() called\n");
/* Lock the cache */
ObpSdCacheLock();
ObpSdCacheLock();
/* Make sure we got a descriptor */
if (SecurityDescriptor)
{
/* Get the entry */
CacheEntry = (PSD_CACHE_ENTRY)((ULONG_PTR)SecurityDescriptor -
sizeof(SD_CACHE_ENTRY));
CacheEntry = (PSD_CACHE_ENTRY)((ULONG_PTR)SecurityDescriptor - sizeof(SD_CACHE_ENTRY));
/* Reference it */
CacheEntry->RefCount++;
DPRINT("RefCount %lu\n", CacheEntry->RefCount);
}
CacheEntry->RefCount++;
DPRINT("RefCount %lu\n", CacheEntry->RefCount);
ObpSdCacheUnlock();
DPRINT("ObpReferenceCachedSecurityDescriptor() done\n");
/* Unlock the cache and return the descriptor */
ObpSdCacheUnlock();
return SecurityDescriptor;
}
VOID
NTAPI
ObpDereferenceCachedSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)

View file

@ -117,9 +117,9 @@ ObGetObjectSecurity(IN PVOID Object,
/* Check if the object uses default security */
if (Type->TypeInfo.SecurityProcedure == SeDefaultObjectMethod)
{
/* Reference the descriptor and return it */
ObpReferenceCachedSecurityDescriptor(Header->SecurityDescriptor);
*SecurityDescriptor = Header->SecurityDescriptor;
/* Reference the descriptor */
*SecurityDescriptor =
ObpReferenceCachedSecurityDescriptor(Header->SecurityDescriptor);
/* Tell the caller that we didn't have to allocate anything */
*MemoryAllocated = FALSE;
@ -134,10 +134,10 @@ ObGetObjectSecurity(IN PVOID Object,
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION |
SACL_SECURITY_INFORMATION,
NULL,
*SecurityDescriptor,
&Length,
&Header->SecurityDescriptor,
PagedPool,
Type->TypeInfo.PoolType,
&Type->TypeInfo.GenericMapping);
if (Status != STATUS_BUFFER_TOO_SMALL) return Status;
@ -158,7 +158,7 @@ ObGetObjectSecurity(IN PVOID Object,
*SecurityDescriptor,
&Length,
&Header->SecurityDescriptor,
PagedPool,
Type->TypeInfo.PoolType,
&Type->TypeInfo.GenericMapping);
if (!NT_SUCCESS(Status))
{