secured access to buffers in NtWaitForSingleObject(),
NtWaitForMultipleObjects() and NtSignalAndWaitForSingleObject()
Modified: trunk/reactos/include/ntos/zw.h
Modified: trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/w32api/include/ddk/winddk.h
_____
Modified: trunk/reactos/include/ntos/zw.h
--- trunk/reactos/include/ntos/zw.h 2005-02-14 21:41:49 UTC (rev
13578)
+++ trunk/reactos/include/ntos/zw.h 2005-02-14 22:50:15 UTC (rev
13579)
@@ -4423,28 +4423,28 @@
/*
* FUNCTION: Signals an object and wait for an other one.
* ARGUMENTS:
- * SignalObject = Handle to the object that should be signaled
- * WaitObject = Handle to the object that should be waited for
+ * ObjectHandleToSignal = Handle to the object that should be
signaled
+ * WaitableObjectHandle = Handle to the object that should be
waited for
* Alertable = True if the wait is alertable
- * Time = The time to wait
+ * TimeOut = The time to wait
* RETURNS: Status
*/
NTSTATUS
STDCALL
NtSignalAndWaitForSingleObject(
- IN HANDLE SignalObject,
- IN HANDLE WaitObject,
+ IN HANDLE ObjectHandleToSignal,
+ IN HANDLE WaitableObjectHandle,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time
+ IN PLARGE_INTEGER TimeOut OPTIONAL
);
NTSTATUS
STDCALL
NtSignalAndWaitForSingleObject(
- IN HANDLE SignalObject,
- IN HANDLE WaitObject,
+ IN HANDLE ObjectHandleToSignal,
+ IN HANDLE WaitableObjectHandle,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time
+ IN PLARGE_INTEGER TimeOut OPTIONAL
);
/*
@@ -4651,9 +4651,9 @@
/*
* FUNCTION: Waits for an object to become signalled.
* ARGUMENTS:
- * Object = The object handle
+ * ObjectHandle = The object handle
* Alertable = If true the wait is alertable.
- * Time = The maximum wait time.
+ * TimeOut = The maximum wait time.
* REMARKS:
* This function maps to the win32 WaitForSingleObjectEx.
* RETURNS: Status
@@ -4661,17 +4661,17 @@
NTSTATUS
STDCALL
NtWaitForSingleObject (
- IN HANDLE Object,
+ IN HANDLE ObjectHandle,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time
+ IN PLARGE_INTEGER TimeOut OPTIONAL
);
NTSTATUS
STDCALL
ZwWaitForSingleObject (
- IN HANDLE Object,
+ IN HANDLE ObjectHandle,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time
+ IN PLARGE_INTEGER TimeOut OPTIONAL
);
/* --- EVENT PAIR OBJECT --- */
@@ -5583,11 +5583,11 @@
/*
* FUNCTION: Waits for multiple objects to become signalled.
* ARGUMENTS:
- * Count = The number of objects
- * Object = The array of object handles
+ * ObjectCount = The number of objects
+ * ObjectsArray = The array of object handles
* WaitType = Can be one of the values UserMode or KernelMode
* Alertable = If true the wait is alertable.
- * Time = The maximum wait time.
+ * TimeOut = The maximum wait time.
* REMARKS:
* This function maps to the win32 WaitForMultipleObjectEx.
* RETURNS: Status
@@ -5595,11 +5595,11 @@
NTSTATUS
STDCALL
NtWaitForMultipleObjects (
- IN ULONG Count,
- IN HANDLE Object[],
+ IN ULONG ObjectCount,
+ IN PHANDLE ObjectsArray,
IN WAIT_TYPE WaitType,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time
+ IN PLARGE_INTEGER TimeOut OPTIONAL
);
@@ -6357,11 +6357,11 @@
/*
* FUNCTION: Waits for multiple objects to become signalled.
* ARGUMENTS:
- * Count = The number of objects
- * Object = The array of object handles
+ * ObjectCount = The number of objects
+ * ObjectsArray = The array of object handles
* WaitType = Can be one of the values UserMode or KernelMode
* Alertable = If true the wait is alertable.
- * Time = The maximum wait time.
+ * TimeOut = The maximum wait time.
* REMARKS:
* This function maps to the win32 WaitForMultipleObjectEx.
* RETURNS: Status
@@ -6369,11 +6369,11 @@
NTSTATUS
STDCALL
ZwWaitForMultipleObjects (
- IN ULONG Count,
- IN HANDLE Object[],
+ IN ULONG ObjectCount,
+ IN PHANDLE ObjectsArray,
IN WAIT_TYPE WaitType,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time
+ IN PLARGE_INTEGER TimeOut OPTIONAL
);
/*
_____
Modified: trunk/reactos/ntoskrnl/ke/wait.c
--- trunk/reactos/ntoskrnl/ke/wait.c 2005-02-14 21:41:49 UTC (rev
13578)
+++ trunk/reactos/ntoskrnl/ke/wait.c 2005-02-14 22:50:15 UTC (rev
13579)
@@ -785,45 +785,71 @@
}
NTSTATUS STDCALL
-NtWaitForMultipleObjects(IN ULONG Count,
- IN HANDLE Object [],
+NtWaitForMultipleObjects(IN ULONG ObjectCount,
+ IN PHANDLE ObjectsArray,
IN WAIT_TYPE WaitType,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER UnsafeTime)
+ IN PLARGE_INTEGER TimeOut OPTIONAL)
{
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
+ HANDLE SafeObjectsArray[MAXIMUM_WAIT_OBJECTS];
PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS];
- NTSTATUS Status;
ULONG i, j;
- KPROCESSOR_MODE WaitMode;
- LARGE_INTEGER Time;
+ KPROCESSOR_MODE PreviousMode;
+ LARGE_INTEGER SafeTimeOut;
+ NTSTATUS Status = STATUS_SUCCESS;
- DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable
%d, "
- "Time %x)\n", Count,Object,Alertable,Time);
+ DPRINT("NtWaitForMultipleObjects(ObjectCount %lu ObjectsArray[] %x,
Alertable %d, "
+ "TimeOut %x)\n", ObjectCount,ObjectsArray,Alertable,TimeOut);
- if (Count > MAXIMUM_WAIT_OBJECTS)
+ PreviousMode = ExGetPreviousMode();
+
+ if (ObjectCount > MAXIMUM_WAIT_OBJECTS)
return STATUS_UNSUCCESSFUL;
- if (0 == Count)
+ if (0 == ObjectCount)
return STATUS_INVALID_PARAMETER;
- if (UnsafeTime)
+ if(PreviousMode != KernelMode)
+ {
+ _SEH_TRY
{
- Status = MmCopyFromCaller(&Time, UnsafeTime,
sizeof(LARGE_INTEGER));
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
+ ProbeForRead(ObjectsArray,
+ ObjectCount * sizeof(ObjectsArray[0]),
+ sizeof(ULONG));
+ /* make a copy so we don't have to guard with SEH later and keep
track of
+ what objects we referenced in case dereferencing pointers
suddenly fails */
+ RtlCopyMemory(SafeObjectsArray, ObjectsArray, ObjectCount *
sizeof(ObjectsArray[0]));
+ ObjectsArray = SafeObjectsArray;
+
+ if(TimeOut != NULL)
+ {
+ ProbeForRead(TimeOut,
+ sizeof(LARGE_INTEGER),
+ sizeof(ULONG));
+ /* make a local copy of the timeout on the stack */
+ SafeTimeOut = *TimeOut;
+ TimeOut = &SafeTimeOut;
+ }
}
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
- WaitMode = ExGetPreviousMode();
-
/* reference all objects */
- for (i = 0; i < Count; i++)
+ for (i = 0; i < ObjectCount; i++)
{
- Status = ObReferenceObjectByHandle(Object[i],
+ Status = ObReferenceObjectByHandle(ObjectsArray[i],
SYNCHRONIZE,
NULL,
- WaitMode,
+ PreviousMode,
&ObjectPtrArray[i],
NULL);
if (!NT_SUCCESS(Status) ||
!KiIsObjectWaitable(ObjectPtrArray[i]))
@@ -845,17 +871,17 @@
}
}
- Status = KeWaitForMultipleObjects(Count,
+ Status = KeWaitForMultipleObjects(ObjectCount,
ObjectPtrArray,
WaitType,
UserRequest,
- WaitMode,
+ PreviousMode,
Alertable,
- UnsafeTime ? &Time : NULL,
+ TimeOut,
WaitBlockArray);
/* dereference all objects */
- for (i = 0; i < Count; i++)
+ for (i = 0; i < ObjectCount; i++)
{
ObDereferenceObject(ObjectPtrArray[i]);
}
@@ -868,33 +894,47 @@
* @implemented
*/
NTSTATUS STDCALL
-NtWaitForSingleObject(IN HANDLE Object,
+NtWaitForSingleObject(IN HANDLE ObjectHandle,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER UnsafeTime)
+ IN PLARGE_INTEGER TimeOut OPTIONAL)
{
PVOID ObjectPtr;
- NTSTATUS Status;
- KPROCESSOR_MODE WaitMode;
- LARGE_INTEGER Time;
+ KPROCESSOR_MODE PreviousMode;
+ LARGE_INTEGER SafeTimeOut;
+ NTSTATUS Status = STATUS_SUCCESS;
- DPRINT("NtWaitForSingleObject(Object %x, Alertable %d, Time %x)\n",
- Object,Alertable,Time);
+ DPRINT("NtWaitForSingleObject(ObjectHandle %x, Alertable %d, TimeOut
%x)\n",
+ ObjectHandle,Alertable,TimeOut);
- if (UnsafeTime)
+ PreviousMode = ExGetPreviousMode();
+
+ if(TimeOut != NULL && PreviousMode != KernelMode)
+ {
+ _SEH_TRY
{
- Status = MmCopyFromCaller(&Time, UnsafeTime,
sizeof(LARGE_INTEGER));
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
+ ProbeForRead(TimeOut,
+ sizeof(LARGE_INTEGER),
+ sizeof(ULONG));
+ /* make a copy on the stack */
+ SafeTimeOut = *TimeOut;
+ TimeOut = &SafeTimeOut;
}
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
- WaitMode = ExGetPreviousMode();
-
- Status = ObReferenceObjectByHandle(Object,
+ Status = ObReferenceObjectByHandle(ObjectHandle,
SYNCHRONIZE,
NULL,
- WaitMode,
+ PreviousMode,
&ObjectPtr,
NULL);
if (!NT_SUCCESS(Status))
@@ -911,9 +951,9 @@
{
Status = KeWaitForSingleObject(ObjectPtr,
UserRequest,
- WaitMode,
+ PreviousMode,
Alertable,
- UnsafeTime ? &Time : NULL);
+ TimeOut);
}
ObDereferenceObject(ObjectPtr);
@@ -923,22 +963,47 @@
NTSTATUS STDCALL
-NtSignalAndWaitForSingleObject(IN HANDLE SignalObject,
- IN HANDLE WaitObject,
+NtSignalAndWaitForSingleObject(IN HANDLE ObjectHandleToSignal,
+ IN HANDLE WaitableObjectHandle,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time)
+ IN PLARGE_INTEGER TimeOut OPTIONAL)
{
- KPROCESSOR_MODE WaitMode;
+ KPROCESSOR_MODE PreviousMode;
DISPATCHER_HEADER* hdr;
PVOID SignalObj;
PVOID WaitObj;
- NTSTATUS Status;
+ LARGE_INTEGER SafeTimeOut;
+ NTSTATUS Status = STATUS_SUCCESS;
- WaitMode = ExGetPreviousMode();
- Status = ObReferenceObjectByHandle(SignalObject,
+ PreviousMode = ExGetPreviousMode();
+
+ if(TimeOut != NULL && PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ ProbeForRead(TimeOut,
+ sizeof(LARGE_INTEGER),
+ sizeof(ULONG));
+ /* make a copy on the stack */
+ SafeTimeOut = *TimeOut;
+ TimeOut = &SafeTimeOut;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if(!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+
+ Status = ObReferenceObjectByHandle(ObjectHandleToSignal,
0,
NULL,
- WaitMode,
+ PreviousMode,
&SignalObj,
NULL);
if (!NT_SUCCESS(Status))
@@ -946,10 +1011,10 @@
return Status;
}
- Status = ObReferenceObjectByHandle(WaitObject,
+ Status = ObReferenceObjectByHandle(WaitableObjectHandle,
SYNCHRONIZE,
NULL,
- WaitMode,
+ PreviousMode,
&WaitObj,
NULL);
if (!NT_SUCCESS(Status))
@@ -988,9 +1053,9 @@
Status = KeWaitForSingleObject(WaitObj,
UserRequest,
- WaitMode,
+ PreviousMode,
Alertable,
- Time);
+ TimeOut);
ObDereferenceObject(SignalObj);
ObDereferenceObject(WaitObj);
_____
Modified: trunk/reactos/w32api/include/ddk/winddk.h
--- trunk/reactos/w32api/include/ddk/winddk.h 2005-02-14 21:41:49 UTC
(rev 13578)
+++ trunk/reactos/w32api/include/ddk/winddk.h 2005-02-14 22:50:15 UTC
(rev 13579)
@@ -9131,17 +9131,17 @@
NTSTATUS
DDKAPI
NtWaitForSingleObject(
- IN HANDLE Object,
+ IN HANDLE ObjectHandle,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time);
+ IN PLARGE_INTEGER TimeOut OPTIONAL);
NTOSAPI
NTSTATUS
DDKAPI
ZwWaitForSingleObject(
- IN HANDLE Object,
+ IN HANDLE ObjectHandle,
IN BOOLEAN Alertable,
- IN PLARGE_INTEGER Time);
+ IN PLARGE_INTEGER TimeOut OPTIONAL);
NTOSAPI
NTSTATUS