mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 08:23:01 +00:00
securely access buffers in NtSetContextThread() and NtGetContextThread()
svn path=/trunk/; revision=13360
This commit is contained in:
parent
1291972098
commit
a725df1b30
1 changed files with 79 additions and 49 deletions
|
@ -186,28 +186,43 @@ NtGetContextThread(IN HANDLE ThreadHandle,
|
||||||
OUT PCONTEXT ThreadContext)
|
OUT PCONTEXT ThreadContext)
|
||||||
{
|
{
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
NTSTATUS Status;
|
|
||||||
CONTEXT Context;
|
CONTEXT Context;
|
||||||
KAPC Apc;
|
KAPC Apc;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
NTSTATUS AStatus;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
Status = MmCopyFromCaller(&Context, ThreadContext, sizeof(CONTEXT));
|
PreviousMode = ExGetPreviousMode();
|
||||||
if (! NT_SUCCESS(Status))
|
|
||||||
|
if(PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(ThreadContext,
|
||||||
|
sizeof(CONTEXT),
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ThreadHandle,
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
THREAD_GET_CONTEXT,
|
THREAD_GET_CONTEXT,
|
||||||
PsThreadType,
|
PsThreadType,
|
||||||
UserMode,
|
PreviousMode,
|
||||||
(PVOID*)&Thread,
|
(PVOID*)&Thread,
|
||||||
NULL);
|
NULL);
|
||||||
if (! NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
if(Thread == PsGetCurrentThread())
|
||||||
}
|
|
||||||
if (Thread == PsGetCurrentThread())
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* I don't know if trying to get your own context makes much
|
* I don't know if trying to get your own context makes much
|
||||||
|
@ -215,14 +230,12 @@ NtGetContextThread(IN HANDLE ThreadHandle,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
KeTrapFrameToContext(Thread->Tcb.TrapFrame, &Context);
|
KeTrapFrameToContext(Thread->Tcb.TrapFrame, &Context);
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KeInitializeEvent(&Event,
|
KeInitializeEvent(&Event,
|
||||||
NotificationEvent,
|
NotificationEvent,
|
||||||
FALSE);
|
FALSE);
|
||||||
AStatus = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
KeInitializeApc(&Apc,
|
KeInitializeApc(&Apc,
|
||||||
&Thread->Tcb,
|
&Thread->Tcb,
|
||||||
|
@ -234,7 +247,7 @@ NtGetContextThread(IN HANDLE ThreadHandle,
|
||||||
(PVOID)&Context);
|
(PVOID)&Context);
|
||||||
if (!KeInsertQueueApc(&Apc,
|
if (!KeInsertQueueApc(&Apc,
|
||||||
(PVOID)&Event,
|
(PVOID)&Event,
|
||||||
(PVOID)&AStatus,
|
(PVOID)&Status,
|
||||||
IO_NO_INCREMENT))
|
IO_NO_INCREMENT))
|
||||||
{
|
{
|
||||||
Status = STATUS_THREAD_IS_TERMINATING;
|
Status = STATUS_THREAD_IS_TERMINATING;
|
||||||
|
@ -243,21 +256,27 @@ NtGetContextThread(IN HANDLE ThreadHandle,
|
||||||
{
|
{
|
||||||
Status = KeWaitForSingleObject(&Event,
|
Status = KeWaitForSingleObject(&Event,
|
||||||
0,
|
0,
|
||||||
UserMode,
|
KernelMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
if (NT_SUCCESS(Status) && !NT_SUCCESS(AStatus))
|
}
|
||||||
|
}
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = AStatus;
|
_SEH_TRY
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(ThreadContext, &Context, sizeof(Context));
|
*ThreadContext = Context;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,28 +310,44 @@ NtSetContextThread(IN HANDLE ThreadHandle,
|
||||||
IN PCONTEXT ThreadContext)
|
IN PCONTEXT ThreadContext)
|
||||||
{
|
{
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
NTSTATUS Status;
|
|
||||||
KAPC Apc;
|
KAPC Apc;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
NTSTATUS AStatus;
|
|
||||||
CONTEXT Context;
|
CONTEXT Context;
|
||||||
|
KPROCESSOR_MODE PreviousMode;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
Status = MmCopyFromCaller(&Context, ThreadContext, sizeof(CONTEXT));
|
PreviousMode = ExGetPreviousMode();
|
||||||
if (! NT_SUCCESS(Status))
|
|
||||||
|
if(PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(ThreadContext,
|
||||||
|
sizeof(CONTEXT),
|
||||||
|
sizeof(ULONG));
|
||||||
|
Context = *ThreadContext;
|
||||||
|
ThreadContext = &Context;
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(ThreadHandle,
|
Status = ObReferenceObjectByHandle(ThreadHandle,
|
||||||
THREAD_SET_CONTEXT,
|
THREAD_SET_CONTEXT,
|
||||||
PsThreadType,
|
PsThreadType,
|
||||||
UserMode,
|
PreviousMode,
|
||||||
(PVOID*)&Thread,
|
(PVOID*)&Thread,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Thread == PsGetCurrentThread())
|
if (Thread == PsGetCurrentThread())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -321,14 +356,12 @@ NtSetContextThread(IN HANDLE ThreadHandle,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
KeContextToTrapFrame(&Context, Thread->Tcb.TrapFrame);
|
KeContextToTrapFrame(&Context, Thread->Tcb.TrapFrame);
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
KeInitializeEvent(&Event,
|
KeInitializeEvent(&Event,
|
||||||
NotificationEvent,
|
NotificationEvent,
|
||||||
FALSE);
|
FALSE);
|
||||||
AStatus = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
KeInitializeApc(&Apc,
|
KeInitializeApc(&Apc,
|
||||||
&Thread->Tcb,
|
&Thread->Tcb,
|
||||||
|
@ -340,7 +373,7 @@ NtSetContextThread(IN HANDLE ThreadHandle,
|
||||||
(PVOID)&Context);
|
(PVOID)&Context);
|
||||||
if (!KeInsertQueueApc(&Apc,
|
if (!KeInsertQueueApc(&Apc,
|
||||||
(PVOID)&Event,
|
(PVOID)&Event,
|
||||||
(PVOID)&AStatus,
|
(PVOID)&Status,
|
||||||
IO_NO_INCREMENT))
|
IO_NO_INCREMENT))
|
||||||
{
|
{
|
||||||
Status = STATUS_THREAD_IS_TERMINATING;
|
Status = STATUS_THREAD_IS_TERMINATING;
|
||||||
|
@ -349,17 +382,14 @@ NtSetContextThread(IN HANDLE ThreadHandle,
|
||||||
{
|
{
|
||||||
Status = KeWaitForSingleObject(&Event,
|
Status = KeWaitForSingleObject(&Event,
|
||||||
0,
|
0,
|
||||||
UserMode,
|
KernelMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
if (NT_SUCCESS(Status) && !NT_SUCCESS(AStatus))
|
|
||||||
{
|
|
||||||
Status = AStatus;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObDereferenceObject(Thread);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue