From ea39ea0e30c205ee167aa27b937aa0854c8bf67a Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Wed, 28 Jan 2009 10:32:43 +0000 Subject: [PATCH] modified ntoskrnl/include/internal/ob.h modified ntoskrnl/ob/obhandle.c New helper routine ObGetProcessHandleCount to safely read the count of handles in a process without messing with Ob internals Goodbye ObpGetHandleCountByHandleTable modified ntoskrnl/ex/sysinfo.c modified ntoskrnl/ps/query.c Read handle counts with ObGetProcessHandleCount instead of ObpGetHandleCountByHandleTable Fixes at least one crash Thanks to Stefan Ginsberg for reporting the issue and testing Thanks to Alex Ionescu for code review and suggestions See issue #4050 for more details. svn path=/trunk/; revision=39169 --- reactos/ntoskrnl/ex/sysinfo.c | 6 +++--- reactos/ntoskrnl/include/internal/ob.h | 17 ++++++++------- reactos/ntoskrnl/ob/obhandle.c | 29 ++++++++++++++++++++++++++ reactos/ntoskrnl/ps/query.c | 2 +- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 278ecb97c85..ffe955c286d 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -778,7 +778,7 @@ QSI_DEF(SystemProcessInformation) SpiCurrent->BasePriority = Process->Pcb.BasePriority; SpiCurrent->UniqueProcessId = Process->UniqueProcessId; SpiCurrent->InheritedFromUniqueProcessId = Process->InheritedFromUniqueProcessId; - SpiCurrent->HandleCount = (Process->ObjectTable ? ObpGetHandleCountByHandleTable(Process->ObjectTable) : 0); + SpiCurrent->HandleCount = ObGetProcessHandleCount(Process); SpiCurrent->PeakVirtualSize = Process->PeakVirtualSize; SpiCurrent->VirtualSize = Process->VirtualSize; SpiCurrent->PageFaultCount = Process->Vm.PageFaultCount; @@ -1023,7 +1023,7 @@ QSI_DEF(SystemHandleInformation) do { - hCount = hCount + (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0); + hCount = hCount + ObGetProcessHandleCount(pr); pr = PsGetNextProcess(pr); if ((pr == syspr) || (pr == NULL)) break; @@ -1059,7 +1059,7 @@ QSI_DEF(SystemHandleInformation) { int Count = 0, HandleCount; - HandleCount = (pr->ObjectTable ? ObpGetHandleCountByHandleTable(pr->ObjectTable) : 0); + HandleCount = ObGetProcessHandleCount(pr); for (Count = 0; HandleCount > 0 ; HandleCount--) { diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index 20890c0e4a6..f055de755fd 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -70,12 +70,6 @@ #define ObMarkHandleAsKernelHandle(Handle) \ (HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG) -// -// Returns the number of handles in a handle table -// -#define ObpGetHandleCountByHandleTable(HandleTable) \ - ((PHANDLE_TABLE)HandleTable)->HandleCount - // // Converts from an EXHANDLE object to a POBJECT_HEADER // @@ -124,7 +118,7 @@ typedef struct _SECURITY_DESCRIPTOR_HEADER LIST_ENTRY Link; ULONG RefCount; ULONG FullHash; - QUAD SecurityDescriptor; + QUAD SecurityDescriptor; } SECURITY_DESCRIPTOR_HEADER, *PSECURITY_DESCRIPTOR_HEADER; // @@ -570,6 +564,15 @@ ObpCaptureObjectCreateInformation( OUT PUNICODE_STRING ObjectName ); +// +// Miscellanea +// +ULONG +NTAPI +ObGetProcessHandleCount( + IN PEPROCESS Process +); + // // Global data inside the Object Manager // diff --git a/reactos/ntoskrnl/ob/obhandle.c b/reactos/ntoskrnl/ob/obhandle.c index 18170fbc37e..f6a2c0c9da3 100644 --- a/reactos/ntoskrnl/ob/obhandle.c +++ b/reactos/ntoskrnl/ob/obhandle.c @@ -54,6 +54,35 @@ ObDereferenceProcessHandleTable(IN PEPROCESS Process) ExReleaseRundownProtection(&Process->RundownProtect); } +ULONG +NTAPI +ObGetProcessHandleCount(IN PEPROCESS Process) +{ + ULONG HandleCount; + PHANDLE_TABLE HandleTable; + + ASSERT(Process); + + /* Ensure the handle table doesn't go away while we use it */ + HandleTable = ObReferenceProcessHandleTable(Process); + + if (HandleTable != NULL) + { + /* Count the number of handles the process has */ + HandleCount = HandleTable->HandleCount; + + /* Let the handle table go */ + ObDereferenceProcessHandleTable(Process); + } + else + { + /* No handle table, no handles */ + HandleCount = 0; + } + + return HandleCount; +} + NTSTATUS NTAPI ObpReferenceProcessObjectByHandle(IN HANDLE Handle, diff --git a/reactos/ntoskrnl/ps/query.c b/reactos/ntoskrnl/ps/query.c index a985db20299..4275d1618c3 100644 --- a/reactos/ntoskrnl/ps/query.c +++ b/reactos/ntoskrnl/ps/query.c @@ -237,7 +237,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle, } /* Count the number of handles this process has */ - HandleCount = ObpGetHandleCountByHandleTable(Process->ObjectTable); + HandleCount = ObGetProcessHandleCount(Process); /* Protect write in SEH */ _SEH2_TRY