- protect access to buffers in NtCreateThread and NtOpenThread - fix incorrect usage of PSEH in NtCreateThread Modified: trunk/reactos/ntoskrnl/ps/security.c Modified: trunk/reactos/ntoskrnl/ps/thread.c _____
Modified: trunk/reactos/ntoskrnl/ps/security.c --- trunk/reactos/ntoskrnl/ps/security.c 2005-10-29 21:20:50 UTC (rev 18858) +++ trunk/reactos/ntoskrnl/ps/security.c 2005-10-29 21:33:57 UTC (rev 18859) @@ -308,14 +308,14 @@
ImpersonationLevel = 0; }
- PsImpersonateClient(Thread, - Token, - FALSE, - FALSE, - ImpersonationLevel); + Status = PsImpersonateClient(Thread, + Token, + FALSE, + FALSE, + ImpersonationLevel);
if (Token != NULL) ObDereferenceObject(Token); - return(STATUS_SUCCESS); + return Status; }
/* @@ -379,10 +379,7 @@ Thread->ImpersonationInfo->EffectiveOnly = EffectiveOnly; Thread->ImpersonationInfo->Token = Token;
- ObReferenceObjectByPointer(Token, - 0, - SepTokenObjectType, - KernelMode); + ObReferenceObject(Token);
Thread->ActiveImpersonationInfo = TRUE;
_____
Modified: trunk/reactos/ntoskrnl/ps/thread.c --- trunk/reactos/ntoskrnl/ps/thread.c 2005-10-29 21:20:50 UTC (rev 18858) +++ trunk/reactos/ntoskrnl/ps/thread.c 2005-10-29 21:33:57 UTC (rev 18859) @@ -587,6 +587,8 @@
IN BOOLEAN CreateSuspended) { INITIAL_TEB SafeInitialTeb; + CONTEXT SafeContext; + NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
@@ -595,6 +597,11 @@
if(KeGetPreviousMode() != KernelMode) {
+ if (ThreadContext == NULL) { + DPRINT1("No context for User-Mode Thread!!\n"); + return STATUS_INVALID_PARAMETER; + } + _SEH_TRY {
ProbeForWriteHandle(ThreadHandle); @@ -608,40 +615,37 @@
if(ThreadContext != NULL) {
- ProbeForRead(ThreadContext, - sizeof(CONTEXT), - sizeof(ULONG)); - - } else { - - DPRINT1("No context for User-Mode Thread!!\n"); - return STATUS_INVALID_PARAMETER; + ProbeForRead(ThreadContext, + sizeof(CONTEXT), + sizeof(ULONG)); + SafeContext = *ThreadContext; + ThreadContext = &SafeContext; }
ProbeForRead(InitialTeb, sizeof(INITIAL_TEB), sizeof(ULONG)); + SafeInitialTeb = *InitialTeb; + InitialTeb = &SafeInitialTeb;
} _SEH_HANDLE {
- return _SEH_GetExceptionCode(); + Status = _SEH_GetExceptionCode();
} _SEH_END; + + if (!NT_SUCCESS(Status)) return Status; }
- /* Use probed data for the Initial TEB */ - SafeInitialTeb = *InitialTeb; /* FIXME - not protected! */ - InitialTeb = &SafeInitialTeb; - /* Call the shared function */ - return PspCreateThread(ThreadHandle, /* FIXME - not protected! */ + return PspCreateThread(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, NULL, - ClientId, /* FIXME - not protected! */ - ThreadContext, /* FIXME - not protected! */ - InitialTeb, /* FIXME - not protected! */ + ClientId, + ThreadContext, + InitialTeb, CreateSuspended, NULL, NULL); @@ -654,17 +658,21 @@ STDCALL NtOpenThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL) { - KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); + KPROCESSOR_MODE PreviousMode; CLIENT_ID SafeClientId; - HANDLE hThread = 0; + ULONG Attributes = 0; + HANDLE hThread = NULL; NTSTATUS Status = STATUS_SUCCESS; PETHREAD Thread; + BOOLEAN HasObjectName = FALSE;
PAGED_CODE();
+ PreviousMode = KeGetPreviousMode(); + /* Probe the paraemeters */ if(PreviousMode != KernelMode) { @@ -681,6 +689,14 @@ SafeClientId = *ClientId; ClientId = &SafeClientId; } + + /* just probe the object attributes structure, don't capture it + completely. This is done later if necessary */ + ProbeForRead(ObjectAttributes, + sizeof(OBJECT_ATTRIBUTES), + sizeof(ULONG)); + HasObjectName = (ObjectAttributes->ObjectName != NULL); + Attributes = ObjectAttributes->Attributes; } _SEH_HANDLE { @@ -690,9 +706,20 @@
if(!NT_SUCCESS(Status)) return Status; } + else + { + HasObjectName = (ObjectAttributes->ObjectName != NULL); + Attributes = ObjectAttributes->Attributes; + } + + if (HasObjectName && ClientId != NULL) + { + /* can't pass both, n object name and a client id */ + return STATUS_INVALID_PARAMETER_MIX; + }
/* Open by name if one was given */ - if (ObjectAttributes->ObjectName) /* FIXME - neither probed nor protected! */ + if (HasObjectName) { /* Open it */ Status = ObOpenObjectByName(ObjectAttributes, @@ -703,22 +730,19 @@ NULL, &hThread);
- if (Status != STATUS_SUCCESS) + if (!NT_SUCCESS(Status)) { DPRINT1("Could not open object by name\n"); } - /* FIXME - would be a good idea to return the handle in case of success! */ - /* Return Status */ - return(Status); } - else if (ClientId) + else if (ClientId != NULL) { /* Open by Thread ID */ - if (ClientId->UniqueProcess) /* FIXME - neither probed nor protected! */ + if (ClientId->UniqueProcess) { /* Get the Process */ - DPRINT("Opening by Process ID: %x\n", ClientId->UniqueProcess); /* FIXME - neither probed nor protected! */ - Status = PsLookupProcessThreadByCid(ClientId, /* FIXME - neither probed nor protected! */ + DPRINT("Opening by Process ID: %x\n", ClientId->UniqueProcess); + Status = PsLookupProcessThreadByCid(ClientId, NULL, &Thread); } @@ -738,7 +762,7 @@
/* Open the Thread Object */ Status = ObOpenObjectByPointer(Thread, - ObjectAttributes->Attributes, /* FIXME - neither probed nor protected! */ + Attributes, NULL, DesiredAccess, PsThreadType, @@ -752,6 +776,11 @@ /* Dereference the thread */ ObDereferenceObject(Thread); } + else + { + /* neither an object name nor a client id was passed */ + return STATUS_INVALID_PARAMETER_MIX; + }
/* Write back the handle */ if(NT_SUCCESS(Status))