mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- 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:
parent
f3922196a5
commit
0d70a37f3b
2 changed files with 66 additions and 40 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue