[22 bugfixes]:

- ObpReferenceProcessObjectByHandle is always called with HandleInformation, remove this check.
- ObpReferenceProcessObjectByHandle already gets a process parameter, don't query the current one.
- ObpReferenceProcessObjectByHandle already gets a handle table, don't query the current one.
- ObpDecrementHandleCount shouldn't remove the object from the creator info.
- ObpDecrementHandleCount should clear the exclusive process if this is the last handle.
- Killing a protected handle should raise an exception if a debug port is connected, not an exception port.
- ObpIncrementHandleCount should support OBJ_FORCE_ACCESS_CHECK.
- ObpIncrementHandleCount needs to support ObDuplicateHandle.
- ObpIncrementHandleCount needs to support being called without an AccessState.
- Fix interlocked handle count accounting.
- Allow user-mode to create kernel-mode handles.
- Fix the way Additional reference bias is de-referenced during failures.
- Complete rundown in ObKillProcess.
- Send SourceProcess in ObDuplicateHandle.
- Assume initial failure and clear handle in ObDuplicateHandle.
- Don't leak object table references when failing in ObDuplicateHandle.
- Assume failure in ObOpenObjectByName.
- Don't leak buffer during failure in ObOpenObjectByName.
- Don't leak object reference durning failure in ObOpenObjecByName.
- Validate handle attributes in ObOpenObjectByPointer.
- Use RtlCopyMemory when possible to speed up.

svn path=/trunk/; revision=25467
This commit is contained in:
Alex Ionescu 2007-01-15 18:37:53 +00:00
parent 3bd87918a1
commit 4e9c7cf7e4

View file

@ -60,14 +60,14 @@ ObpReferenceProcessObjectByHandle(IN HANDLE Handle,
IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE HandleTable,
IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE AccessMode,
OUT PVOID *Object, OUT PVOID *Object,
OUT POBJECT_HANDLE_INFORMATION HandleInformation) OUT POBJECT_HANDLE_INFORMATION HandleInformation,
OUT PACCESS_MASK AuditMask)
{ {
PHANDLE_TABLE_ENTRY HandleEntry; PHANDLE_TABLE_ENTRY HandleEntry;
POBJECT_HEADER ObjectHeader; POBJECT_HEADER ObjectHeader;
ACCESS_MASK GrantedAccess; ACCESS_MASK GrantedAccess;
ULONG Attributes; ULONG Attributes;
PEPROCESS CurrentProcess; PETHREAD Thread = PsGetCurrentThread();
PETHREAD CurrentThread;
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
@ -77,46 +77,40 @@ ObpReferenceProcessObjectByHandle(IN HANDLE Handle,
/* Check if the caller wants the current process */ /* Check if the caller wants the current process */
if (Handle == NtCurrentProcess()) if (Handle == NtCurrentProcess())
{ {
/* Get the current process */ /* Return handle info */
CurrentProcess = PsGetCurrentProcess(); HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = Process->GrantedAccess;
/* Check if the caller wanted handle information */ /* No audit mask */
if (HandleInformation) *AuditMask = 0;
{
/* Return it */
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = Process->GrantedAccess;
}
/* Reference ourselves */ /* Reference ourselves */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentProcess); ObjectHeader = OBJECT_TO_OBJECT_HEADER(Process);
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1); InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
/* Return the pointer */ /* Return the pointer */
*Object = CurrentProcess; *Object = Process;
ASSERT(*Object != NULL);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/* Check if the caller wants the current thread */ /* Check if the caller wants the current thread */
if (Handle == NtCurrentThread()) if (Handle == NtCurrentThread())
{ {
/* Get the current thread */ /* Return handle information */
CurrentThread = PsGetCurrentThread(); HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = Thread->GrantedAccess;
/* Check if the caller wanted handle information */
if (HandleInformation)
{
/* Return it */
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = CurrentThread->GrantedAccess;
}
/* Reference ourselves */ /* Reference ourselves */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentThread); ObjectHeader = OBJECT_TO_OBJECT_HEADER(Thread);
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1); InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
/* No audit mask */
*AuditMask = 0;
/* Return the pointer */ /* Return the pointer */
*Object = CurrentThread; *Object = Thread;
ASSERT(*Object != NULL);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -127,11 +121,6 @@ ObpReferenceProcessObjectByHandle(IN HANDLE Handle,
Handle = ObKernelHandleToHandle(Handle); Handle = ObKernelHandleToHandle(Handle);
HandleTable = ObpKernelHandleTable; HandleTable = ObpKernelHandleTable;
} }
else
{
/* Otherwise use this process's handle table */
HandleTable = PsGetCurrentProcess()->ObjectTable;
}
/* Enter a critical region while we touch the handle table */ /* Enter a critical region while we touch the handle table */
ASSERT(HandleTable != NULL); ASSERT(HandleTable != NULL);
@ -157,6 +146,9 @@ ObpReferenceProcessObjectByHandle(IN HANDLE Handle,
HandleInformation->HandleAttributes = Attributes; HandleInformation->HandleAttributes = Attributes;
HandleInformation->GrantedAccess = GrantedAccess; HandleInformation->GrantedAccess = GrantedAccess;
/* No audit mask (FIXME!) */
*AuditMask = 0;
/* Return the pointer */ /* Return the pointer */
*Object = &ObjectHeader->Body; *Object = &ObjectHeader->Body;
@ -244,7 +236,7 @@ ObpInsertHandleCount(IN POBJECT_HEADER ObjectHeader)
if (!HandleDatabase) return NULL; if (!HandleDatabase) return NULL;
/* Copy the old database */ /* Copy the old database */
RtlMoveMemory(HandleDatabase, OldHandleDatabase, OldSize); RtlCopyMemory(HandleDatabase, OldHandleDatabase, OldSize);
/* Check if we he had a single entry before */ /* Check if we he had a single entry before */
if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS) if (ObjectHeader->Flags & OB_FLAG_SINGLE_PROCESS)
@ -440,12 +432,12 @@ ObpDecrementHandleCount(IN PVOID ObjectBody,
POBJECT_TYPE ObjectType; POBJECT_TYPE ObjectType;
LONG SystemHandleCount, ProcessHandleCount; LONG SystemHandleCount, ProcessHandleCount;
LONG NewCount; LONG NewCount;
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
KIRQL CalloutIrql; KIRQL CalloutIrql;
POBJECT_HEADER_HANDLE_INFO HandleInfo; POBJECT_HEADER_HANDLE_INFO HandleInfo;
POBJECT_HANDLE_COUNT_ENTRY HandleEntry; POBJECT_HANDLE_COUNT_ENTRY HandleEntry;
POBJECT_HANDLE_COUNT_DATABASE HandleDatabase; POBJECT_HANDLE_COUNT_DATABASE HandleDatabase;
ULONG i; ULONG i;
PAGED_CODE();
/* Get the object type and header */ /* Get the object type and header */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody); ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
@ -467,17 +459,11 @@ ObpDecrementHandleCount(IN PVOID ObjectBody,
/* Decrement the handle count */ /* Decrement the handle count */
NewCount = InterlockedDecrement(&ObjectHeader->HandleCount); NewCount = InterlockedDecrement(&ObjectHeader->HandleCount);
/* Check if we're out of handles */ /* Check if we're out of handles and this was an exclusive object */
if (!NewCount) if (!(NewCount) && (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE))
{ {
/* Get the creator info */ /* Clear the exclusive flag */
CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader); OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = NULL;
if ((CreatorInfo) && !(IsListEmpty(&CreatorInfo->TypeList)))
{
/* Remove it from the list and re-initialize it */
RemoveEntryList(&CreatorInfo->TypeList);
InitializeListHead(&CreatorInfo->TypeList);
}
} }
/* Is the object type keeping track of handles? */ /* Is the object type keeping track of handles? */
@ -644,8 +630,8 @@ ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable,
/* We are! Unlock the entry */ /* We are! Unlock the entry */
ExUnlockHandleTableEntry(HandleTable, HandleEntry); ExUnlockHandleTableEntry(HandleTable, HandleEntry);
/* Make sure we have an exception port */ /* Make sure we have a debug port */
if (PsGetCurrentProcess()->ExceptionPort) if (PsGetCurrentProcess()->DebugPort)
{ {
/* Raise an exception */ /* Raise an exception */
return KeRaiseUserException(STATUS_HANDLE_NOT_CLOSABLE); return KeRaiseUserException(STATUS_HANDLE_NOT_CLOSABLE);
@ -656,10 +642,11 @@ ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable,
return STATUS_HANDLE_NOT_CLOSABLE; return STATUS_HANDLE_NOT_CLOSABLE;
} }
} }
else
/* Otherwise, we are kernel mode, so unlock the entry and return */ {
ExUnlockHandleTableEntry(HandleTable, HandleEntry); /* Otherwise, bugcheck the OS */
return STATUS_HANDLE_NOT_CLOSABLE; KeBugCheckEx(0x8B, (ULONG_PTR)Handle, 0, 0, 0);
}
} }
/* Destroy and unlock the handle entry */ /* Destroy and unlock the handle entry */
@ -727,6 +714,8 @@ ObpIncrementHandleCount(IN PVOID Object,
BOOLEAN Exclusive = FALSE, NewObject; BOOLEAN Exclusive = FALSE, NewObject;
POBJECT_HEADER_CREATOR_INFO CreatorInfo; POBJECT_HEADER_CREATOR_INFO CreatorInfo;
KIRQL CalloutIrql; KIRQL CalloutIrql;
KPROCESSOR_MODE ProbeMode;
ULONG Total;
/* Get the object header and type */ /* Get the object header and type */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
@ -739,6 +728,18 @@ ObpIncrementHandleCount(IN PVOID Object,
ObjectHeader->HandleCount, ObjectHeader->HandleCount,
ObjectHeader->PointerCount); ObjectHeader->PointerCount);
/* Check if caller is forcing user mode */
if (HandleAttributes & OBJ_FORCE_ACCESS_CHECK)
{
/* Force it */
ProbeMode = UserMode;
}
else
{
/* Keep original setting */
ProbeMode = AccessMode;
}
/* Lock the object type */ /* Lock the object type */
ObpEnterObjectTypeMutex(ObjectType); ObpEnterObjectTypeMutex(ObjectType);
@ -797,7 +798,8 @@ ObpIncrementHandleCount(IN PVOID Object,
} }
/* Check if we're opening an existing handle */ /* Check if we're opening an existing handle */
if (OpenReason == ObOpenHandle) if ((OpenReason == ObOpenHandle) ||
((OpenReason == ObDuplicateHandle) && (AccessState)))
{ {
/* Validate the caller's access to this object */ /* Validate the caller's access to this object */
if (!ObCheckObjectAccess(Object, if (!ObCheckObjectAccess(Object,
@ -875,7 +877,10 @@ ObpIncrementHandleCount(IN PVOID Object,
Status = ObjectType->TypeInfo.OpenProcedure(OpenReason, Status = ObjectType->TypeInfo.OpenProcedure(OpenReason,
Process, Process,
Object, Object,
AccessState->PreviouslyGrantedAccess, AccessState ?
AccessState->
PreviouslyGrantedAccess :
0,
ProcessHandleCount); ProcessHandleCount);
ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object); ObpCalloutEnd(CalloutIrql, "Open", ObjectType, Object);
@ -889,26 +894,30 @@ ObpIncrementHandleCount(IN PVOID Object,
} }
} }
/* Check if we have creator info */ /* Check if this is a create operation */
CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader); if (OpenReason == ObCreateHandle)
if (CreatorInfo)
{ {
/* We do, acquire the lock */ /* Check if we have creator info */
ObpEnterObjectTypeMutex(ObjectType); CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(ObjectHeader);
if (CreatorInfo)
{
/* We do, acquire the lock */
ObpEnterObjectTypeMutex(ObjectType);
/* Insert us on the list */ /* Insert us on the list */
InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList); InsertTailList(&ObjectType->TypeList, &CreatorInfo->TypeList);
/* Release the lock */ /* Release the lock */
ObpLeaveObjectTypeMutex(ObjectType); ObpLeaveObjectTypeMutex(ObjectType);
}
} }
/* Increase total number of handles */ /* Increase total number of handles */
InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles); Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
if (ObjectType->TotalNumberOfHandles > ObjectType->HighWaterNumberOfHandles) if (Total > ObjectType->HighWaterNumberOfHandles)
{ {
/* Fixup count */ /* Fixup count */
ObjectType->HighWaterNumberOfHandles = ObjectType->TotalNumberOfHandles; ObjectType->HighWaterNumberOfHandles = Total;
} }
/* Trace call and return */ /* Trace call and return */
@ -971,6 +980,7 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object,
BOOLEAN Exclusive = FALSE, NewObject; BOOLEAN Exclusive = FALSE, NewObject;
POBJECT_HEADER_CREATOR_INFO CreatorInfo; POBJECT_HEADER_CREATOR_INFO CreatorInfo;
KIRQL CalloutIrql; KIRQL CalloutIrql;
ULONG Total;
/* Get the object header and type */ /* Get the object header and type */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
@ -1123,11 +1133,11 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object,
} }
/* Increase total number of handles */ /* Increase total number of handles */
InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles); Total = InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfHandles);
if (ObjectType->TotalNumberOfHandles > ObjectType->HighWaterNumberOfHandles) if (Total > ObjectType->HighWaterNumberOfHandles)
{ {
/* Fixup count */ /* Fixup count */
ObjectType->HighWaterNumberOfHandles = ObjectType->TotalNumberOfHandles; ObjectType->HighWaterNumberOfHandles = Total;
} }
/* Trace call and return */ /* Trace call and return */
@ -1208,7 +1218,7 @@ ObpCreateUnnamedHandle(IN PVOID Object,
ObjectHeader->PointerCount); ObjectHeader->PointerCount);
/* Check if this is a kernel handle */ /* Check if this is a kernel handle */
if ((HandleAttributes & OBJ_KERNEL_HANDLE) && (AccessMode == KernelMode)) if (HandleAttributes & OBJ_KERNEL_HANDLE)
{ {
/* Set the handle table */ /* Set the handle table */
HandleTable = ObpKernelHandleTable; HandleTable = ObpKernelHandleTable;
@ -1309,14 +1319,9 @@ ObpCreateUnnamedHandle(IN PVOID Object,
} }
/* Handle extra references */ /* Handle extra references */
if (AdditionalReferences == 1) if (AdditionalReferences)
{ {
/* Dereference the object once */ /* Dereference it as many times as required */
ObDereferenceObject(Object);
}
else if (AdditionalReferences > 1)
{
/* Dereference it many times */
InterlockedExchangeAdd(&ObjectHeader->PointerCount, InterlockedExchangeAdd(&ObjectHeader->PointerCount,
-AdditionalReferences); -AdditionalReferences);
} }
@ -1413,7 +1418,7 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason,
} }
/* Check if this is a kernel handle */ /* Check if this is a kernel handle */
if ((HandleAttributes & OBJ_KERNEL_HANDLE) && (AccessMode == KernelMode)) if (HandleAttributes & OBJ_KERNEL_HANDLE)
{ {
/* Set the handle table */ /* Set the handle table */
HandleTable = ObpKernelHandleTable; HandleTable = ObpKernelHandleTable;
@ -1508,12 +1513,6 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason,
/* Make sure we got a handle */ /* Make sure we got a handle */
if (Handle) if (Handle)
{ {
/* Check if we have auxiliary data */
if (AuxData)
{
/* FIXME: Change handle security */
}
/* Check if this was a kernel handle */ /* Check if this was a kernel handle */
if (KernelHandle) Handle = ObMarkHandleAsKernelHandle(Handle); if (KernelHandle) Handle = ObMarkHandleAsKernelHandle(Handle);
@ -1573,17 +1572,19 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason,
GrantedAccess); GrantedAccess);
/* Handle extra references */ /* Handle extra references */
if (AdditionalReferences == 1) if (AdditionalReferences)
{ {
/* Dereference the object once */ /* Check how many extra references were added */
if (AdditionalReferences > 1)
{
/* Dereference it many times */
InterlockedExchangeAdd(&ObjectHeader->PointerCount,
-(AdditionalReferences - 1));
}
/* Dereference the object one last time */
ObDereferenceObject(Object); ObDereferenceObject(Object);
} }
else if (AdditionalReferences > 1)
{
/* Dereference it many times */
InterlockedExchangeAdd(&ObjectHeader->PointerCount,
-AdditionalReferences);
}
/* Detach if necessary and fail */ /* Detach if necessary and fail */
if (AttachedToProcess) KeUnstackDetachProcess(&ApcState); if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
@ -1670,9 +1671,9 @@ ObpCloseHandle(IN HANDLE Handle,
/* Detach */ /* Detach */
if (AttachedToProcess) KeUnstackDetachProcess(&ApcState); if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
/* Check if this was a user-mode caller with a valid exception port */ /* Check if this was a user-mode caller with a valid debug port */
if ((AccessMode != KernelMode) && if ((AccessMode != KernelMode) &&
(PsGetCurrentProcess()->ExceptionPort)) (PsGetCurrentProcess()->DebugPort))
{ {
/* Raise an exception */ /* Raise an exception */
Status = KeRaiseUserException(STATUS_INVALID_HANDLE); Status = KeRaiseUserException(STATUS_INVALID_HANDLE);
@ -1948,8 +1949,9 @@ ObKillProcess(IN PEPROCESS Process)
BOOLEAN HardErrors; BOOLEAN HardErrors;
PAGED_CODE(); PAGED_CODE();
/* Wait for process rundown */ /* Wait for process rundown and then complete it */
ExWaitForRundownProtectionRelease(&Process->RundownProtect); ExWaitForRundownProtectionRelease(&Process->RundownProtect);
ExRundownCompleted(&Process->RundownProtect);
/* Get the object table */ /* Get the object table */
HandleTable = Process->ObjectTable; HandleTable = Process->ObjectTable;
@ -2007,6 +2009,7 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
AUX_DATA AuxData; AUX_DATA AuxData;
PHANDLE_TABLE HandleTable; PHANDLE_TABLE HandleTable;
OBJECT_HANDLE_INFORMATION HandleInformation; OBJECT_HANDLE_INFORMATION HandleInformation;
ULONG AuditMask;
PAGED_CODE(); PAGED_CODE();
OBTRACE(OB_HANDLE_DEBUG, OBTRACE(OB_HANDLE_DEBUG,
"%s - Duplicating handle: %lx for %p into %p\n", "%s - Duplicating handle: %lx for %p into %p\n",
@ -2015,6 +2018,9 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
SourceProcess, SourceProcess,
TargetProcess); TargetProcess);
/* Assume failure */
if (TargetHandle) *TargetHandle = NULL;
/* Check if we're not duplicating the same access */ /* Check if we're not duplicating the same access */
if (!(Options & DUPLICATE_SAME_ACCESS)) if (!(Options & DUPLICATE_SAME_ACCESS))
{ {
@ -2029,11 +2035,12 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
/* Reference the process object */ /* Reference the process object */
Status = ObpReferenceProcessObjectByHandle(SourceHandle, Status = ObpReferenceProcessObjectByHandle(SourceHandle,
0, SourceProcess,
HandleTable, HandleTable,
PreviousMode, PreviousMode,
&SourceObject, &SourceObject,
&HandleInformation); &HandleInformation,
&AuditMask);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* Fail */ /* Fail */
@ -2191,6 +2198,10 @@ ObDuplicateObject(IN PEPROCESS SourceProcess,
/* Now check if incrementing actually failed */ /* Now check if incrementing actually failed */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* Dereference handle tables */
ObDereferenceProcessHandleTable(SourceProcess);
ObDereferenceProcessHandleTable(TargetProcess);
/* Dereference the source object */ /* Dereference the source object */
ObDereferenceObject(SourceObject); ObDereferenceObject(SourceObject);
return Status; return Status;
@ -2283,11 +2294,13 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
POB_TEMP_BUFFER TempBuffer; POB_TEMP_BUFFER TempBuffer;
PAGED_CODE(); PAGED_CODE();
/* Assume failure */
*Handle = NULL;
/* Check if we didn't get any Object Attributes */ /* Check if we didn't get any Object Attributes */
if (!ObjectAttributes) if (!ObjectAttributes)
{ {
/* Fail with special status code */ /* Fail with special status code */
*Handle = NULL;
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -2303,7 +2316,12 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
TRUE, TRUE,
&TempBuffer->ObjectCreateInfo, &TempBuffer->ObjectCreateInfo,
&ObjectName); &ObjectName);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status))
{
/* Fail */
ExFreePool(TempBuffer);
return Status;
}
/* Check if we didn't get an access state */ /* Check if we didn't get an access state */
if (!PassedAccessState) if (!PassedAccessState)
@ -2378,6 +2396,9 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
/* Cleanup after lookup */ /* Cleanup after lookup */
ObpCleanupDirectoryLookup(&TempBuffer->LookupContext); ObpCleanupDirectoryLookup(&TempBuffer->LookupContext);
/* Dereference the object */
ObDereferenceObject(Object);
} }
else else
{ {
@ -2466,8 +2487,8 @@ ObOpenObjectByPointer(IN PVOID Object,
AUX_DATA AuxData; AUX_DATA AuxData;
PAGED_CODE(); PAGED_CODE();
/* Get the Header Info */ /* Assume failure */
Header = OBJECT_TO_OBJECT_HEADER(Object); *Handle = NULL;
/* Reference the object */ /* Reference the object */
Status = ObReferenceObjectByPointer(Object, Status = ObReferenceObjectByPointer(Object,
@ -2476,6 +2497,9 @@ ObOpenObjectByPointer(IN PVOID Object,
AccessMode); AccessMode);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
/* Get the Header Info */
Header = OBJECT_TO_OBJECT_HEADER(Object);
/* Check if we didn't get an access state */ /* Check if we didn't get an access state */
if (!PassedAccessState) if (!PassedAccessState)
{ {
@ -2493,6 +2517,20 @@ ObOpenObjectByPointer(IN PVOID Object,
} }
} }
/* Check if we have invalid object attributes */
if (Header->Type->TypeInfo.InvalidAttributes & HandleAttributes)
{
/* Delete the access state */
if (PassedAccessState == &AccessState)
{
SeDeleteAccessState(PassedAccessState);
}
/* Dereference the object */
ObDereferenceObject(Object);
return STATUS_INVALID_PARAMETER;
}
/* Create the handle */ /* Create the handle */
Status = ObpCreateHandle(ObOpenHandle, Status = ObpCreateHandle(ObOpenHandle,
Object, Object,