Author: ion Date: Fri Dec 29 23:52:33 2006 New Revision: 25239
URL: http://svn.reactos.org/svn/reactos?rev=25239&view=rev Log: - Fix some subtle bugs in NtWaitForMultipleObjects/NtWaitForSingleObject: - Fail if memory allocation failed. - Don't overwrite original captured handle value when decoding to kernel handle. - Use PAGED_CODE. - Check timeout validity first before probing the entire handle array. - Fix a critical bug in NtSignalAndWaitForObject which was using the wrong object type (waitable object instead of signalled objecT).
Modified: trunk/reactos/ntoskrnl/include/internal/tag.h trunk/reactos/ntoskrnl/ob/obwait.c
Modified: trunk/reactos/ntoskrnl/include/internal/tag.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/t... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/tag.h (original) +++ trunk/reactos/ntoskrnl/include/internal/tag.h Fri Dec 29 23:52:33 2006 @@ -161,4 +161,6 @@ /* Se Process Audit */ #define TAG_SEPA TAG('S', 'e', 'P', 'a')
+#define TAG_WAIT TAG('W', 'a', 'i', 't') + #endif /* _NTOSKRNL_TAG_H */
Modified: trunk/reactos/ntoskrnl/ob/obwait.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obwait.c?rev=25... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obwait.c (original) +++ trunk/reactos/ntoskrnl/ob/obwait.c Fri Dec 29 23:52:33 2006 @@ -12,8 +12,6 @@ #include <ntoskrnl.h> #define NDEBUG #include <internal/debug.h> - -#define TAG_WAIT TAG('W', 'a', 'i', 't')
/* FUNCTIONS *****************************************************************/
@@ -52,7 +50,7 @@ IN PLARGE_INTEGER TimeOut OPTIONAL) { PKWAIT_BLOCK WaitBlockArray = NULL; - HANDLE Handles[MAXIMUM_WAIT_OBJECTS]; + HANDLE Handles[MAXIMUM_WAIT_OBJECTS], KernelHandle; PVOID Objects[MAXIMUM_WAIT_OBJECTS]; PVOID WaitObjects[MAXIMUM_WAIT_OBJECTS]; ULONG i = 0, ReferencedObjects = 0, j; @@ -65,17 +63,16 @@ ACCESS_MASK GrantedAccess; PVOID DefaultObject; NTSTATUS Status = STATUS_SUCCESS; - DPRINT("NtWaitForMultipleObjects(ObjectCount %lu HandleArray[] %x," - " Alertable %d, TimeOut %x)\n", - ObjectCount, HandleArray, Alertable, TimeOut); + PAGED_CODE();
/* Enter a critical region since we'll play with handles */ LockInUse = TRUE; KeEnterCriticalRegion();
/* Check for valid Object Count */ - if ((ObjectCount > MAXIMUM_WAIT_OBJECTS) || !ObjectCount) - { + if ((ObjectCount > MAXIMUM_WAIT_OBJECTS) || !(ObjectCount)) + { + /* Fail */ Status = STATUS_INVALID_PARAMETER_1; goto Quickie; } @@ -83,6 +80,7 @@ /* Check for valid Wait Type */ if ((WaitType != WaitAll) && (WaitType != WaitAny)) { + /* Fail */ Status = STATUS_INVALID_PARAMETER_3; goto Quickie; } @@ -93,16 +91,18 @@ /* Check if the call came from user mode */ if(PreviousMode != KernelMode) { - /* Probe all the handles */ - ProbeForRead(HandleArray, - ObjectCount * sizeof(HANDLE), - sizeof(HANDLE)); + /* Check if we have a timeout */ if (TimeOut) { /* Make a local copy of the timeout on the stack */ SafeTimeOut = ProbeForReadLargeInteger(TimeOut); TimeOut = &SafeTimeOut; } + + /* Probe all the handles */ + ProbeForRead(HandleArray, + ObjectCount * sizeof(HANDLE), + sizeof(HANDLE)); }
/* @@ -132,6 +132,12 @@ ObjectCount * sizeof(KWAIT_BLOCK), TAG_WAIT); + if (!WaitBlockArray) + { + /* Fail */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } }
/* Start the loop */ @@ -142,16 +148,21 @@ { /* Use the System Handle Table and decode */ HandleTable = ObpKernelHandleTable; - Handles[i] = ObKernelHandleToHandle(Handles[i]); + KernelHandle = ObKernelHandleToHandle(Handles[i]); + + /* Get a pointer to it */ + HandleEntry = ExMapHandleToPointer(HandleTable, KernelHandle); } else { /* Use the Process' Handle table and get the Ex Handle */ HandleTable = PsGetCurrentProcess()->ObjectTable; - } - - /* Get a pointer to it */ - HandleEntry = ExMapHandleToPointer(HandleTable, Handles[i]); + + /* Get a pointer to it */ + HandleEntry = ExMapHandleToPointer(HandleTable, Handles[i]); + } + + /* Check if we have an entry */ if (!HandleEntry) { /* Fail, handle is invalid */ @@ -349,12 +360,11 @@ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); LARGE_INTEGER SafeTimeOut; NTSTATUS Status = STATUS_SUCCESS; - DPRINT("NtWaitForSingleObject(ObjectHandle %x, Alertable %d, TimeOut %x)\n", - ObjectHandle,Alertable,TimeOut);
/* Check if we came with a timeout from user mode */ - if (TimeOut && PreviousMode != KernelMode) - { + if ((TimeOut) && (PreviousMode != KernelMode)) + { + /* Enter SEH for proving */ _SEH_TRY { /* Make a copy on the stack */ @@ -367,8 +377,6 @@ Status = _SEH_GetExceptionCode(); } _SEH_END; - - /* Fail if we got an access violation */ if (!NT_SUCCESS(Status)) return Status; }
@@ -449,16 +457,15 @@ { KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); POBJECT_TYPE Type; - PVOID SignalObj; - PVOID WaitObj; - PVOID WaitableObject; + PVOID SignalObj, WaitObj, WaitableObject; LARGE_INTEGER SafeTimeOut; OBJECT_HANDLE_INFORMATION HandleInfo; NTSTATUS Status = STATUS_SUCCESS;
/* Check if we came with a timeout from user mode */ - if (TimeOut && PreviousMode != KernelMode) - { + if ((TimeOut) && (PreviousMode != KernelMode)) + { + /* Enter SEH for probing */ _SEH_TRY { /* Make a copy on the stack */ @@ -471,8 +478,6 @@ Status = _SEH_GetExceptionCode(); } _SEH_END; - - /* Fail if we got an access violation */ if (!NT_SUCCESS(Status)) return Status; }
@@ -511,7 +516,7 @@ }
/* Check Signal Object Type */ - Type = OBJECT_TO_OBJECT_HEADER(WaitObj)->Type; + Type = OBJECT_TO_OBJECT_HEADER(SignalObj)->Type; if (Type == ExEventObjectType) { /* Check if we came from user-mode without the right access */