mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 10:45:24 +00:00
- Add ObGetObjectSecurity calls like in PspCreateProcess to check the thread's level of access towards itself.
- Add code to handle two more failure (the last, afaics) cases. - Get rid of 2 kernel fun entries. svn path=/trunk/; revision=23250
This commit is contained in:
parent
3774a4b259
commit
e685ced6d0
|
@ -27,9 +27,7 @@
|
||||||
// Ps:
|
// Ps:
|
||||||
// - Figure out why processes don't die.
|
// - Figure out why processes don't die.
|
||||||
// - Generate process cookie for user-more thread.
|
// - Generate process cookie for user-more thread.
|
||||||
// - Add security calls where necessary for thread creation.
|
|
||||||
// - Add tracing.
|
// - Add tracing.
|
||||||
// - Add failure/race checks for thread creation.
|
|
||||||
//
|
//
|
||||||
// Ob:
|
// Ob:
|
||||||
// - Possible bug in deferred deletion under Cc Rewrite branch.
|
// - Possible bug in deferred deletion under Cc Rewrite branch.
|
||||||
|
|
|
@ -144,11 +144,14 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
||||||
PTEB TebBase = NULL;
|
PTEB TebBase = NULL;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status;
|
NTSTATUS Status, AccessStatus;
|
||||||
HANDLE_TABLE_ENTRY CidEntry;
|
HANDLE_TABLE_ENTRY CidEntry;
|
||||||
ACCESS_STATE LocalAccessState;
|
ACCESS_STATE LocalAccessState;
|
||||||
PACCESS_STATE AccessState = &LocalAccessState;
|
PACCESS_STATE AccessState = &LocalAccessState;
|
||||||
AUX_DATA AuxData;
|
AUX_DATA AuxData;
|
||||||
|
BOOLEAN Result, SdAllocated;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
|
SECURITY_SUBJECT_CONTEXT SubjectContext;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* If we were called from PsCreateSystemThread, then we're kernel mode */
|
/* If we were called from PsCreateSystemThread, then we're kernel mode */
|
||||||
|
@ -402,8 +405,26 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
||||||
{
|
{
|
||||||
/* Get the exception code */
|
/* Get the exception code */
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
|
|
||||||
|
/* Thread insertion failed, thread is dead */
|
||||||
|
InterlockedOr(&Thread->CrossThreadFlags, CT_DEAD_THREAD_BIT);
|
||||||
|
|
||||||
|
/* If we were suspended, wake it up */
|
||||||
|
if (CreateSuspended) KeResumeThread(&Thread->Tcb);
|
||||||
|
|
||||||
|
/* Dispatch thread */
|
||||||
|
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||||
|
KiReadyThread(&Thread->Tcb);
|
||||||
|
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||||
|
|
||||||
|
/* Dereference it, leaving only the keep-alive */
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
|
||||||
|
/* Close its handle, killing it */
|
||||||
|
ObCloseHandle(ThreadHandle, PreviousMode);
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -418,8 +439,70 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
||||||
KeQuerySystemTime(&Thread->CreateTime);
|
KeQuerySystemTime(&Thread->CreateTime);
|
||||||
ASSERT(!(Thread->CreateTime.HighPart & 0xF0000000));
|
ASSERT(!(Thread->CreateTime.HighPart & 0xF0000000));
|
||||||
|
|
||||||
/* Set the thread access mask */
|
/* Make sure the thread isn't dead */
|
||||||
Thread->GrantedAccess = THREAD_ALL_ACCESS;
|
if (!Thread->DeadThread)
|
||||||
|
{
|
||||||
|
/* Get the thread's SD */
|
||||||
|
Status = ObGetObjectSecurity(Thread,
|
||||||
|
&SecurityDescriptor,
|
||||||
|
&SdAllocated);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Thread insertion failed, thread is dead */
|
||||||
|
InterlockedOr(&Thread->CrossThreadFlags, CT_DEAD_THREAD_BIT);
|
||||||
|
|
||||||
|
/* If we were suspended, wake it up */
|
||||||
|
if (CreateSuspended) KeResumeThread(&Thread->Tcb);
|
||||||
|
|
||||||
|
/* Dispatch thread */
|
||||||
|
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||||
|
KiReadyThread(&Thread->Tcb);
|
||||||
|
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||||
|
|
||||||
|
/* Dereference it, leaving only the keep-alive */
|
||||||
|
ObDereferenceObject(Thread);
|
||||||
|
|
||||||
|
/* Close its handle, killing it */
|
||||||
|
ObCloseHandle(ThreadHandle, PreviousMode);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the subject context */
|
||||||
|
SubjectContext.ProcessAuditId = Process;
|
||||||
|
SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process);
|
||||||
|
SubjectContext.ClientToken = NULL;
|
||||||
|
|
||||||
|
/* Do the access check */
|
||||||
|
if (!SecurityDescriptor) DPRINT1("FIX PS SDs!!\n");
|
||||||
|
Result = SeAccessCheck(SecurityDescriptor,
|
||||||
|
&SubjectContext,
|
||||||
|
FALSE,
|
||||||
|
MAXIMUM_ALLOWED,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&PsThreadType->TypeInfo.GenericMapping,
|
||||||
|
PreviousMode,
|
||||||
|
&Thread->GrantedAccess,
|
||||||
|
&AccessStatus);
|
||||||
|
|
||||||
|
/* Dereference the token and let go the SD */
|
||||||
|
ObFastDereferenceObject(&Process->Token,
|
||||||
|
SubjectContext.PrimaryToken);
|
||||||
|
ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated);
|
||||||
|
|
||||||
|
/* Remove access if it failed */
|
||||||
|
if (!Result) Process->GrantedAccess = 0;
|
||||||
|
|
||||||
|
/* Set least some minimum access */
|
||||||
|
Thread->GrantedAccess |= (THREAD_TERMINATE |
|
||||||
|
THREAD_SET_INFORMATION |
|
||||||
|
THREAD_QUERY_INFORMATION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Set the thread access mask to maximum */
|
||||||
|
Thread->GrantedAccess = THREAD_ALL_ACCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* Dispatch thread */
|
/* Dispatch thread */
|
||||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||||
|
|
Loading…
Reference in a new issue