- Object Manager Fixes (2 of 3):

* Remove superflous debug prints used a long time ago while debugging
  * Set the CreatorUniqueProcess 
  * Align code to 80 chars
  * Do a privilege check of OB_FLAG_PERMANENT is being used, and de-allocate the object if this failed.
  * Send the PreviousMode to ObpAllocateObject so that it can honor it and set the OB_FLAG_KERNEL_MODE flag.
  * Use OBJECT_TYPE accounting to increase TotalNumberOfObjects.
  * Fail ObCreateObject in low-memory situations instead of ignoring it.
  * Respect OBJECT_TYPE.TypeInfo.InvalidAttributes if an attempt is to create an object with invalid attributes is detected.
  * Respect PagedPoolCharge and NonPagedPoolCharge parameters and save them in the OBJECT_CREATE_INFORMATION strucutre.

svn path=/trunk/; revision=22099
This commit is contained in:
Alex Ionescu 2006-05-29 00:18:36 +00:00
parent 0817ba9198
commit 453c3d0af0
2 changed files with 81 additions and 64 deletions

View file

@ -57,6 +57,9 @@ ObInit(VOID)
/* Initialize the Default Event */ /* Initialize the Default Event */
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE ); KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
/* Setup the Object Reaper */
ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);
/* Create the Type Type */ /* Create the Type Type */
DPRINT("Creating Type Type\n"); DPRINT("Creating Type Type\n");
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));

View file

@ -398,7 +398,6 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes,
return Status; return Status;
} }
VOID VOID
STDCALL STDCALL
ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo) ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
@ -414,12 +413,13 @@ ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
} }
NTSTATUS NTSTATUS
STDCALL NTAPI
ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
PUNICODE_STRING ObjectName, IN PUNICODE_STRING ObjectName,
POBJECT_TYPE ObjectType, IN POBJECT_TYPE ObjectType,
ULONG ObjectSize, IN ULONG ObjectSize,
POBJECT_HEADER *ObjectHeader) IN KPROCESSOR_MODE PreviousMode,
IN POBJECT_HEADER *ObjectHeader)
{ {
POBJECT_HEADER Header; POBJECT_HEADER Header;
BOOLEAN HasHandleInfo = FALSE; BOOLEAN HasHandleInfo = FALSE;
@ -431,9 +431,9 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
POOL_TYPE PoolType; POOL_TYPE PoolType;
ULONG FinalSize = ObjectSize; ULONG FinalSize = ObjectSize;
ULONG Tag; ULONG Tag;
PAGED_CODE();
/* If we don't have an Object Type yet, force NonPaged */ /* If we don't have an Object Type yet, force NonPaged */
DPRINT("ObpAllocateObject\n");
if (!ObjectType) if (!ObjectType)
{ {
PoolType = NonPagedPool; PoolType = NonPagedPool;
@ -445,7 +445,6 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
Tag = ObjectType->Key; Tag = ObjectType->Key;
} }
DPRINT("Checking ObjectName: %x\n", ObjectName);
/* Check if the Object has a name */ /* Check if the Object has a name */
if (ObjectName->Buffer) if (ObjectName->Buffer)
{ {
@ -456,7 +455,6 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
if (ObjectType) if (ObjectType)
{ {
/* Check if the Object maintains handle counts */ /* Check if the Object maintains handle counts */
DPRINT("Checking ObjectType->TypeInfo: %x\n", &ObjectType->TypeInfo);
if (ObjectType->TypeInfo.MaintainHandleCount) if (ObjectType->TypeInfo.MaintainHandleCount)
{ {
FinalSize += sizeof(OBJECT_HEADER_HANDLE_INFO); FinalSize += sizeof(OBJECT_HEADER_HANDLE_INFO);
@ -472,18 +470,13 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
} }
/* Allocate memory for the Object and Header */ /* Allocate memory for the Object and Header */
DPRINT("Allocating: %x %x\n", FinalSize, Tag);
Header = ExAllocatePoolWithTag(PoolType, FinalSize, Tag); Header = ExAllocatePoolWithTag(PoolType, FinalSize, Tag);
if (!Header) { if (!Header) return STATUS_INSUFFICIENT_RESOURCES;
DPRINT1("Not enough memory!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Initialize Handle Info */ /* Initialize Handle Info */
if (HasHandleInfo) if (HasHandleInfo)
{ {
HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header; HandleInfo = (POBJECT_HEADER_HANDLE_INFO)Header;
DPRINT("Info: %x\n", HandleInfo);
HandleInfo->SingleEntry.HandleCount = 0; HandleInfo->SingleEntry.HandleCount = 0;
Header = (POBJECT_HEADER)(HandleInfo + 1); Header = (POBJECT_HEADER)(HandleInfo + 1);
} }
@ -492,7 +485,6 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
if (HasNameInfo) if (HasNameInfo)
{ {
NameInfo = (POBJECT_HEADER_NAME_INFO)Header; NameInfo = (POBJECT_HEADER_NAME_INFO)Header;
DPRINT("Info: %x %wZ\n", NameInfo, ObjectName);
NameInfo->Name = *ObjectName; NameInfo->Name = *ObjectName;
NameInfo->Directory = NULL; NameInfo->Directory = NULL;
Header = (POBJECT_HEADER)(NameInfo + 1); Header = (POBJECT_HEADER)(NameInfo + 1);
@ -502,48 +494,56 @@ ObpAllocateObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo,
if (HasCreatorInfo) if (HasCreatorInfo)
{ {
CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header; CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
DPRINT("Info: %x\n", CreatorInfo); CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcess() ?
/* FIXME: Needs Alex's Init patch PsGetCurrentProcessId() : 0;
* CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcessId();
*/
InitializeListHead(&CreatorInfo->TypeList); InitializeListHead(&CreatorInfo->TypeList);
Header = (POBJECT_HEADER)(CreatorInfo + 1); Header = (POBJECT_HEADER)(CreatorInfo + 1);
} }
/* Initialize the object header */ /* Initialize the object header */
RtlZeroMemory(Header, ObjectSize); RtlZeroMemory(Header, ObjectSize);
DPRINT("Initalized header %p\n", Header);
Header->HandleCount = 0;
Header->PointerCount = 1; Header->PointerCount = 1;
Header->Type = ObjectType; Header->Type = ObjectType;
Header->Flags = OB_FLAG_CREATE_INFO; Header->Flags = OB_FLAG_CREATE_INFO;
Header->ObjectCreateInfo = ObjectCreateInfo;
/* Set the Offsets for the Info */ /* Set the Offsets for the Info */
if (HasHandleInfo) if (HasHandleInfo)
{ {
Header->HandleInfoOffset = HasNameInfo * sizeof(OBJECT_HEADER_NAME_INFO) + Header->HandleInfoOffset = HasNameInfo *
sizeof(OBJECT_HEADER_NAME_INFO) +
sizeof(OBJECT_HEADER_HANDLE_INFO) + sizeof(OBJECT_HEADER_HANDLE_INFO) +
HasCreatorInfo * sizeof(OBJECT_HEADER_CREATOR_INFO); HasCreatorInfo *
sizeof(OBJECT_HEADER_CREATOR_INFO);
/* Set the flag so we know when freeing */
Header->Flags |= OB_FLAG_SINGLE_PROCESS; Header->Flags |= OB_FLAG_SINGLE_PROCESS;
} }
if (HasNameInfo) if (HasNameInfo)
{ {
Header->NameInfoOffset = sizeof(OBJECT_HEADER_NAME_INFO) + Header->NameInfoOffset = sizeof(OBJECT_HEADER_NAME_INFO) +
HasCreatorInfo * sizeof(OBJECT_HEADER_CREATOR_INFO); HasCreatorInfo *
sizeof(OBJECT_HEADER_CREATOR_INFO);
} }
if (HasCreatorInfo) Header->Flags |= OB_FLAG_CREATOR_INFO; if (HasCreatorInfo) Header->Flags |= OB_FLAG_CREATOR_INFO;
if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_PERMANENT))
if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_PERMANENT)
{ {
/* Set the needed flag so we can check */
Header->Flags |= OB_FLAG_PERMANENT; Header->Flags |= OB_FLAG_PERMANENT;
} }
if (ObjectCreateInfo && ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE) if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
{ {
/* Set the needed flag so we can check */
Header->Flags |= OB_FLAG_EXCLUSIVE; Header->Flags |= OB_FLAG_EXCLUSIVE;
} }
if (PreviousMode == KernelMode)
{
/* Set the kernel flag */
Header->Flags |= OB_FLAG_KERNEL_MODE;
}
/* Link stuff to Object Header */ /* Increase the number of objects of this type */
Header->ObjectCreateInfo = ObjectCreateInfo; if (ObjectType) ObjectType->TotalNumberOfObjects++;
/* Return Header */ /* Return Header */
*ObjectHeader = Header; *ObjectHeader = Header;
@ -560,41 +560,34 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
POBJECT_TYPE LocalObjectType; POBJECT_TYPE LocalObjectType;
ULONG HeaderSize; ULONG HeaderSize;
NTSTATUS Status; NTSTATUS Status;
CHAR Tag[4];
OBP_LOOKUP_CONTEXT Context;
DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
/* Allocate the Object */ /* Allocate the Object */
Status = ObpAllocateObject(NULL, Status = ObpAllocateObject(NULL,
TypeName, TypeName,
ObTypeObjectType, ObTypeObjectType,
sizeof(OBJECT_TYPE) + sizeof(OBJECT_HEADER), sizeof(OBJECT_TYPE) + sizeof(OBJECT_HEADER),
KernelMode,
(POBJECT_HEADER*)&Header); (POBJECT_HEADER*)&Header);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status)) return Status;
{
DPRINT1("ObpAllocateObject failed!\n");
return Status;
}
LocalObjectType = (POBJECT_TYPE)&Header->Body; LocalObjectType = (POBJECT_TYPE)&Header->Body;
DPRINT("Local ObjectType: %p Header: %p \n", LocalObjectType, Header);
/* Check if this is the first Object Type */ /* Check if this is the first Object Type */
if (!ObTypeObjectType) if (!ObTypeObjectType)
{ {
ObTypeObjectType = LocalObjectType; ObTypeObjectType = LocalObjectType;
Header->Type = ObTypeObjectType; Header->Type = ObTypeObjectType;
LocalObjectType->TotalNumberOfObjects = 1;
LocalObjectType->Key = TAG('O', 'b', 'j', 'T'); LocalObjectType->Key = TAG('O', 'b', 'j', 'T');
} }
else else
{ {
CHAR Tag[4]; /* Set Tag */
Tag[0] = TypeName->Buffer[0]; Tag[0] = TypeName->Buffer[0];
Tag[1] = TypeName->Buffer[1]; Tag[1] = TypeName->Buffer[1];
Tag[2] = TypeName->Buffer[2]; Tag[2] = TypeName->Buffer[2];
Tag[3] = TypeName->Buffer[3]; Tag[3] = TypeName->Buffer[3];
/* Set Tag */
DPRINT("Convert: %s \n", Tag);
LocalObjectType->Key = *(PULONG)Tag; LocalObjectType->Key = *(PULONG)Tag;
} }
@ -662,7 +655,6 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
/* Insert it into the Object Directory */ /* Insert it into the Object Directory */
if (ObpTypeDirectoryObject) if (ObpTypeDirectoryObject)
{ {
OBP_LOOKUP_CONTEXT Context;
Context.Directory = ObpTypeDirectoryObject; Context.Directory = ObpTypeDirectoryObject;
Context.DirectoryLocked = TRUE; Context.DirectoryLocked = TRUE;
ObpLookupEntryDirectory(ObpTypeDirectoryObject, ObpLookupEntryDirectory(ObpTypeDirectoryObject,
@ -701,46 +693,68 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
Type, ObjectAttributes, Object); Type, ObjectAttributes, Object);
/* Allocate a Buffer for the Object Create Info */ /* Allocate a Buffer for the Object Create Info */
DPRINT("Allocating Create Buffer\n");
ObjectCreateInfo = ExAllocatePoolWithTag(NonPagedPool, ObjectCreateInfo = ExAllocatePoolWithTag(NonPagedPool,
sizeof(*ObjectCreateInfo), sizeof(*ObjectCreateInfo),
TAG('O','b','C', 'I')); TAG('O','b','C', 'I'));
if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
/* Capture all the info */ /* Capture all the info */
DPRINT("Capturing Create Info\n");
Status = ObpCaptureObjectAttributes(ObjectAttributes, Status = ObpCaptureObjectAttributes(ObjectAttributes,
ObjectAttributesAccessMode, ObjectAttributesAccessMode,
Type, Type,
ObjectCreateInfo, ObjectCreateInfo,
&ObjectName); &ObjectName);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
/* Allocate the Object */ /* Validate attributes */
DPRINT("Allocating: %wZ\n", &ObjectName); if (Type->TypeInfo.InvalidAttributes &
Status = ObpAllocateObject(ObjectCreateInfo, ObjectCreateInfo->Attributes)
&ObjectName,
Type,
ObjectSize + sizeof(OBJECT_HEADER),
&Header);
if (NT_SUCCESS(Status))
{ {
/* Return the Object */ /* Fail */
DPRINT("Returning Object\n"); Status = STATUS_INVALID_PARAMETER;
*Object = &Header->Body; }
else
/* Return to caller, leave the Capture Info Alive for ObInsert */ {
return Status; /* Save the pool charges */
ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
/* Allocate the Object */
Status = ObpAllocateObject(ObjectCreateInfo,
&ObjectName,
Type,
ObjectSize + sizeof(OBJECT_HEADER),
AccessMode,
&Header);
if (NT_SUCCESS(Status))
{
/* Return the Object */
*Object = &Header->Body;
/* Check if this is a permanent object */
if (Header->Flags & OB_FLAG_PERMANENT)
{
/* Do the privilege check */
if (!SeSinglePrivilegeCheck(SeCreatePermanentPrivilege,
ObjectAttributesAccessMode))
{
/* Fail */
ObpDeallocateObject(*Object);
Status = STATUS_PRIVILEGE_NOT_HELD;
}
}
/* Return status */
return Status;
}
} }
/* Release the Capture Info, we don't need it */ /* Release the Capture Info, we don't need it */
DPRINT1("Allocation failed\n");
ObpReleaseCapturedAttributes(ObjectCreateInfo); ObpReleaseCapturedAttributes(ObjectCreateInfo);
if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
} }
/* We failed, so release the Buffer */ /* We failed, so release the Buffer */
DPRINT1("Capture failed\n");
ExFreePool(ObjectCreateInfo); ExFreePool(ObjectCreateInfo);
return Status; return Status;
} }