From a725df1b30397ab49ac4d34cde4ef1ba2b501ba9 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sat, 29 Jan 2005 12:24:15 +0000 Subject: [PATCH] securely access buffers in NtSetContextThread() and NtGetContextThread() svn path=/trunk/; revision=13360 --- reactos/ntoskrnl/ps/debug.c | 128 ++++++++++++++++++++++-------------- 1 file changed, 79 insertions(+), 49 deletions(-) diff --git a/reactos/ntoskrnl/ps/debug.c b/reactos/ntoskrnl/ps/debug.c index 07351e02b6f..0a74fe8cbc8 100644 --- a/reactos/ntoskrnl/ps/debug.c +++ b/reactos/ntoskrnl/ps/debug.c @@ -186,28 +186,43 @@ NtGetContextThread(IN HANDLE ThreadHandle, OUT PCONTEXT ThreadContext) { PETHREAD Thread; - NTSTATUS Status; CONTEXT Context; KAPC Apc; KEVENT Event; - NTSTATUS AStatus; + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PreviousMode = ExGetPreviousMode(); - Status = MmCopyFromCaller(&Context, ThreadContext, sizeof(CONTEXT)); - 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; } + } + Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_GET_CONTEXT, PsThreadType, - UserMode, + PreviousMode, (PVOID*)&Thread, NULL); - if (! NT_SUCCESS(Status)) - { - return Status; - } - if (Thread == PsGetCurrentThread()) + if(NT_SUCCESS(Status)) + { + if(Thread == PsGetCurrentThread()) { /* * I don't know if trying to get your own context makes much @@ -215,15 +230,13 @@ NtGetContextThread(IN HANDLE ThreadHandle, */ KeTrapFrameToContext(Thread->Tcb.TrapFrame, &Context); - Status = STATUS_SUCCESS; } - else + else { KeInitializeEvent(&Event, NotificationEvent, - FALSE); - AStatus = STATUS_SUCCESS; - + FALSE); + KeInitializeApc(&Apc, &Thread->Tcb, OriginalApcEnvironment, @@ -234,7 +247,7 @@ NtGetContextThread(IN HANDLE ThreadHandle, (PVOID)&Context); if (!KeInsertQueueApc(&Apc, (PVOID)&Event, - (PVOID)&AStatus, + (PVOID)&Status, IO_NO_INCREMENT)) { Status = STATUS_THREAD_IS_TERMINATING; @@ -243,21 +256,27 @@ NtGetContextThread(IN HANDLE ThreadHandle, { Status = KeWaitForSingleObject(&Event, 0, - UserMode, + KernelMode, FALSE, NULL); - if (NT_SUCCESS(Status) && !NT_SUCCESS(AStatus)) - { - Status = AStatus; - } } } - if (NT_SUCCESS(Status)) + ObDereferenceObject(Thread); + + if(NT_SUCCESS(Status)) { - Status = MmCopyToCaller(ThreadContext, &Context, sizeof(Context)); + _SEH_TRY + { + *ThreadContext = Context; + } + _SEH_HANDLE + { + Status = _SEH_GetExceptionCode(); + } + _SEH_END; } - - ObDereferenceObject(Thread); + } + return Status; } @@ -291,29 +310,45 @@ NtSetContextThread(IN HANDLE ThreadHandle, IN PCONTEXT ThreadContext) { PETHREAD Thread; - NTSTATUS Status; KAPC Apc; KEVENT Event; - NTSTATUS AStatus; CONTEXT Context; - - Status = MmCopyFromCaller(&Context, ThreadContext, sizeof(CONTEXT)); - if (! NT_SUCCESS(Status)) + KPROCESSOR_MODE PreviousMode; + NTSTATUS Status = STATUS_SUCCESS; + + PreviousMode = ExGetPreviousMode(); + + 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; } + } + Status = ObReferenceObjectByHandle(ThreadHandle, THREAD_SET_CONTEXT, PsThreadType, - UserMode, + PreviousMode, (PVOID*)&Thread, NULL); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - if (Thread == PsGetCurrentThread()) + if(NT_SUCCESS(Status)) + { + if (Thread == PsGetCurrentThread()) { /* * I don't know if trying to set your own context makes much @@ -321,14 +356,12 @@ NtSetContextThread(IN HANDLE ThreadHandle, */ KeContextToTrapFrame(&Context, Thread->Tcb.TrapFrame); - Status = STATUS_SUCCESS; } - else + else { KeInitializeEvent(&Event, NotificationEvent, FALSE); - AStatus = STATUS_SUCCESS; KeInitializeApc(&Apc, &Thread->Tcb, @@ -340,7 +373,7 @@ NtSetContextThread(IN HANDLE ThreadHandle, (PVOID)&Context); if (!KeInsertQueueApc(&Apc, (PVOID)&Event, - (PVOID)&AStatus, + (PVOID)&Status, IO_NO_INCREMENT)) { Status = STATUS_THREAD_IS_TERMINATING; @@ -349,17 +382,14 @@ NtSetContextThread(IN HANDLE ThreadHandle, { Status = KeWaitForSingleObject(&Event, 0, - UserMode, + KernelMode, FALSE, - NULL); - if (NT_SUCCESS(Status) && !NT_SUCCESS(AStatus)) - { - Status = AStatus; - } + NULL); } } - - ObDereferenceObject(Thread); + ObDereferenceObject(Thread); + } + return Status; }