- protect access to buffers in NtCreateThread and NtOpenThread

- fix incorrect usage of PSEH in NtCreateThread

svn path=/trunk/; revision=18859
This commit is contained in:
Thomas Bluemel 2005-10-29 21:33:57 +00:00
parent f3922196a5
commit 0d70a37f3b
2 changed files with 66 additions and 40 deletions

View file

@ -308,14 +308,14 @@ PsAssignImpersonationToken(PETHREAD Thread,
ImpersonationLevel = 0; ImpersonationLevel = 0;
} }
PsImpersonateClient(Thread, Status = PsImpersonateClient(Thread,
Token, Token,
FALSE, FALSE,
FALSE, FALSE,
ImpersonationLevel); ImpersonationLevel);
if (Token != NULL) ObDereferenceObject(Token); if (Token != NULL) ObDereferenceObject(Token);
return(STATUS_SUCCESS); return Status;
} }
/* /*
@ -379,10 +379,7 @@ PsImpersonateClient(IN PETHREAD Thread,
Thread->ImpersonationInfo->EffectiveOnly = EffectiveOnly; Thread->ImpersonationInfo->EffectiveOnly = EffectiveOnly;
Thread->ImpersonationInfo->Token = Token; Thread->ImpersonationInfo->Token = Token;
ObReferenceObjectByPointer(Token, ObReferenceObject(Token);
0,
SepTokenObjectType,
KernelMode);
Thread->ActiveImpersonationInfo = TRUE; Thread->ActiveImpersonationInfo = TRUE;

View file

@ -587,6 +587,8 @@ NtCreateThread(OUT PHANDLE ThreadHandle,
IN BOOLEAN CreateSuspended) IN BOOLEAN CreateSuspended)
{ {
INITIAL_TEB SafeInitialTeb; INITIAL_TEB SafeInitialTeb;
CONTEXT SafeContext;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE(); PAGED_CODE();
@ -595,6 +597,11 @@ NtCreateThread(OUT PHANDLE ThreadHandle,
if(KeGetPreviousMode() != KernelMode) { if(KeGetPreviousMode() != KernelMode) {
if (ThreadContext == NULL) {
DPRINT1("No context for User-Mode Thread!!\n");
return STATUS_INVALID_PARAMETER;
}
_SEH_TRY { _SEH_TRY {
ProbeForWriteHandle(ThreadHandle); ProbeForWriteHandle(ThreadHandle);
@ -608,40 +615,37 @@ NtCreateThread(OUT PHANDLE ThreadHandle,
if(ThreadContext != NULL) { if(ThreadContext != NULL) {
ProbeForRead(ThreadContext, ProbeForRead(ThreadContext,
sizeof(CONTEXT), sizeof(CONTEXT),
sizeof(ULONG)); sizeof(ULONG));
SafeContext = *ThreadContext;
} else { ThreadContext = &SafeContext;
DPRINT1("No context for User-Mode Thread!!\n");
return STATUS_INVALID_PARAMETER;
} }
ProbeForRead(InitialTeb, ProbeForRead(InitialTeb,
sizeof(INITIAL_TEB), sizeof(INITIAL_TEB),
sizeof(ULONG)); sizeof(ULONG));
SafeInitialTeb = *InitialTeb;
InitialTeb = &SafeInitialTeb;
} _SEH_HANDLE { } _SEH_HANDLE {
return _SEH_GetExceptionCode(); Status = _SEH_GetExceptionCode();
} _SEH_END; } _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 */ /* Call the shared function */
return PspCreateThread(ThreadHandle, /* FIXME - not protected! */ return PspCreateThread(ThreadHandle,
DesiredAccess, DesiredAccess,
ObjectAttributes, ObjectAttributes,
ProcessHandle, ProcessHandle,
NULL, NULL,
ClientId, /* FIXME - not protected! */ ClientId,
ThreadContext, /* FIXME - not protected! */ ThreadContext,
InitialTeb, /* FIXME - not protected! */ InitialTeb,
CreateSuspended, CreateSuspended,
NULL, NULL,
NULL); NULL);
@ -654,17 +658,21 @@ NTSTATUS
STDCALL STDCALL
NtOpenThread(OUT PHANDLE ThreadHandle, NtOpenThread(OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL) IN PCLIENT_ID ClientId OPTIONAL)
{ {
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); KPROCESSOR_MODE PreviousMode;
CLIENT_ID SafeClientId; CLIENT_ID SafeClientId;
HANDLE hThread = 0; ULONG Attributes = 0;
HANDLE hThread = NULL;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PETHREAD Thread; PETHREAD Thread;
BOOLEAN HasObjectName = FALSE;
PAGED_CODE(); PAGED_CODE();
PreviousMode = KeGetPreviousMode();
/* Probe the paraemeters */ /* Probe the paraemeters */
if(PreviousMode != KernelMode) if(PreviousMode != KernelMode)
{ {
@ -681,6 +689,14 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
SafeClientId = *ClientId; SafeClientId = *ClientId;
ClientId = &SafeClientId; 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 _SEH_HANDLE
{ {
@ -690,9 +706,20 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
if(!NT_SUCCESS(Status)) return Status; 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 */ /* Open by name if one was given */
if (ObjectAttributes->ObjectName) /* FIXME - neither probed nor protected! */ if (HasObjectName)
{ {
/* Open it */ /* Open it */
Status = ObOpenObjectByName(ObjectAttributes, Status = ObOpenObjectByName(ObjectAttributes,
@ -703,22 +730,19 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
NULL, NULL,
&hThread); &hThread);
if (Status != STATUS_SUCCESS) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Could not open object by name\n"); 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 */ /* Open by Thread ID */
if (ClientId->UniqueProcess) /* FIXME - neither probed nor protected! */ if (ClientId->UniqueProcess)
{ {
/* Get the Process */ /* Get the Process */
DPRINT("Opening by Process ID: %x\n", ClientId->UniqueProcess); /* FIXME - neither probed nor protected! */ DPRINT("Opening by Process ID: %x\n", ClientId->UniqueProcess);
Status = PsLookupProcessThreadByCid(ClientId, /* FIXME - neither probed nor protected! */ Status = PsLookupProcessThreadByCid(ClientId,
NULL, NULL,
&Thread); &Thread);
} }
@ -738,7 +762,7 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
/* Open the Thread Object */ /* Open the Thread Object */
Status = ObOpenObjectByPointer(Thread, Status = ObOpenObjectByPointer(Thread,
ObjectAttributes->Attributes, /* FIXME - neither probed nor protected! */ Attributes,
NULL, NULL,
DesiredAccess, DesiredAccess,
PsThreadType, PsThreadType,
@ -752,6 +776,11 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
/* Dereference the thread */ /* Dereference the thread */
ObDereferenceObject(Thread); ObDereferenceObject(Thread);
} }
else
{
/* neither an object name nor a client id was passed */
return STATUS_INVALID_PARAMETER_MIX;
}
/* Write back the handle */ /* Write back the handle */
if(NT_SUCCESS(Status)) if(NT_SUCCESS(Status))