mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
1. fixed the timer functions to securely access buffers
2. minor fixes due to copy+paste svn path=/trunk/; revision=13236
This commit is contained in:
parent
7c02041548
commit
064504a61d
2 changed files with 258 additions and 98 deletions
|
@ -240,12 +240,12 @@ NtQuerySemaphore(IN HANDLE SemaphoreHandle,
|
||||||
&Status);
|
&Status);
|
||||||
if(!NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("NtQueryEvent() failed, Status: 0x%x\n", Status);
|
DPRINT1("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(SemaphoreHandle,
|
Status = ObReferenceObjectByHandle(SemaphoreHandle,
|
||||||
EVENT_QUERY_STATE,
|
SEMAPHORE_QUERY_STATE,
|
||||||
ExSemaphoreObjectType,
|
ExSemaphoreObjectType,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
(PVOID*)&Semaphore,
|
(PVOID*)&Semaphore,
|
||||||
|
|
|
@ -36,6 +36,10 @@ static GENERIC_MAPPING ExpTimerMapping = {
|
||||||
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
||||||
TIMER_ALL_ACCESS};
|
TIMER_ALL_ACCESS};
|
||||||
|
|
||||||
|
static const INFORMATION_CLASS_INFO ExTimerInfoClass[] =
|
||||||
|
{
|
||||||
|
ICI_SQ_SAME( sizeof(TIMER_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* TimerBasicInformation */
|
||||||
|
};
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -146,36 +150,67 @@ NtCancelTimer(IN HANDLE TimerHandle,
|
||||||
OUT PBOOLEAN CurrentState OPTIONAL)
|
OUT PBOOLEAN CurrentState OPTIONAL)
|
||||||
{
|
{
|
||||||
PNTTIMER Timer;
|
PNTTIMER Timer;
|
||||||
NTSTATUS Status;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
BOOLEAN State;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
KIRQL OldIrql;
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
DPRINT("NtCancelTimer(0x%x, 0x%x)\n", TimerHandle, CurrentState);
|
||||||
|
|
||||||
|
if(CurrentState != NULL && PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(CurrentState,
|
||||||
|
sizeof(BOOLEAN),
|
||||||
|
sizeof(BOOLEAN));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT("NtCancelTimer()\n");
|
|
||||||
Status = ObReferenceObjectByHandle(TimerHandle,
|
Status = ObReferenceObjectByHandle(TimerHandle,
|
||||||
TIMER_ALL_ACCESS,
|
TIMER_ALL_ACCESS,
|
||||||
ExTimerType,
|
ExTimerType,
|
||||||
UserMode,
|
PreviousMode,
|
||||||
(PVOID*)&Timer,
|
(PVOID*)&Timer,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
return Status;
|
{
|
||||||
|
BOOLEAN State;
|
||||||
|
KIRQL OldIrql = KeRaiseIrqlToDpcLevel();
|
||||||
|
|
||||||
OldIrql = KeRaiseIrqlToDpcLevel();
|
State = KeCancelTimer(&Timer->Timer);
|
||||||
|
KeRemoveQueueDpc(&Timer->Dpc);
|
||||||
|
KeRemoveQueueApc(&Timer->Apc);
|
||||||
|
Timer->Running = FALSE;
|
||||||
|
|
||||||
State = KeCancelTimer(&Timer->Timer);
|
KeLowerIrql(OldIrql);
|
||||||
KeRemoveQueueDpc(&Timer->Dpc);
|
ObDereferenceObject(Timer);
|
||||||
KeRemoveQueueApc(&Timer->Apc);
|
|
||||||
Timer->Running = FALSE;
|
|
||||||
|
|
||||||
KeLowerIrql(OldIrql);
|
if(CurrentState != NULL)
|
||||||
ObDereferenceObject(Timer);
|
|
||||||
|
|
||||||
if (CurrentState != NULL)
|
|
||||||
{
|
{
|
||||||
*CurrentState = State;
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*CurrentState = State;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,38 +221,75 @@ NtCreateTimer(OUT PHANDLE TimerHandle,
|
||||||
IN TIMER_TYPE TimerType)
|
IN TIMER_TYPE TimerType)
|
||||||
{
|
{
|
||||||
PNTTIMER Timer;
|
PNTTIMER Timer;
|
||||||
NTSTATUS Status;
|
HANDLE hTimer;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT("NtCreateTimer()\n");
|
DPRINT("NtCreateTimer()\n");
|
||||||
Status = ObCreateObject(ExGetPreviousMode(),
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if(PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(TimerHandle,
|
||||||
|
sizeof(HANDLE),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = ObCreateObject(PreviousMode,
|
||||||
ExTimerType,
|
ExTimerType,
|
||||||
ObjectAttributes,
|
ObjectAttributes,
|
||||||
ExGetPreviousMode(),
|
PreviousMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(NTTIMER),
|
sizeof(NTTIMER),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&Timer);
|
(PVOID*)&Timer);
|
||||||
if (!NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
return Status;
|
{
|
||||||
|
KeInitializeTimerEx(&Timer->Timer,
|
||||||
|
TimerType);
|
||||||
|
|
||||||
KeInitializeTimerEx(&Timer->Timer,
|
KeInitializeDpc(&Timer->Dpc,
|
||||||
TimerType);
|
&ExpTimerDpcRoutine,
|
||||||
|
Timer);
|
||||||
|
|
||||||
KeInitializeDpc(&Timer->Dpc,
|
Timer->Running = FALSE;
|
||||||
&ExpTimerDpcRoutine,
|
|
||||||
Timer);
|
|
||||||
|
|
||||||
Timer->Running = FALSE;
|
Status = ObInsertObject ((PVOID)Timer,
|
||||||
|
NULL,
|
||||||
Status = ObInsertObject ((PVOID)Timer,
|
DesiredAccess,
|
||||||
NULL,
|
0,
|
||||||
DesiredAccess,
|
NULL,
|
||||||
0,
|
&hTimer);
|
||||||
NULL,
|
ObDereferenceObject(Timer);
|
||||||
TimerHandle);
|
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
ObDereferenceObject(Timer);
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*TimerHandle = hTimer;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -228,15 +300,54 @@ NtOpenTimer(OUT PHANDLE TimerHandle,
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
IN POBJECT_ATTRIBUTES ObjectAttributes)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
HANDLE hTimer;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
DPRINT("NtOpenTimer()\n");
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if(PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(TimerHandle,
|
||||||
|
sizeof(HANDLE),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObOpenObjectByName(ObjectAttributes,
|
Status = ObOpenObjectByName(ObjectAttributes,
|
||||||
ExTimerType,
|
ExTimerType,
|
||||||
NULL,
|
NULL,
|
||||||
UserMode,
|
PreviousMode,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
NULL,
|
NULL,
|
||||||
TimerHandle);
|
&hTimer);
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
*TimerHandle = hTimer;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,58 +359,67 @@ NtQueryTimer(IN HANDLE TimerHandle,
|
||||||
IN ULONG TimerInformationLength,
|
IN ULONG TimerInformationLength,
|
||||||
OUT PULONG ReturnLength OPTIONAL)
|
OUT PULONG ReturnLength OPTIONAL)
|
||||||
{
|
{
|
||||||
PNTTIMER Timer;
|
PNTTIMER Timer;
|
||||||
TIMER_BASIC_INFORMATION SafeTimerInformation;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
ULONG ResultLength;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(TimerHandle,
|
PreviousMode = ExGetPreviousMode();
|
||||||
TIMER_QUERY_STATE,
|
|
||||||
ExTimerType,
|
|
||||||
(KPROCESSOR_MODE)KeGetPreviousMode(),
|
|
||||||
(PVOID*)&Timer,
|
|
||||||
NULL);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TimerInformationClass != TimerBasicInformation)
|
DefaultQueryInfoBufferCheck(TimerInformationClass,
|
||||||
{
|
ExTimerInfoClass,
|
||||||
ObDereferenceObject(Timer);
|
TimerInformation,
|
||||||
return(STATUS_INVALID_INFO_CLASS);
|
TimerInformationLength,
|
||||||
}
|
ReturnLength,
|
||||||
if (TimerInformationLength < sizeof(TIMER_BASIC_INFORMATION))
|
PreviousMode,
|
||||||
{
|
&Status);
|
||||||
ObDereferenceObject(Timer);
|
if(!NT_SUCCESS(Status))
|
||||||
return(STATUS_INFO_LENGTH_MISMATCH);
|
{
|
||||||
}
|
DPRINT1("NtQueryTimer() failed, Status: 0x%x\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&SafeTimerInformation.TimeRemaining, &Timer->Timer.DueTime,
|
Status = ObReferenceObjectByHandle(TimerHandle,
|
||||||
sizeof(LARGE_INTEGER));
|
TIMER_QUERY_STATE,
|
||||||
SafeTimerInformation.SignalState = (BOOLEAN)Timer->Timer.Header.SignalState;
|
ExTimerType,
|
||||||
ResultLength = sizeof(TIMER_BASIC_INFORMATION);
|
PreviousMode,
|
||||||
|
(PVOID*)&Timer,
|
||||||
|
NULL);
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
switch(TimerInformationClass)
|
||||||
|
{
|
||||||
|
case TimerBasicInformation:
|
||||||
|
{
|
||||||
|
PTIMER_BASIC_INFORMATION BasicInfo = (PTIMER_BASIC_INFORMATION)TimerInformation;
|
||||||
|
|
||||||
Status = MmCopyToCaller(TimerInformation, &SafeTimerInformation,
|
_SEH_TRY
|
||||||
sizeof(TIMER_BASIC_INFORMATION));
|
{
|
||||||
if (!NT_SUCCESS(Status))
|
/* FIXME - interrupt correction */
|
||||||
{
|
BasicInfo->TimeRemaining.QuadPart = Timer->Timer.DueTime.QuadPart;
|
||||||
ObDereferenceObject(Timer);
|
BasicInfo->SignalState = (BOOLEAN)Timer->Timer.Header.SignalState;
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ReturnLength != NULL)
|
if(ReturnLength != NULL)
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(ReturnLength, &ResultLength,
|
*ReturnLength = sizeof(TIMER_BASIC_INFORMATION);
|
||||||
sizeof(ULONG));
|
}
|
||||||
if (!NT_SUCCESS(Status))
|
}
|
||||||
{
|
_SEH_HANDLE
|
||||||
ObDereferenceObject(Timer);
|
{
|
||||||
return(Status);
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
}
|
||||||
}
|
_SEH_END;
|
||||||
ObDereferenceObject(Timer);
|
break;
|
||||||
return(STATUS_SUCCESS);
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(Timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -313,16 +433,48 @@ NtSetTimer(IN HANDLE TimerHandle,
|
||||||
OUT PBOOLEAN PreviousState OPTIONAL)
|
OUT PBOOLEAN PreviousState OPTIONAL)
|
||||||
{
|
{
|
||||||
PNTTIMER Timer;
|
PNTTIMER Timer;
|
||||||
NTSTATUS Status;
|
|
||||||
BOOLEAN Result;
|
BOOLEAN Result;
|
||||||
BOOLEAN State;
|
BOOLEAN State;
|
||||||
|
LARGE_INTEGER TimerDueTime;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT("NtSetTimer()\n");
|
DPRINT("NtSetTimer()\n");
|
||||||
|
|
||||||
|
PreviousMode = ExGetPreviousMode();
|
||||||
|
|
||||||
|
if(PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(DueTime,
|
||||||
|
sizeof(LARGE_INTEGER),
|
||||||
|
sizeof(ULONG));
|
||||||
|
TimerDueTime = *DueTime;
|
||||||
|
|
||||||
|
if(PreviousState != NULL)
|
||||||
|
{
|
||||||
|
ProbeForWrite(PreviousState,
|
||||||
|
sizeof(BOOLEAN),
|
||||||
|
sizeof(BOOLEAN));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(TimerHandle,
|
Status = ObReferenceObjectByHandle(TimerHandle,
|
||||||
TIMER_ALL_ACCESS,
|
TIMER_ALL_ACCESS,
|
||||||
ExTimerType,
|
ExTimerType,
|
||||||
(KPROCESSOR_MODE)KeGetPreviousMode(),
|
PreviousMode,
|
||||||
(PVOID*)&Timer,
|
(PVOID*)&Timer,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -351,15 +503,15 @@ NtSetTimer(IN HANDLE TimerHandle,
|
||||||
&ExpTimerApcKernelRoutine,
|
&ExpTimerApcKernelRoutine,
|
||||||
(PKRUNDOWN_ROUTINE)NULL,
|
(PKRUNDOWN_ROUTINE)NULL,
|
||||||
(PKNORMAL_ROUTINE)TimerApcRoutine,
|
(PKNORMAL_ROUTINE)TimerApcRoutine,
|
||||||
(KPROCESSOR_MODE)KeGetPreviousMode(),
|
PreviousMode,
|
||||||
TimerContext);
|
TimerContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = KeSetTimerEx(&Timer->Timer,
|
Result = KeSetTimerEx(&Timer->Timer,
|
||||||
*DueTime,
|
TimerDueTime,
|
||||||
Period,
|
Period,
|
||||||
TimerApcRoutine ? &Timer->Dpc : 0 );
|
TimerApcRoutine ? &Timer->Dpc : 0 );
|
||||||
if (Result == TRUE)
|
if (Result)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Timer);
|
ObDereferenceObject(Timer);
|
||||||
DPRINT1( "KeSetTimer says the timer was already running, this shouldn't be\n" );
|
DPRINT1( "KeSetTimer says the timer was already running, this shouldn't be\n" );
|
||||||
|
@ -371,11 +523,19 @@ NtSetTimer(IN HANDLE TimerHandle,
|
||||||
ObDereferenceObject(Timer);
|
ObDereferenceObject(Timer);
|
||||||
|
|
||||||
if (PreviousState != NULL)
|
if (PreviousState != NULL)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
*PreviousState = State;
|
*PreviousState = State;
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue