From a3abeb83af0f72707be40b7db800926df0459c92 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Mon, 8 Aug 2005 15:39:35 +0000 Subject: [PATCH] - reverted ObpCaptureObjectAttributes back to my old implementation (slightly modified and extended) because that one at least does what it's supposed to correctly svn path=/trunk/; revision=17205 --- reactos/ntoskrnl/cm/ntfunc.c | 28 +- reactos/ntoskrnl/cm/registry.c | 9 +- reactos/ntoskrnl/include/internal/ob.h | 23 +- reactos/ntoskrnl/lpc/connect.c | 4 +- reactos/ntoskrnl/ob/handle.c | 7 +- reactos/ntoskrnl/ob/namespc.c | 48 +++- reactos/ntoskrnl/ob/object.c | 372 +++++++++++++++++-------- 7 files changed, 333 insertions(+), 158 deletions(-) diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 77697c1bf1e..642dba47c86 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -192,20 +192,19 @@ NtCreateKey(OUT PHANDLE KeyHandle, PWSTR Start; UNICODE_STRING ObjectName; OBJECT_CREATE_INFORMATION ObjectCreateInfo; + KPROCESSOR_MODE PreviousMode; unsigned i; PAGED_CODE(); - - DPRINT("NtCreateKey (Name %wZ KeyHandle 0x%p Root 0x%p)\n", - ObjectAttributes->ObjectName, - KeyHandle, - ObjectAttributes->RootDirectory); + + PreviousMode = KeGetPreviousMode(); /* Capture all the info */ DPRINT("Capturing Create Info\n"); Status = ObpCaptureObjectAttributes(ObjectAttributes, - KeGetPreviousMode(), - CmiKeyType, + PreviousMode, + PagedPool, + FALSE, &ObjectCreateInfo, &ObjectName); if (!NT_SUCCESS(Status)) @@ -219,8 +218,10 @@ NtCreateKey(OUT PHANDLE KeyHandle, (PVOID*)&Object, &RemainingPath, CmiKeyType); - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + ObpReleaseCapturedAttributes(&ObjectCreateInfo, + &ObjectName, + PreviousMode, + FALSE); if (!NT_SUCCESS(Status)) { DPRINT("CmpFindObject failed, Status: 0x%x\n", Status); @@ -1169,7 +1170,8 @@ NtOpenKey(OUT PHANDLE KeyHandle, DPRINT("Capturing Create Info\n"); Status = ObpCaptureObjectAttributes(ObjectAttributes, PreviousMode, - CmiKeyType, + PagedPool, + FALSE, &ObjectCreateInfo, &ObjectName); if (!NT_SUCCESS(Status)) @@ -1185,8 +1187,10 @@ NtOpenKey(OUT PHANDLE KeyHandle, (PVOID*)&Object, &RemainingPath, CmiKeyType); - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + ObpReleaseCapturedAttributes(&ObjectCreateInfo, + &ObjectName, + PreviousMode, + FALSE); if (!NT_SUCCESS(Status)) { DPRINT("CmpFindObject() returned 0x%08lx\n", Status); diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index c328abe37d3..65019a2f73c 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -705,7 +705,8 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, DPRINT("Capturing Create Info\n"); Status = ObpCaptureObjectAttributes(KeyObjectAttributes, KernelMode, - CmiKeyType, + PagedPool, + FALSE, &ObjectCreateInfo, &ObjectName); if (!NT_SUCCESS(Status)) @@ -719,8 +720,10 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, (PVOID*)&ParentKey, &RemainingPath, CmiKeyType); - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + ObpReleaseCapturedAttributes(&ObjectCreateInfo, + &ObjectName, + KernelMode, + FALSE); if (!NT_SUCCESS(Status)) { return Status; diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index cf696be818a..3438dfa57b1 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -173,14 +173,6 @@ ObFastDereferenceObject(IN PEX_FAST_REF FastRef, /* Secure object information functions */ -typedef struct _CAPTURED_OBJECT_ATTRIBUTES -{ - HANDLE RootDirectory; - ULONG Attributes; - PSECURITY_DESCRIPTOR SecurityDescriptor; - PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; -} CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES; - NTSTATUS STDCALL ObpCaptureObjectName(IN PUNICODE_STRING CapturedName, @@ -189,16 +181,19 @@ ObpCaptureObjectName(IN PUNICODE_STRING CapturedName, NTSTATUS STDCALL -ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes, +ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, - IN POBJECT_TYPE ObjectType, - IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, - OUT PUNICODE_STRING ObjectName); + IN POOL_TYPE PoolType, + IN BOOLEAN CaptureIfKernel, + OUT POBJECT_CREATE_INFORMATION CapturedObjectAttributes OPTIONAL, + OUT PUNICODE_STRING ObjectName OPTIONAL); VOID STDCALL -ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo); - +ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION CapturedObjectAttributes OPTIONAL, + IN PUNICODE_STRING ObjectName OPTIONAL, + IN KPROCESSOR_MODE AccessMode, + IN BOOLEAN CaptureIfKernel); /* object information classes */ #define ICIF_QUERY 0x1 diff --git a/reactos/ntoskrnl/lpc/connect.c b/reactos/ntoskrnl/lpc/connect.c index 7afa196abe8..95fec58aa14 100644 --- a/reactos/ntoskrnl/lpc/connect.c +++ b/reactos/ntoskrnl/lpc/connect.c @@ -410,7 +410,7 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle, NULL, PORT_ALL_ACCESS, /* DesiredAccess */ LpcPortObjectType, - UserMode, + PreviousMode, NULL, (PVOID*)&NamedPort); if (!NT_SUCCESS(Status)) @@ -430,7 +430,7 @@ NtConnectPort (PHANDLE UnsafeConnectedPortHandle, Status = ObReferenceObjectByHandle(WriteMap.SectionHandle, SECTION_MAP_READ | SECTION_MAP_WRITE, MmSectionObjectType, - UserMode, + PreviousMode, (PVOID*)&SectionObject, NULL); if (!NT_SUCCESS(Status)) diff --git a/reactos/ntoskrnl/ob/handle.c b/reactos/ntoskrnl/ob/handle.c index e4e8cae3b7f..4b23ef31246 100644 --- a/reactos/ntoskrnl/ob/handle.c +++ b/reactos/ntoskrnl/ob/handle.c @@ -955,7 +955,7 @@ ObInsertObject(IN PVOID Object, /* First try to find the Object */ if (ObjectNameInfo && ObjectNameInfo->Name.Buffer) { - DPRINT("Object has a name. Trying to find it: %wZ.\n", &ObjectNameInfo->Name); + DPRINT("Object has a name. Trying to find it: \"%wZ\".\n", &ObjectNameInfo->Name); Status = ObFindObject(ObjectCreateInfo, &ObjectNameInfo->Name, &FoundObject, @@ -1132,7 +1132,10 @@ ObInsertObject(IN PVOID Object, /* We can delete the Create Info now */ Header->ObjectCreateInfo = NULL; - ObpReleaseCapturedAttributes(ObjectCreateInfo); + ObpReleaseCapturedAttributes(ObjectCreateInfo, + NULL, + ObjectCreateInfo->ProbeMode, + FALSE); ExFreePool(ObjectCreateInfo); DPRINT("Status %x\n", Status); diff --git a/reactos/ntoskrnl/ob/namespc.c b/reactos/ntoskrnl/ob/namespc.c index df73bfe6272..fca5a3c79d0 100644 --- a/reactos/ntoskrnl/ob/namespc.c +++ b/reactos/ntoskrnl/ob/namespc.c @@ -70,20 +70,35 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath, NTSTATUS Status; PAGED_CODE(); + + /* capture the ObjectPath */ + Status = RtlCaptureUnicodeString(&ObjectName, + AccessMode, + NonPagedPool, /* FIXME */ + FALSE, + ObjectPath); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlCaptureUnicodeString() failed (Status %lx)\n", Status); + return Status; + } InitializeObjectAttributes(&ObjectAttributes, - ObjectPath, + &ObjectName, Attributes | OBJ_OPENIF, NULL, NULL); - /* Capture all the info */ + /* "Capture" all the info, it doesn't make sense to capture from the kernel + stack as the information should be safe anyway...just do a raw copy of the + data into the OBJECT_CREATE_INFORMATION structure */ DPRINT("Capturing Create Info\n"); Status = ObpCaptureObjectAttributes(&ObjectAttributes, - AccessMode, - ObjectType, + KernelMode, /* raw copy! */ + NonPagedPool, + FALSE, &ObjectCreateInfo, - &ObjectName); + NULL); if (!NT_SUCCESS(Status)) { DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status); @@ -96,8 +111,18 @@ ObReferenceObjectByName(PUNICODE_STRING ObjectPath, &RemainingPath, ObjectType); - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + /* we don't need to release the "captured" object attributes! Nothing was allocated! */ +#if 0 + ObpReleaseCapturedAttributes(&ObjectCreateInfo, + NULL, + AccessMode, + FALSE); +#endif + + /* free the captured ObjectPath if needed */ + RtlReleaseCapturedUnicodeString(&ObjectName, + AccessMode, + FALSE); if (!NT_SUCCESS(Status)) { @@ -169,7 +194,8 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, DPRINT("Capturing Create Info\n"); Status = ObpCaptureObjectAttributes(ObjectAttributes, AccessMode, - ObjectType, + PagedPool, + FALSE, &ObjectCreateInfo, &ObjectName); if (!NT_SUCCESS(Status)) @@ -183,8 +209,10 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, &Object, &RemainingPath, ObjectType); - ObpReleaseCapturedAttributes(&ObjectCreateInfo); - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + ObpReleaseCapturedAttributes(&ObjectCreateInfo, + &ObjectName, + AccessMode, + FALSE); if (!NT_SUCCESS(Status)) { DPRINT("ObFindObject() failed (Status %lx)\n", Status); diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index 2467fd0f8e1..68eb5fb0d2b 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -110,162 +110,298 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName, NTSTATUS STDCALL -ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes, +ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, - IN POBJECT_TYPE ObjectType, - IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, - OUT PUNICODE_STRING ObjectName) + IN POOL_TYPE PoolType, + IN BOOLEAN CaptureIfKernel, + OUT POBJECT_CREATE_INFORMATION CapturedObjectAttributes OPTIONAL, + OUT PUNICODE_STRING ObjectName OPTIONAL) { + OBJECT_ATTRIBUTES AttributesCopy; NTSTATUS Status = STATUS_SUCCESS; - PSECURITY_DESCRIPTOR SecurityDescriptor; - PSECURITY_QUALITY_OF_SERVICE SecurityQos; - PUNICODE_STRING LocalObjectName = NULL; - /* Zero out the Capture Data */ - DPRINT("ObpCaptureObjectAttributes\n"); - RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION)); - - /* Check if we got Oba */ - if (ObjectAttributes) + /* at least one output parameter must be != NULL! */ + ASSERT(CapturedObjectAttributes != NULL || ObjectName != NULL); + + if (ObjectAttributes == NULL) { - if (AccessMode != KernelMode) - { - DPRINT("Probing OBA\n"); - _SEH_TRY - { - /* FIXME: SMSS SENDS BULLSHIT. */ - #if 0 - ProbeForRead(ObjectAttributes, - sizeof(ObjectAttributes), - sizeof(ULONG)); - #endif - } - _SEH_HANDLE - { - Status = _SEH_GetExceptionCode(); - } - _SEH_END; - } - - /* Validate the Size */ - DPRINT("Validating OBA\n"); - if (ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES)) - { - Status = STATUS_INVALID_PARAMETER; - } + /* we're going to return STATUS_SUCCESS! */ + goto failbasiccleanup; + } + + if (AccessMode != KernelMode) + { + _SEH_TRY + { + ProbeForRead(ObjectAttributes, + sizeof(ObjectAttributes), + sizeof(ULONG)); + /* make a copy on the stack */ + AttributesCopy = *ObjectAttributes; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; - /* Fail if SEH or Size Validation failed */ if(!NT_SUCCESS(Status)) { - DPRINT1("ObpCaptureObjectAttributes failed to probe object attributes\n"); - goto fail; + DPRINT1("ObpCaptureObjectAttributes failed to probe object attributes 0x%p\n", ObjectAttributes); + KEBUGCHECK(0); + goto failbasiccleanup; } - - /* Set some Create Info */ - DPRINT("Creating OBCI\n"); - ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory; - ObjectCreateInfo->Attributes = ObjectAttributes->Attributes; - LocalObjectName = ObjectAttributes->ObjectName; - SecurityDescriptor = ObjectAttributes->SecurityDescriptor; - SecurityQos = ObjectAttributes->SecurityQualityOfService; - - /* Validate the SD */ - if (SecurityDescriptor) + } + else if (!CaptureIfKernel) + { + if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) { - DPRINT("Probing SD: %x\n", SecurityDescriptor); - Status = SeCaptureSecurityDescriptor(SecurityDescriptor, + if (ObjectName != NULL) + { + /* we don't have to capture any memory, the caller considers the passed data + as valid */ + if (ObjectAttributes->ObjectName != NULL) + { + *ObjectName = *ObjectAttributes->ObjectName; + } + else + { + ObjectName->Length = ObjectName->MaximumLength = 0; + ObjectName->Buffer = NULL; + } + } + if (CapturedObjectAttributes != NULL) + { + CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory; + CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes; + CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor; + CapturedObjectAttributes->SecurityDescriptorCharge = 0; /* FIXME */ + CapturedObjectAttributes->ProbeMode = AccessMode; + } + + return STATUS_SUCCESS; + } + else + { + Status = STATUS_INVALID_PARAMETER; + goto failbasiccleanup; + } + } + else + { + AttributesCopy = *ObjectAttributes; + } + + /* if Length isn't as expected, bail with an invalid parameter status code so + the caller knows he passed garbage... */ + if (AttributesCopy.Length != sizeof(OBJECT_ATTRIBUTES)) + { + Status = STATUS_INVALID_PARAMETER; + goto failbasiccleanup; + } + + if (CapturedObjectAttributes != NULL) + { + CapturedObjectAttributes->RootDirectory = AttributesCopy.RootDirectory; + CapturedObjectAttributes->Attributes = AttributesCopy.Attributes; + + if (AttributesCopy.SecurityDescriptor != NULL) + { + Status = SeCaptureSecurityDescriptor(AttributesCopy.SecurityDescriptor, AccessMode, - NonPagedPool, + PoolType, TRUE, - &ObjectCreateInfo->SecurityDescriptor); - if(!NT_SUCCESS(Status)) + &CapturedObjectAttributes->SecurityDescriptor); + if (!NT_SUCCESS(Status)) { DPRINT1("Unable to capture the security descriptor!!!\n"); - ObjectCreateInfo->SecurityDescriptor = NULL; - goto fail; + goto failbasiccleanup; } - - DPRINT("Probe done\n"); - ObjectCreateInfo->SecurityDescriptorCharge = 0; /* FIXME */ - ObjectCreateInfo->ProbeMode = AccessMode; + CapturedObjectAttributes->SecurityDescriptorCharge = 0; /* FIXME */ } - - /* Validate the QoS */ - if (SecurityQos) + else { + CapturedObjectAttributes->SecurityDescriptor = NULL; + CapturedObjectAttributes->SecurityDescriptorCharge = 0; + } + } + + if (ObjectName != NULL) + { + ObjectName->Buffer = NULL; + + if (AttributesCopy.ObjectName != NULL) + { + UNICODE_STRING OriginalCopy = {0}; + if (AccessMode != KernelMode) { - DPRINT("Probing QoS\n"); _SEH_TRY { - ProbeForRead(SecurityQos, - sizeof(SECURITY_QUALITY_OF_SERVICE), + /* probe the ObjectName structure and make a local stack copy of it */ + ProbeForRead(AttributesCopy.ObjectName, + sizeof(UNICODE_STRING), sizeof(ULONG)); + OriginalCopy = *AttributesCopy.ObjectName; + if (OriginalCopy.Length > 0) + { + ProbeForRead(OriginalCopy.Buffer, + OriginalCopy.Length, + sizeof(WCHAR)); + } } _SEH_HANDLE { Status = _SEH_GetExceptionCode(); } _SEH_END; - } - if(!NT_SUCCESS(Status)) - { - DPRINT1("Unable to capture QoS!!!\n"); - goto fail; + if (NT_SUCCESS(Status)) + { + ObjectName->Length = OriginalCopy.Length; + + if(OriginalCopy.Length > 0) + { + ObjectName->MaximumLength = OriginalCopy.Length + sizeof(WCHAR); + ObjectName->Buffer = ExAllocatePool(PoolType, + ObjectName->MaximumLength); + if (ObjectName->Buffer != NULL) + { + _SEH_TRY + { + /* no need to probe OriginalCopy.Buffer again, we already did that + when capturing the UNICODE_STRING structure itself */ + RtlCopyMemory(ObjectName->Buffer, OriginalCopy.Buffer, OriginalCopy.Length); + ObjectName->Buffer[OriginalCopy.Length / sizeof(WCHAR)] = L'\0'; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + + if (!NT_SUCCESS(Status)) + { + DPRINT1("ObpCaptureObjectAttributes failed to copy the unicode string!\n"); + } + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + else if(AttributesCopy.RootDirectory != NULL /* && OriginalCopy.Length == 0 */) + { + /* if the caller specified a root directory, there must be an object name! */ + Status = STATUS_OBJECT_NAME_INVALID; + } + else + { + ObjectName->Length = ObjectName->MaximumLength = 0; + } + } +#ifdef DBG + else + { + DPRINT1("ObpCaptureObjectAttributes failed to probe the object name UNICODE_STRING structure!\n"); + } +#endif + } + else /* AccessMode == KernelMode */ + { + OriginalCopy = *AttributesCopy.ObjectName; + ObjectName->Length = OriginalCopy.Length; + + if (OriginalCopy.Length > 0) + { + ObjectName->MaximumLength = OriginalCopy.Length + sizeof(WCHAR); + ObjectName->Buffer = ExAllocatePool(PoolType, + ObjectName->MaximumLength); + if (ObjectName->Buffer != NULL) + { + RtlCopyMemory(ObjectName->Buffer, OriginalCopy.Buffer, OriginalCopy.Length); + ObjectName->Buffer[OriginalCopy.Length / sizeof(WCHAR)] = L'\0'; + } + else + { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + else if (AttributesCopy.RootDirectory != NULL /* && OriginalCopy.Length == 0 */) + { + /* if the caller specified a root directory, there must be an object name! */ + Status = STATUS_OBJECT_NAME_INVALID; + } + else + { + ObjectName->Length = ObjectName->MaximumLength = 0; + } } - - ObjectCreateInfo->SecurityQualityOfService = *SecurityQos; - ObjectCreateInfo->SecurityQos = &ObjectCreateInfo->SecurityQualityOfService; } - } - - /* Clear Local Object Name */ - DPRINT("Clearing name\n"); - RtlZeroMemory(ObjectName, sizeof(UNICODE_STRING)); - - /* Now check if the Object Attributes had an Object Name */ - if (LocalObjectName) - { - DPRINT("Name Buffer: %x\n", LocalObjectName->Buffer); - Status = ObpCaptureObjectName(ObjectName, - LocalObjectName, - AccessMode); - } - else - { - /* He can't have specified a Root Directory */ - if (ObjectCreateInfo->RootDirectory) + else { - DPRINT1("Invalid name\n"); - Status = STATUS_OBJECT_NAME_INVALID; + ObjectName->Length = ObjectName->MaximumLength = 0; } } -fail: + CapturedObjectAttributes->ProbeMode = AccessMode; + if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to capture, cleaning up\n"); - ObpReleaseCapturedAttributes(ObjectCreateInfo); + if (ObjectName->Buffer) + { + ExFreePool(ObjectName->Buffer); + } + if (CapturedObjectAttributes != NULL) + { + /* cleanup allocated resources */ + SeReleaseSecurityDescriptor(CapturedObjectAttributes->SecurityDescriptor, + AccessMode, + TRUE); + } + +failbasiccleanup: + if (ObjectName != NULL) + { + ObjectName->Length = ObjectName->MaximumLength = 0; + ObjectName->Buffer = NULL; + } + if (CapturedObjectAttributes != NULL) + { + RtlZeroMemory(CapturedObjectAttributes, sizeof(OBJECT_CREATE_INFORMATION)); + } } - - DPRINT("Return to caller\n"); + return Status; } VOID STDCALL -ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo) +ObpReleaseCapturedAttributes(IN POBJECT_CREATE_INFORMATION CapturedObjectAttributes OPTIONAL, + IN PUNICODE_STRING ObjectName OPTIONAL, + IN KPROCESSOR_MODE AccessMode, + IN BOOLEAN CaptureIfKernel) { - /* Release the SD, it's the only thing we allocated */ - if (ObjectCreateInfo->SecurityDescriptor) + /* WARNING - You need to pass the same parameters to this function as you passed + to ObpCaptureObjectAttributes() to avoid memory leaks */ + if(AccessMode != KernelMode || CaptureIfKernel) + { + if(CapturedObjectAttributes != NULL && + CapturedObjectAttributes->SecurityDescriptor != NULL) { - SeReleaseSecurityDescriptor(ObjectCreateInfo->SecurityDescriptor, - ObjectCreateInfo->ProbeMode, - TRUE); - ObjectCreateInfo->SecurityDescriptor = NULL; + ExFreePool(CapturedObjectAttributes->SecurityDescriptor); + +#ifdef DBG + RtlZeroMemory(CapturedObjectAttributes, sizeof(OBJECT_CREATE_INFORMATION)); +#endif } + if(ObjectName != NULL && + ObjectName->Length > 0) + { + ExFreePool(ObjectName->Buffer); + } + } } @@ -348,7 +484,7 @@ ObFindObject(POBJECT_CREATE_INFORMATION ObjectCreateInfo, ObjectName->Buffer[0] != L'\\') { ObDereferenceObject (CurrentObject); - DPRINT1("failed\n"); + DPRINT1("failed: \"%wZ\"\n", ObjectName); return STATUS_UNSUCCESSFUL; } @@ -795,8 +931,9 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL, /* Capture all the info */ DPRINT("Capturing Create Info\n"); Status = ObpCaptureObjectAttributes(ObjectAttributes, - AccessMode, - Type, + ObjectAttributesAccessMode, + NonPagedPool, + TRUE, ObjectCreateInfo, &ObjectName); @@ -822,8 +959,10 @@ ObCreateObject(IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL, /* Release the Capture Info, we don't need it */ DPRINT1("Allocation failed\n"); - ObpReleaseCapturedAttributes(ObjectCreateInfo); - if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer); + ObpReleaseCapturedAttributes(ObjectCreateInfo, + &ObjectName, + ObjectAttributesAccessMode, + TRUE); } /* We failed, so release the Buffer */ @@ -977,7 +1116,10 @@ ObpDeleteObject(POBJECT_HEADER Header) } if (Header->ObjectCreateInfo) { - ObpReleaseCapturedAttributes(Header->ObjectCreateInfo); + ObpReleaseCapturedAttributes(Header->ObjectCreateInfo, + NULL, + Header->ObjectCreateInfo->ProbeMode, + FALSE); ExFreePool(Header->ObjectCreateInfo); }