mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
secured access to buffers in NtWaitForSingleObject(), NtWaitForMultipleObjects() and NtSignalAndWaitForSingleObject()
svn path=/trunk/; revision=13579
This commit is contained in:
parent
eafae64526
commit
f4c9f96205
3 changed files with 152 additions and 87 deletions
|
@ -4423,28 +4423,28 @@ ZwShutdownSystem(
|
|||
/*
|
||||
* 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 @@ ZwWriteVirtualMemory(
|
|||
/*
|
||||
* 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 @@ ZwWriteVirtualMemory(
|
|||
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 @@ NtUnlockVirtualMemory(
|
|||
/*
|
||||
* 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 @@ NtUnlockVirtualMemory(
|
|||
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 @@ ZwUnlockVirtualMemory(
|
|||
/*
|
||||
* 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 @@ ZwUnlockVirtualMemory(
|
|||
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
|
||||
);
|
||||
|
||||
/*
|
||||
|
|
|
@ -785,45 +785,71 @@ VOID KeInitializeDispatcher(VOID)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
WaitMode = ExGetPreviousMode();
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 @@ NtWaitForMultipleObjects(IN ULONG Count,
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ NtWaitForMultipleObjects(IN ULONG Count,
|
|||
* @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 @@ NtWaitForSingleObject(IN HANDLE Object,
|
|||
{
|
||||
Status = KeWaitForSingleObject(ObjectPtr,
|
||||
UserRequest,
|
||||
WaitMode,
|
||||
PreviousMode,
|
||||
Alertable,
|
||||
UnsafeTime ? &Time : NULL);
|
||||
TimeOut);
|
||||
}
|
||||
|
||||
ObDereferenceObject(ObjectPtr);
|
||||
|
@ -923,22 +963,47 @@ NtWaitForSingleObject(IN HANDLE Object,
|
|||
|
||||
|
||||
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 @@ NtSignalAndWaitForSingleObject(IN HANDLE SignalObject,
|
|||
return Status;
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByHandle(WaitObject,
|
||||
Status = ObReferenceObjectByHandle(WaitableObjectHandle,
|
||||
SYNCHRONIZE,
|
||||
NULL,
|
||||
WaitMode,
|
||||
PreviousMode,
|
||||
&WaitObj,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -988,9 +1053,9 @@ NtSignalAndWaitForSingleObject(IN HANDLE SignalObject,
|
|||
|
||||
Status = KeWaitForSingleObject(WaitObj,
|
||||
UserRequest,
|
||||
WaitMode,
|
||||
PreviousMode,
|
||||
Alertable,
|
||||
Time);
|
||||
TimeOut);
|
||||
|
||||
ObDereferenceObject(SignalObj);
|
||||
ObDereferenceObject(WaitObj);
|
||||
|
|
|
@ -9131,17 +9131,17 @@ NTOSAPI
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue