Author: ion
Date: Sun Jul 23 21:56:57 2006
New Revision: 23250
URL:
http://svn.reactos.org/svn/reactos?rev=23250&view=rev
Log:
- 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.
Modified:
trunk/reactos/ntoskrnl/KrnlFun.c
trunk/reactos/ntoskrnl/ps/thread.c
Modified: trunk/reactos/ntoskrnl/KrnlFun.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=232…
==============================================================================
--- trunk/reactos/ntoskrnl/KrnlFun.c (original)
+++ trunk/reactos/ntoskrnl/KrnlFun.c Sun Jul 23 21:56:57 2006
@@ -27,9 +27,7 @@
// Ps:
// - Figure out why processes don't die.
// - Generate process cookie for user-more thread.
-// - Add security calls where necessary for thread creation.
// - Add tracing.
-// - Add failure/race checks for thread creation.
//
// Ob:
// - Possible bug in deferred deletion under Cc Rewrite branch.
Modified: trunk/reactos/ntoskrnl/ps/thread.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/thread.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/ps/thread.c (original)
+++ trunk/reactos/ntoskrnl/ps/thread.c Sun Jul 23 21:56:57 2006
@@ -144,11 +144,14 @@
PTEB TebBase = NULL;
KIRQL OldIrql;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
- NTSTATUS Status;
+ NTSTATUS Status, AccessStatus;
HANDLE_TABLE_ENTRY CidEntry;
ACCESS_STATE LocalAccessState;
PACCESS_STATE AccessState = &LocalAccessState;
AUX_DATA AuxData;
+ BOOLEAN Result, SdAllocated;
+ PSECURITY_DESCRIPTOR SecurityDescriptor;
+ SECURITY_SUBJECT_CONTEXT SubjectContext;
PAGED_CODE();
/* If we were called from PsCreateSystemThread, then we're kernel mode */
@@ -402,8 +405,26 @@
{
/* Get the exception code */
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;
+ if (!NT_SUCCESS(Status)) return Status;
}
else
{
@@ -418,8 +439,70 @@
KeQuerySystemTime(&Thread->CreateTime);
ASSERT(!(Thread->CreateTime.HighPart & 0xF0000000));
- /* Set the thread access mask */
- Thread->GrantedAccess = THREAD_ALL_ACCESS;
+ /* Make sure the thread isn't dead */
+ 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 */
OldIrql = KeAcquireDispatcherDatabaseLock ();