From 9522e0a02b2feaf0f28545cef9d35dc0923226c6 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 18 Jan 2007 09:44:49 +0000 Subject: [PATCH] [25 bug fixes]: - Implement KeReadStateThread. - Fix PspTerminateProcess to handle case where there's no threads in the process. - Fix check in PspTerminateProcess. ObClearProcessHandleTable gets called if there's a debug port, not if there's an object table. - Simplfy PspReapRoutine. - Fix PspExitThread to wait for all other threads before continuing to kill the last thread. Should fix lots of race/wait conditions. - PspExitThread should check for !DeadThread and not !Terminated before determining if it should free the TEB. Also, the DbgK handle should only be closed if the thread isn't already dead. - Fixup formatting of some code to warn less on MSVC. - Fail various APIs if acquiring rundown protection failed. - Fix Process Quantum/Priority settings. - Grant PROCESS_TERMINATE by default. - Add PROCESS_SET_INFORMATION, STANDARD_RIGHTS_ALL and PROCESS_SET_QUOTA to the default process granted access mask. - Initialize process/thread/image notification callbacks durin phase 0 Ps initialization. - The Audit Name belongs to the system process, not the idle process. - Detect more failures in phase 0 startup. - Fix various race conditions/incorrect checks in ps/security.c related to impersonation information. Also allow PspAssignPrimaryToken to be called directly with the token pointer and not only the handle. - Wrap system thread startup stub in SEH and write a SEH filter function to print out debug information when a system thread dies unexpectedly. svn path=/trunk/; revision=25504 --- reactos/ntoskrnl/include/internal/ke.h | 4 + reactos/ntoskrnl/include/internal/lpc.h | 3 +- reactos/ntoskrnl/include/internal/ps.h | 2 +- reactos/ntoskrnl/ke/thrdobj.c | 11 ++ reactos/ntoskrnl/lpc/reply.c | 5 +- reactos/ntoskrnl/lpc/send.c | 2 +- reactos/ntoskrnl/ps/kill.c | 220 +++++++++++++++--------- reactos/ntoskrnl/ps/process.c | 42 ++--- reactos/ntoskrnl/ps/psmgr.c | 41 +++-- reactos/ntoskrnl/ps/security.c | 167 +++++++++++------- reactos/ntoskrnl/ps/thread.c | 69 +++++--- 11 files changed, 355 insertions(+), 211 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 7260f78d4f6..9e213f6f327 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -215,6 +215,10 @@ NTSTATUS NTAPI KeSuspendThread(PKTHREAD Thread); +BOOLEAN +NTAPI +KeReadStateThread(IN PKTHREAD Thread); + BOOLEAN FASTCALL KiSwapContext( diff --git a/reactos/ntoskrnl/include/internal/lpc.h b/reactos/ntoskrnl/include/internal/lpc.h index 5570e81c6dc..2eba4487101 100644 --- a/reactos/ntoskrnl/include/internal/lpc.h +++ b/reactos/ntoskrnl/include/internal/lpc.h @@ -93,7 +93,8 @@ VOID NTAPI LpcpSaveDataInfoMessage( IN PLPCP_PORT_OBJECT Port, - IN PLPCP_MESSAGE Message + IN PLPCP_MESSAGE Message, + IN ULONG LockHeld ); // diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index 0ee2c237568..d167814a82f 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -175,7 +175,7 @@ NTAPI PspSetPrimaryToken( IN PEPROCESS Process, IN HANDLE TokenHandle OPTIONAL, - IN PTOKEN Token OPTIONAL + IN PACCESS_TOKEN Token OPTIONAL ); NTSTATUS diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index 5377642449f..98c00d6a031 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -46,6 +46,17 @@ KeFindNextRightSetAffinity(IN UCHAR Number, return (UCHAR)Result; } + +BOOLEAN +NTAPI +KeReadStateThread(IN PKTHREAD Thread) +{ + ASSERT_THREAD(Thread); + + /* Return signal state */ + return (BOOLEAN)Thread->DispatcherHeader.SignalState; +} + KPRIORITY NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread) diff --git a/reactos/ntoskrnl/lpc/reply.c b/reactos/ntoskrnl/lpc/reply.c index 1e613b02e5b..751564b8666 100644 --- a/reactos/ntoskrnl/lpc/reply.c +++ b/reactos/ntoskrnl/lpc/reply.c @@ -57,7 +57,8 @@ LpcpFreeDataInfoMessage(IN PLPCP_PORT_OBJECT Port, VOID NTAPI LpcpSaveDataInfoMessage(IN PLPCP_PORT_OBJECT Port, - IN PLPCP_MESSAGE Message) + IN PLPCP_MESSAGE Message, + IN ULONG LockFlags) { PAGED_CODE(); @@ -402,7 +403,7 @@ NtReplyWaitReceivePortEx(IN HANDLE PortHandle, if (Message->Request.u2.s2.DataInfoOffset) { /* It does, save it, and don't free the message below */ - LpcpSaveDataInfoMessage(Port, Message); + LpcpSaveDataInfoMessage(Port, Message, 1); Message = NULL; } } diff --git a/reactos/ntoskrnl/lpc/send.c b/reactos/ntoskrnl/lpc/send.c index 8605a70edb7..3658ced2ca4 100644 --- a/reactos/ntoskrnl/lpc/send.c +++ b/reactos/ntoskrnl/lpc/send.c @@ -391,7 +391,7 @@ NtRequestWaitReplyPort(IN HANDLE PortHandle, (Message->Request.u2.s2.DataInfoOffset)) { /* Save the data information */ - LpcpSaveDataInfoMessage(Port, Message); + LpcpSaveDataInfoMessage(Port, Message, 0); } else { diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index da89e57e5f8..d5009c1f5fc 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -18,6 +18,7 @@ LIST_ENTRY PspReaperListHead = {0}; WORK_QUEUE_ITEM PspReaperWorkItem; +LARGE_INTEGER ShortTime = {{-10 * 100 * 1000, -1}}; /* PRIVATE FUNCTIONS *********************************************************/ @@ -81,7 +82,8 @@ NTAPI PspTerminateProcess(IN PEPROCESS Process, IN NTSTATUS ExitStatus) { - PETHREAD Thread = NULL; + PETHREAD Thread; + NTSTATUS Status = STATUS_NOTHING_TO_TERMINATE; PAGED_CODE(); PSTRACE(PS_KILL_DEBUG, "Process: %p ExitStatus: %p\n", Process, ExitStatus); @@ -100,22 +102,26 @@ PspTerminateProcess(IN PEPROCESS Process, InterlockedOr((PLONG)&Process->Flags, PSF_PROCESS_DELETE_BIT); /* Get the first thread */ - Thread = PsGetNextProcessThread(Process, Thread); + Thread = PsGetNextProcessThread(Process, NULL); while (Thread) { /* Kill it */ - PSREFTRACE(Thread); PspTerminateThreadByPointer(Thread, ExitStatus, FALSE); - PSREFTRACE(Thread); Thread = PsGetNextProcessThread(Process, Thread); + + /* We had at least one thread, so termination is OK */ + Status = STATUS_SUCCESS; } - /* Clear the handle table */ - if (Process->ObjectTable) ObClearProcessHandleTable(Process); + /* Check if there was nothing to terminate or if we have a debug port */ + if ((Status == STATUS_NOTHING_TO_TERMINATE) || (Process->DebugPort)) + { + /* Clear the handle table anyway */ + ObClearProcessHandleTable(Process); + } - /* Return success*/ - PSREFTRACE(Process); - return STATUS_SUCCESS; + /* Return status */ + return Status; } NTSTATUS @@ -163,19 +169,16 @@ VOID NTAPI PspReapRoutine(IN PVOID Context) { - PLIST_ENTRY *ListAddr; - PLIST_ENTRY NextEntry; + PSINGLE_LIST_ENTRY NextEntry; PETHREAD Thread; PSTRACE(PS_KILL_DEBUG, "Context: %p\n", Context); - /* Get the Reaper Address Pointer */ - ListAddr = &PspReaperListHead.Flink; - /* Start main loop */ do { /* Write magic value and return the next entry to process */ - NextEntry = InterlockedExchangePointer(ListAddr, (PVOID)1); + NextEntry = InterlockedExchangePointer(&PspReaperListHead.Flink, + (PVOID)1); ASSERT((NextEntry != NULL) && (NextEntry != (PVOID)1)); /* Start inner loop */ @@ -190,15 +193,16 @@ PspReapRoutine(IN PVOID Context) Thread->Tcb.InitialStack = NULL; /* Move to the next entry */ - NextEntry = NextEntry->Flink; + NextEntry = NextEntry->Next; /* Dereference this thread */ ObDereferenceObject(Thread); - PSREFTRACE(Thread); } while ((NextEntry != NULL) && (NextEntry != (PVOID)1)); /* Remove magic value, keep looping if it got changed */ - } while (InterlockedCompareExchangePointer(ListAddr, 0, 1) != (PVOID)1); + } while (InterlockedCompareExchangePointer(&PspReaperListHead.Flink, + 0, + 1) != (PVOID)1); } VOID @@ -245,7 +249,7 @@ PspDeleteProcess(IN PVOID ObjectBody) /* Check if we have a debug port */ if (Process->DebugPort) { - /* Dererence the Debug Port */ + /* Deference the Debug Port */ ObDereferenceObject(Process->DebugPort); Process->DebugPort = NULL; } @@ -253,7 +257,7 @@ PspDeleteProcess(IN PVOID ObjectBody) /* Check if we have an exception port */ if (Process->ExceptionPort) { - /* Dererence the Exception Port */ + /* Deference the Exception Port */ ObDereferenceObject(Process->ExceptionPort); Process->ExceptionPort = NULL; } @@ -261,7 +265,7 @@ PspDeleteProcess(IN PVOID ObjectBody) /* Check if we have a section object */ if (Process->SectionObject) { - /* Dererence the Section Object */ + /* Deference the Section Object */ ObDereferenceObject(Process->SectionObject); Process->SectionObject = NULL; } @@ -279,7 +283,7 @@ PspDeleteProcess(IN PVOID ObjectBody) /* Kill the Object Info */ ObKillProcess(Process); - /* Dettach */ + /* Detach */ KeUnstackDetachProcess(&ApcState); } @@ -295,7 +299,7 @@ PspDeleteProcess(IN PVOID ObjectBody) /* Clean the Address Space */ PspExitProcess(FALSE, Process); - /* Dettach */ + /* Detach */ KeUnstackDetachProcess(&ApcState); /* Completely delete the Address Space */ @@ -303,7 +307,7 @@ PspDeleteProcess(IN PVOID ObjectBody) } /* See if we have a PID */ - if(Process->UniqueProcessId) + if (Process->UniqueProcessId) { /* Delete the PID */ if (!(ExDestroyHandle(PspCidTable, Process->UniqueProcessId))) @@ -331,7 +335,6 @@ PspDeleteProcess(IN PVOID ObjectBody) /* Destroy the Quota Block */ PspDestroyQuotaBlock(Process); - PSREFTRACE(Process); } VOID @@ -368,7 +371,6 @@ PspDeleteThread(IN PVOID ObjectBody) PspDeleteThreadSecurity(Thread); /* Make sure the thread was inserted, before continuing */ - PSREFTRACE(Thread); if (!Process) return; /* Check if the thread list is valid */ @@ -388,8 +390,6 @@ PspDeleteThread(IN PVOID ObjectBody) /* Dereference the Process */ ObDereferenceObject(Process); - PSREFTRACE(Thread); - PSREFTRACE(Process); } /* @@ -404,7 +404,7 @@ PspExitThread(IN NTSTATUS ExitStatus) NTSTATUS Status; PTEB Teb; PEPROCESS CurrentProcess; - PETHREAD Thread; + PETHREAD Thread, OtherThread, PreviousThread = NULL; PVOID DeallocationStack; ULONG Dummy; BOOLEAN Last = FALSE; @@ -421,8 +421,6 @@ PspExitThread(IN NTSTATUS ExitStatus) ASSERT((Thread) == PsGetCurrentThread()); /* Can't terminate a thread if it attached another process */ - PSREFTRACE(Thread); - PSREFTRACE(CurrentProcess); if (KeIsAttachedProcess()) { /* Bugcheck */ @@ -434,7 +432,7 @@ PspExitThread(IN NTSTATUS ExitStatus) } /* Lower to Passive Level */ - KfLowerIrql(PASSIVE_LEVEL); + KeLowerIrql(PASSIVE_LEVEL); /* Can't be a worker thread */ if (Thread->ActiveExWorker) @@ -453,9 +451,9 @@ PspExitThread(IN NTSTATUS ExitStatus) /* Bugcheck */ KEBUGCHECKEX(KERNEL_APC_PENDING_DURING_EXIT, 0, - Thread->Tcb.KernelApcDisable, - APC_LEVEL, - 0); + Thread->Tcb.CombinedApcDisable, + 0, + 1); } /* Lock the thread */ @@ -500,7 +498,44 @@ PspExitThread(IN NTSTATUS ExitStatus) CurrentProcess->ExitStatus = ExitStatus; } - /* FIXME: Wait on the other threads to finish */ + /* Loop all the current threads */ + FirstEntry = &CurrentProcess->ThreadListHead; + CurrentEntry = FirstEntry->Flink; + while (FirstEntry != CurrentEntry) + { + /* Get the thread on the list */ + OtherThread = CONTAINING_RECORD(CurrentEntry, + ETHREAD, + ThreadListEntry); + + /* Check if it's a thread that's still alive */ + if ((OtherThread != Thread) && + !(KeReadStateThread(&OtherThread->Tcb)) && + (ObReferenceObjectSafe(OtherThread))) + { + /* It's a live thread and we referenced it, unlock process */ + ExReleasePushLockExclusive(&CurrentProcess->ProcessLock); + KeLeaveCriticalRegion(); + + /* Wait on the thread */ + KeWaitForSingleObject(OtherThread, + Executive, + KernelMode, + FALSE, + NULL); + + /* Check if we had a previous thread to dereference */ + if (PreviousThread) ObDereferenceObject(PreviousThread); + + /* Remember the thread and re-lock the process */ + PreviousThread = OtherThread; + KeEnterCriticalRegion(); + ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock); + } + + /* Go to the next thread */ + CurrentEntry = CurrentEntry->Flink; + } } else if (ExitStatus != STATUS_THREAD_IS_TERMINATING) { @@ -512,6 +547,9 @@ PspExitThread(IN NTSTATUS ExitStatus) ExReleasePushLockExclusive(&CurrentProcess->ProcessLock); KeLeaveCriticalRegion(); + /* Check if we had a previous thread to dereference */ + if (PreviousThread) ObDereferenceObject(PreviousThread); + /* Check if the process has a debug port and if this is a user thread */ if ((CurrentProcess->DebugPort) && !(Thread->SystemThread)) { @@ -570,15 +608,20 @@ PspExitThread(IN NTSTATUS ExitStatus) /* Save the Create Time */ TerminationMsg.CreateTime = Thread->CreateTime; -TryAgain: - /* Send the LPC Message */ - Status = LpcRequestPort(TerminationPort->Port, &TerminationMsg.h); - if ((Status == STATUS_NO_MEMORY) || - (Status == STATUS_INSUFFICIENT_RESOURCES)) + /* Loop trying to send message */ + while (TRUE) { - /* Wait a bit and try again */ - KeDelayExecutionThread(KernelMode, FALSE, &ShortPsLockDelay); - goto TryAgain; + /* Send the LPC Message */ + Status = LpcRequestPort(TerminationPort->Port, + &TerminationMsg.h); + if ((Status == STATUS_NO_MEMORY) || + (Status == STATUS_INSUFFICIENT_RESOURCES)) + { + /* Wait a bit and try again */ + KeDelayExecutionThread(KernelMode, FALSE, &ShortTime); + continue; + } + break; } /* Dereference this LPC Port */ @@ -591,7 +634,8 @@ TryAgain: ExFreePool(TerminationPort); /* Keep looping as long as there is a port */ - } while ((TerminationPort = NextPort)); + TerminationPort = NextPort; + } while (TerminationPort); } else if (((ExitStatus == STATUS_THREAD_IS_TERMINATING) && (Thread->DeadThread)) || @@ -627,16 +671,20 @@ TryAgain: /* Save the Create Time */ TerminationMsg.CreateTime = Thread->CreateTime; -TryAgain2: - /* Send the LPC Message */ - Status = LpcRequestPort(CurrentProcess->ExceptionPort, - &TerminationMsg.h); - if ((Status == STATUS_NO_MEMORY) || - (Status == STATUS_INSUFFICIENT_RESOURCES)) + /* Loop trying to send message */ + while (TRUE) { - /* Wait a bit and try again */ - KeDelayExecutionThread(KernelMode, FALSE, &ShortPsLockDelay); - goto TryAgain2; + /* Send the LPC Message */ + Status = LpcRequestPort(CurrentProcess->ExceptionPort, + &TerminationMsg.h); + if ((Status == STATUS_NO_MEMORY) || + (Status == STATUS_INSUFFICIENT_RESOURCES)) + { + /* Wait a bit and try again */ + KeDelayExecutionThread(KernelMode, FALSE, &ShortTime); + continue; + } + break; } } } @@ -646,7 +694,6 @@ TryAgain2: PsW32ThreadCalloutExit); /* If we are the last thread and have a W32 Process */ - PSREFTRACE(Thread); if ((Last) && (CurrentProcess->Win32Process)) { /* Run it down too */ @@ -674,26 +721,30 @@ TryAgain2: /* Check if we have a TEB */ Teb = Thread->Tcb.Teb; - if(Teb) + if (Teb) { - /* Check if the thread isn't terminated and if we should free stack */ - if (!(Thread->Terminated) && (Teb->FreeStackOnTermination)) + /* Check if the thread is still alive */ + if (!Thread->DeadThread) { - /* Set the TEB's Deallocation Stack as the Base Address */ - Dummy = 0; - DeallocationStack = Teb->DeallocationStack; + /* Check if we need to free its stack */ + if (Teb->FreeStackOnTermination) + { + /* Set the TEB's Deallocation Stack as the Base Address */ + Dummy = 0; + DeallocationStack = Teb->DeallocationStack; - /* Free the Thread's Stack */ - ZwFreeVirtualMemory(NtCurrentProcess(), - &DeallocationStack, - &Dummy, - MEM_RELEASE); + /* Free the Thread's Stack */ + ZwFreeVirtualMemory(NtCurrentProcess(), + &DeallocationStack, + &Dummy, + MEM_RELEASE); + } + + /* Free the debug handle */ + if (Teb->DbgSsReserved[1]) ObCloseHandle(Teb->DbgSsReserved[1], + UserMode); } - /* Free the debug handle */ - if (Teb->DbgSsReserved[1]) ObCloseHandle(Teb->DbgSsReserved[1], - UserMode); - /* Decommit the TEB */ MmDeleteTeb(CurrentProcess, Teb); Thread->Tcb.Teb = NULL; @@ -710,8 +761,6 @@ TryAgain2: ASSERT(Thread->Tcb.CombinedApcDisable == 0); /* Check if this is the final thread or not */ - PSREFTRACE(Thread); - PSREFTRACE(CurrentProcess); if (Last) { /* Set the process exit time */ @@ -736,7 +785,6 @@ TryAgain2: /* Kill the process in the Object Manager */ ObKillProcess(CurrentProcess); - PSREFTRACE(CurrentProcess); /* Check if we have a section object */ if (CurrentProcess->SectionObject) @@ -768,6 +816,7 @@ TryAgain2: FirstEntry = KeFlushQueueApc(&Thread->Tcb, UserMode); if (FirstEntry) { + /* Start with the first entry */ CurrentEntry = FirstEntry; do { @@ -781,7 +830,7 @@ TryAgain2: if (Apc->RundownRoutine) { /* Call its own routine */ - (Apc->RundownRoutine)(Apc); + Apc->RundownRoutine(Apc); } else { @@ -800,12 +849,12 @@ TryAgain2: /* Flush the APC queue, which should be empty */ FirstEntry = KeFlushQueueApc(&Thread->Tcb, KernelMode); - if (FirstEntry) + if ((FirstEntry) || (Thread->Tcb.CombinedApcDisable != 0)) { /* Bugcheck time */ KEBUGCHECKEX(KERNEL_APC_PENDING_DURING_EXIT, (ULONG_PTR)FirstEntry, - Thread->Tcb.KernelApcDisable, + Thread->Tcb.CombinedApcDisable, KeGetCurrentIrql(), 0); } @@ -814,8 +863,6 @@ TryAgain2: if (Last) KeSetProcess(&CurrentProcess->Pcb, 0, FALSE); /* Terminate the Thread from the Scheduler */ - PSREFTRACE(Thread); - PSREFTRACE(CurrentProcess); KeTerminateThread(0); } @@ -927,10 +974,11 @@ PspTerminateThreadByPointer(IN PETHREAD Thread, Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC); /* Set the Terminated Flag */ - Flags = Thread->CrossThreadFlags | 1; + Flags = Thread->CrossThreadFlags | CT_TERMINATED_BIT; /* Set it, and check if it was already set while we were running */ - if (!(InterlockedExchange((PLONG)&Thread->CrossThreadFlags, Flags) & 1)) + if (!(InterlockedExchange((PLONG)&Thread->CrossThreadFlags, Flags) & + CT_TERMINATED_BIT)) { /* Initialize a Kernel Mode APC to Kill the Thread */ KeInitializeApc(Apc, @@ -961,7 +1009,6 @@ PspTerminateThreadByPointer(IN PETHREAD Thread, ExFreePool(Apc); /* Return Status */ - PSREFTRACE(Thread); return Status; } @@ -1006,7 +1053,6 @@ PspExitProcess(IN BOOLEAN LastThread, } /* Check if we are the last thread */ - PSREFTRACE(Process); if (LastThread) { /* Check if we have to set the Timer Resolution */ @@ -1088,7 +1134,12 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL, } /* Lock the Process */ - ExAcquireRundownProtection(&Process->RundownProtect); + if (!ExAcquireRundownProtection(&Process->RundownProtect)) + { + /* Failed to lock, fal */ + ObDereferenceObject (Process); + return STATUS_PROCESS_IS_TERMINATING; + } /* Set the delete flag */ if (!KillByHandle) InterlockedOr((PLONG)&Process->Flags, @@ -1113,7 +1164,8 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL, } /* Move to the next thread */ - } while((Thread = PsGetNextProcessThread(Process, Thread))); + Thread = PsGetNextProcessThread(Process, Thread); + } while (Thread); } /* Unlock the process */ diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index e61179d7032..c3b9061ceda 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -397,7 +397,6 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, (PVOID*)&Parent, NULL); if (!NT_SUCCESS(Status)) return Status; - PSREFTRACE(Parent); /* If this process should be in a job but the parent isn't */ if ((InJob) && (!Parent->Job)) @@ -434,7 +433,6 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, if (!NT_SUCCESS(Status)) goto Cleanup; /* Clean up the Object */ - PSREFTRACE(Process); RtlZeroMemory(Process, sizeof(EPROCESS)); /* Initialize pushlock and rundown protection */ @@ -485,14 +483,15 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, if (Parent != PsInitialSystemProcess) { /* It's not, so acquire the process rundown */ - ExAcquireRundownProtection(&Process->RundownProtect); + if (ExAcquireRundownProtection(&Process->RundownProtect)) + { + /* If the parent has a section, use it */ + SectionObject = Parent->SectionObject; + if (SectionObject) ObReferenceObject(SectionObject); - /* If the parent has a section, use it */ - SectionObject = Parent->SectionObject; - if (SectionObject) ObReferenceObject(SectionObject); - - /* Release process rundown */ - ExReleaseRundownProtection(&Process->RundownProtect); + /* Release process rundown */ + ExReleaseRundownProtection(&Process->RundownProtect); + } /* If we don't have a section object */ if (!SectionObject) @@ -647,23 +646,25 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, AccessState, DesiredAccess, 1, - (PVOID*)&Process, + NULL, &hProcess); /* Free the access state */ if (AccessState) SeDeleteAccessState(AccessState); /* Cleanup on failure */ - PSREFTRACE(Process); if (!NT_SUCCESS(Status)) goto Cleanup; /* Compute Quantum and Priority */ - Process->Pcb.BasePriority = (SCHAR)PspComputeQuantumAndPriority(Process, - 0, - &Quantum); + ASSERT(IsListEmpty(&Process->ThreadListHead) == TRUE); + Process->Pcb.BasePriority = + (SCHAR)PspComputeQuantumAndPriority(Process, + PsProcessPriorityBackground, + &Quantum); Process->Pcb.QuantumReset = Quantum; /* Check if we have a parent other then the initial system process */ + Process->GrantedAccess = PROCESS_TERMINATE; if ((Parent) && (Parent != PsInitialSystemProcess)) { /* Get the process's SD */ @@ -683,7 +684,6 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, SubjectContext.ClientToken = NULL; /* Do the access check */ - if (!SecurityDescriptor) DPRINT1("FIX PS SDs!!\n"); Result = SeAccessCheck(SecurityDescriptor, &SubjectContext, FALSE, @@ -712,7 +712,9 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, PROCESS_CREATE_THREAD | PROCESS_DUP_HANDLE | PROCESS_CREATE_PROCESS | - PROCESS_SET_INFORMATION); + PROCESS_SET_INFORMATION | + STANDARD_RIGHTS_ALL | + PROCESS_SET_QUOTA); } else { @@ -720,14 +722,10 @@ PspCreateProcess(OUT PHANDLE ProcessHandle, Process->GrantedAccess = PROCESS_ALL_ACCESS; } - /* Sanity check */ - ASSERT(IsListEmpty(&Process->ThreadListHead)); - /* Set the Creation Time */ KeQuerySystemTime(&Process->CreateTime); /* Protect against bad user-mode pointer */ - PSREFTRACE(Process); _SEH_TRY { /* Save the process handle */ @@ -753,8 +751,6 @@ Cleanup: if (Parent) ObDereferenceObject(Parent); /* Return status to caller */ - PSREFTRACE(Process); - if (Parent) PSREFTRACE(Parent); return Status; } @@ -1387,8 +1383,6 @@ NtOpenProcess(OUT PHANDLE ProcessHandle, /* Dereference the Process */ ObDereferenceObject(Process); - PSREFTRACE(Process); - if (Thread) PSREFTRACE(Thread); } else { diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index 7ed35892743..3b19a60f671 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -231,7 +231,6 @@ PsLocateSystemDll(VOID) KeBugCheckEx(PROCESS1_INITIALIZATION_FAILED, Status, 4, 0, 0); } - /* Map it */ Status = PspMapSystemDll(PsGetCurrentProcess(), &PspSystemDllBase); if (!NT_SUCCESS(Status)) @@ -290,9 +289,7 @@ PspInitPhase0(VOID) MM_SYSTEMSIZE SystemSize; UNICODE_STRING Name; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; - - /* FIXME: Initialize Lock Data do it STATIC */ - ShortPsLockDelay.QuadPart = -100LL; + ULONG i; /* Get the system size */ SystemSize = MmQuerySystemSize(); @@ -320,11 +317,23 @@ PspInitPhase0(VOID) break; } + /* Setup callbacks */ + for (i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i++) + { + ExInitializeCallBack(&PspThreadNotifyRoutine[i]); + } + for (i = 0; i < PSP_MAX_CREATE_PROCESS_NOTIFY; i++) + { + ExInitializeCallBack(&PspProcessNotifyRoutine[i]); + } + for (i = 0; i < PSP_MAX_LOAD_IMAGE_NOTIFY; i++) + { + ExInitializeCallBack(&PspLoadImageNotifyRoutine[i]); + } + /* Setup the quantum table */ PsChangeQuantumTable(FALSE, PsRawPrioritySeparation); - /* Setup callbacks when we implement Generic Callbacks */ - /* Set quota settings */ if (!PspDefaultPagedLimit) PspDefaultPagedLimit = 0; if (!PspDefaultNonPagedLimit) PspDefaultNonPagedLimit = 0; @@ -406,6 +415,7 @@ PspInitPhase0(VOID) /* Create the CID Handle table */ PspCidTable = ExCreateHandleTable(NULL); + if (!PspCidTable) return FALSE; /* FIXME: Initialize LDT/VDM support */ @@ -447,11 +457,22 @@ PspInitPhase0(VOID) strcpy(PsInitialSystemProcess->ImageFileName, "System"); /* Allocate a structure for the audit name */ - PsIdleProcess->SeAuditProcessCreationInfo.ImageFileName = - ExAllocatePoolWithTag(PagedPool, sizeof(UNICODE_STRING), TAG_SEPA); - if (!PsIdleProcess->SeAuditProcessCreationInfo.ImageFileName) KEBUGCHECK(0); + PsInitialSystemProcess->SeAuditProcessCreationInfo.ImageFileName = + ExAllocatePoolWithTag(PagedPool, + sizeof(OBJECT_NAME_INFORMATION), + TAG_SEPA); + if (!PsInitialSystemProcess->SeAuditProcessCreationInfo.ImageFileName) + { + /* Allocation failed */ + return FALSE; + } - /* Setup the system initailization thread */ + /* Zero it */ + RtlZeroMemory(PsInitialSystemProcess-> + SeAuditProcessCreationInfo.ImageFileName, + sizeof(OBJECT_NAME_INFORMATION)); + + /* Setup the system initialization thread */ Status = PsCreateSystemThread(&SysThreadHandle, THREAD_ALL_ACCESS, &ObjectAttributes, diff --git a/reactos/ntoskrnl/ps/security.c b/reactos/ntoskrnl/ps/security.c index de5363ec96e..12b4cf1482a 100644 --- a/reactos/ntoskrnl/ps/security.c +++ b/reactos/ntoskrnl/ps/security.c @@ -45,6 +45,7 @@ VOID NTAPI PspDeleteThreadSecurity(IN PETHREAD Thread) { + PPS_IMPERSONATION_INFORMATION ImpersonationInfo = Thread->ImpersonationInfo; PAGED_CODE(); PSTRACE(PS_SECURITY_DEBUG, "Thread: %p\n", Thread); @@ -52,14 +53,14 @@ PspDeleteThreadSecurity(IN PETHREAD Thread) if (Thread->ActiveImpersonationInfo) { /* Dereference its token */ - ObDereferenceObject(Thread->ImpersonationInfo->Token); + ObDereferenceObject(ImpersonationInfo->Token); } /* Check if we have impersonation info */ - if (Thread->ImpersonationInfo) + if (ImpersonationInfo) { /* Free it */ - ExFreePool(Thread->ImpersonationInfo); + ExFreePool(ImpersonationInfo); PspClearCrossThreadFlag(Thread, CT_ACTIVE_IMPERSONATION_INFO_BIT); Thread->ImpersonationInfo = NULL; } @@ -91,7 +92,11 @@ PspInitializeProcessSecurity(IN PEPROCESS Process, ObFastDereferenceObject(&Parent->Token, ParentToken); /* Set the new Token */ - ObInitializeFastReference(&Process->Token, NewToken); + if (NT_SUCCESS(Status)) + { + /* Initailize the fast reference */ + ObInitializeFastReference(&Process->Token, NewToken); + } } else { @@ -133,26 +138,24 @@ PspWriteTebImpersonationInfo(IN PETHREAD Thread, Attached = TRUE; } - /* Check if we're in a different thread */ - if (Thread != CurrentThread) + /* Check if we're in a different thread or acquire rundown */ + if ((Thread == CurrentThread) || + (ExAcquireRundownProtection(&Thread->RundownProtect))) { - /* Acquire thread rundown protection */ - ExAcquireRundownProtection(&Thread->RundownProtect); - } - - /* Check if the thread is impersonating */ - IsImpersonating = (BOOLEAN)Thread->ActiveImpersonationInfo; - if (IsImpersonating) - { - /* Set TEB data */ - Teb->ImpersonationLocale = -1; - Teb->IsImpersonating = 1; - } - else - { - /* Set TEB data */ - Teb->ImpersonationLocale = 0; - Teb->IsImpersonating = 0; + /* Check if the thread is impersonating */ + IsImpersonating = (BOOLEAN)Thread->ActiveImpersonationInfo; + if (IsImpersonating) + { + /* Set TEB data */ + Teb->ImpersonationLocale = -1; + Teb->IsImpersonating = 1; + } + else + { + /* Set TEB data */ + Teb->ImpersonationLocale = 0; + Teb->IsImpersonating = 0; + } } /* Check if we're in a different thread */ @@ -162,7 +165,7 @@ PspWriteTebImpersonationInfo(IN PETHREAD Thread, ExReleaseRundownProtection(&Thread->RundownProtect); } - /* Dettach */ + /* Detach */ if (Attached) KeUnstackDetachProcess(&ApcState); } @@ -170,29 +173,40 @@ PspWriteTebImpersonationInfo(IN PETHREAD Thread, return STATUS_SUCCESS; } - NTSTATUS NTAPI PspAssignPrimaryToken(IN PEPROCESS Process, - IN PTOKEN Token) + IN HANDLE Token, + IN PACCESS_TOKEN AccessToken OPTIONAL) { - PACCESS_TOKEN OldToken; + PACCESS_TOKEN NewToken = AccessToken, OldToken; NTSTATUS Status; PAGED_CODE(); PSTRACE(PS_SECURITY_DEBUG, "Process: %p Token: %p\n", Process, Token); - /* Lock the process */ + /* Check if we don't have a pointer */ + if (!AccessToken) + { + /* Reference it from the handle */ + Status = ObReferenceObjectByHandle(Token, + TOKEN_ASSIGN_PRIMARY, + SepTokenObjectType, + ExGetPreviousMode(), + &NewToken, + NULL); + if (!NT_SUCCESS(Status)) return Status; + } + + /* Exchange tokens */ + Status = SeExchangePrimaryToken(Process, NewToken, &OldToken); + + /* Acquire and release the lock */ PspLockProcessSecurityExclusive(Process); - - /* Exchange them */ - Status = SeExchangePrimaryToken(Process, Token, &OldToken); - - /* Release the lock */ PspUnlockProcessSecurityExclusive(Process); /* Dereference Tokens and Return */ if (NT_SUCCESS(Status)) ObDereferenceObject(OldToken); - ObDereferenceObject(Token); + if (AccessToken) ObDereferenceObject(NewToken); return Status; } @@ -200,10 +214,11 @@ NTSTATUS NTAPI PspSetPrimaryToken(IN PEPROCESS Process, IN HANDLE TokenHandle OPTIONAL, - IN PTOKEN Token OPTIONAL) + IN PACCESS_TOKEN Token OPTIONAL) { KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); BOOLEAN IsChild; + PACCESS_TOKEN NewToken = Token; NTSTATUS Status, AccessStatus; BOOLEAN Result, SdAllocated; PSECURITY_DESCRIPTOR SecurityDescriptor; @@ -218,17 +233,17 @@ PspSetPrimaryToken(IN PEPROCESS Process, TOKEN_ASSIGN_PRIMARY, SepTokenObjectType, PreviousMode, - (PVOID*)&Token, + (PVOID*)&NewToken, NULL); if (!NT_SUCCESS(Status)) return Status; } /* Check if this is a child */ - Status = SeIsTokenChild(Token, &IsChild); + Status = SeIsTokenChild(NewToken, &IsChild); if (!NT_SUCCESS(Status)) { /* Failed, dereference */ - if (TokenHandle) ObDereferenceObject(Token); + if (TokenHandle) ObDereferenceObject(NewToken); return Status; } @@ -246,7 +261,7 @@ PspSetPrimaryToken(IN PEPROCESS Process, } /* Assign the token */ - Status = PspAssignPrimaryToken(Process, Token); + Status = PspAssignPrimaryToken(Process, NULL, NewToken); if (NT_SUCCESS(Status)) { /* @@ -264,7 +279,6 @@ PspSetPrimaryToken(IN PEPROCESS Process, SubjectContext.ClientToken = NULL; /* Do the access check */ - if (!SecurityDescriptor) DPRINT1("FIX PS SDs!!\n"); Result = SeAccessCheck(SecurityDescriptor, &SubjectContext, FALSE, @@ -283,6 +297,19 @@ PspSetPrimaryToken(IN PEPROCESS Process, /* Remove access if it failed */ if (!Result) Process->GrantedAccess = 0; + + /* Setup granted access */ + Process->GrantedAccess |= (PROCESS_VM_OPERATION | + PROCESS_VM_READ | + PROCESS_VM_WRITE | + PROCESS_QUERY_INFORMATION | + PROCESS_TERMINATE | + PROCESS_CREATE_THREAD | + PROCESS_DUP_HANDLE | + PROCESS_CREATE_PROCESS | + PROCESS_SET_INFORMATION | + STANDARD_RIGHTS_ALL | + PROCESS_SET_QUOTA); } /* Dereference the process */ @@ -290,7 +317,7 @@ PspSetPrimaryToken(IN PEPROCESS Process, } /* Dereference the token */ - if (TokenHandle) ObDereferenceObject(Token); + if (Token) ObDereferenceObject(NewToken); return Status; } @@ -352,7 +379,7 @@ NtOpenProcessTokenEx(IN HANDLE ProcessHandle, /* Open the process token */ Status = PsOpenTokenOfProcess(ProcessHandle, &Token); - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Reference it by handle and dereference the pointer */ Status = ObOpenObjectByPointer(Token, @@ -365,7 +392,7 @@ NtOpenProcessTokenEx(IN HANDLE ProcessHandle, ObDereferenceObject(Token); /* Make sure we got a handle */ - if(NT_SUCCESS(Status)) + if (NT_SUCCESS(Status)) { /* Enter SEH for write */ _SEH_TRY @@ -487,10 +514,7 @@ PsAssignImpersonationToken(IN PETHREAD Thread, return STATUS_BAD_TOKEN_TYPE; } - /* Check if this is a job, which we don't support yet */ - if (Thread->ThreadsProcess->Job) KEBUGCHECK(0); - - /* Get the impersionation level */ + /* Get the impersonation level */ ImpersonationLevel = SeTokenImpersonationLevel(Token); /* Call the impersonation API */ @@ -501,7 +525,7 @@ PsAssignImpersonationToken(IN PETHREAD Thread, ImpersonationLevel); /* Dereference the token and return status */ - if (Token) ObDereferenceObject(Token); + ObDereferenceObject(Token); return Status; } @@ -546,13 +570,17 @@ PsRevertThreadToSelf(IN PETHREAD Thread) /* Release thread security */ PspUnlockThreadSecurityExclusive(Thread); + + /* Check if we had a token */ + if (Token) + { + /* Dereference the impersonation token */ + ObDereferenceObject(Token); + + /* Write impersonation info to the TEB */ + PspWriteTebImpersonationInfo(Thread, PsGetCurrentThread()); + } } - - /* Dereference the impersonation token */ - if (Token) ObDereferenceObject(Token); - - /* Write impersonation info to the TEB */ - PspWriteTebImpersonationInfo(Thread, PsGetCurrentThread()); } /* @@ -566,7 +594,7 @@ PsImpersonateClient(IN PETHREAD Thread, IN BOOLEAN EffectiveOnly, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel) { - PPS_IMPERSONATION_INFORMATION Impersonation; + PPS_IMPERSONATION_INFORMATION Impersonation, OldData; PTOKEN OldToken = NULL; PAGED_CODE(); PSTRACE(PS_SECURITY_DEBUG, "Thread: %p, Token: %p\n", Thread, Token); @@ -591,8 +619,9 @@ PsImpersonateClient(IN PETHREAD Thread, OldToken = Thread->ImpersonationInfo->Token; } - /* Unlock the process */ + /* Unlock the process and write TEB information */ PspUnlockThreadSecurityExclusive(Thread); + PspWriteTebImpersonationInfo(Thread, PsGetCurrentThread()); } } else @@ -608,12 +637,15 @@ PsImpersonateClient(IN PETHREAD Thread, if (!Impersonation) return STATUS_INSUFFICIENT_RESOURCES; /* Update the pointer */ - if (InterlockedCompareExchangePointer(&Thread->ImpersonationInfo, - Impersonation, - NULL)) + OldData = InterlockedCompareExchangePointer(&Thread-> + ImpersonationInfo, + Impersonation, + NULL); + if (OldData) { /* Someone beat us to it, free our copy */ ExFreePool(Impersonation); + Impersonation = OldData; } } @@ -644,13 +676,13 @@ PsImpersonateClient(IN PETHREAD Thread, /* Unlock the thread */ PspUnlockThreadSecurityExclusive(Thread); + + /* Write impersonation info to the TEB */ + PspWriteTebImpersonationInfo(Thread, PsGetCurrentThread()); } - /* Write impersonation info to the TEB */ - PspWriteTebImpersonationInfo(Thread, PsGetCurrentThread()); - /* Dereference the token and return success */ - if (OldToken) ObDereferenceObject(OldToken); + if (OldToken) PsDereferenceImpersonationToken(OldToken); return STATUS_SUCCESS; } @@ -674,9 +706,6 @@ PsReferenceEffectiveToken(IN PETHREAD Thread, Process = Thread->ThreadsProcess; if (!Thread->ActiveImpersonationInfo) { - *TokenType = TokenPrimary; - *EffectiveOnly = FALSE; - /* Fast Reference the Token */ Token = ObFastReferenceObject(&Process->Token); @@ -709,6 +738,10 @@ PsReferenceEffectiveToken(IN PETHREAD Thread, *TokenType = TokenImpersonation; *EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly; *Level = Thread->ImpersonationInfo->ImpersonationLevel; + + /* Unlock the Process */ + PspUnlockProcessSecurityShared(Process); + return Token; } /* Unlock the Process */ @@ -716,6 +749,8 @@ PsReferenceEffectiveToken(IN PETHREAD Thread, } /* Return the token */ + *TokenType = TokenPrimary; + *EffectiveOnly = FALSE; return Token; } diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index c8ac1fc0655..4814b52bd36 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -51,9 +51,8 @@ PspUserThreadStartup(IN PKSTART_ROUTINE StartRoutine, Teb->IdealProcessor = Thread->Tcb.IdealProcessor; } - /* Check if this is a system thread, or if we're hiding */ - PSREFTRACE(Thread); - if (!(Thread->SystemThread) && !(Thread->HideFromDebugger)) + /* Check if this is a dead thread, or if we're hiding */ + if (!(Thread->DeadThread) && !(Thread->HideFromDebugger)) { /* We're not, so notify the debugger */ DbgkCreateThread(StartContext); @@ -113,6 +112,30 @@ PspUserThreadStartup(IN PKSTART_ROUTINE StartRoutine, } } +_SEH_FILTER(PspUnhandledExceptionInSystemThread) +{ + PEXCEPTION_POINTERS ExceptionPointers= _SEH_GetExceptionPointers(); + + /* Print debugging information */ + DPRINT1("PS: Unhandled Kernel Mode Exception Pointers = 0x%p\n", + ExceptionPointers); + DPRINT1("Code %x Addr %p Info0 %p Info1 %p Info2 %p Info3 %p\n", + ExceptionPointers->ExceptionRecord->ExceptionCode, + ExceptionPointers->ExceptionRecord->ExceptionAddress, + ExceptionPointers->ExceptionRecord->ExceptionInformation[0], + ExceptionPointers->ExceptionRecord->ExceptionInformation[1], + ExceptionPointers->ExceptionRecord->ExceptionInformation[2], + ExceptionPointers->ExceptionRecord->ExceptionInformation[3]); + + /* Bugcheck the system */ + KeBugCheckEx(0x7E, + ExceptionPointers->ExceptionRecord->ExceptionCode, + (ULONG_PTR)ExceptionPointers->ExceptionRecord->ExceptionAddress, + (ULONG_PTR)ExceptionPointers->ExceptionRecord, + (ULONG_PTR)ExceptionPointers->ContextRecord); + return 0; +} + VOID NTAPI PspSystemThreadStartup(IN PKSTART_ROUTINE StartRoutine, @@ -127,12 +150,20 @@ PspSystemThreadStartup(IN PKSTART_ROUTINE StartRoutine, Thread = PsGetCurrentThread(); /* Make sure the thread isn't gone */ - PSREFTRACE(Thread); - if (!(Thread->Terminated) && !(Thread->DeadThread)) + _SEH_TRY { - /* Call it the Start Routine */ - StartRoutine(StartContext); + if (!(Thread->Terminated) && !(Thread->DeadThread)) + { + /* Call it the Start Routine */ + StartRoutine(StartContext); + } } + _SEH_EXCEPT(PspUnhandledExceptionInSystemThread) + { + /* Bugcheck if we got here */ + KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED); + } + _SEH_END; /* Exit the thread */ PspTerminateThreadByPointer(Thread, STATUS_SUCCESS, TRUE); @@ -192,7 +223,6 @@ PspCreateThread(OUT PHANDLE ThreadHandle, { /* Reference the Process by Pointer */ ObReferenceObject(TargetProcess); - PSREFTRACE(TargetProcess); Process = TargetProcess; Status = STATUS_SUCCESS; } @@ -232,7 +262,6 @@ PspCreateThread(OUT PHANDLE ThreadHandle, } /* Zero the Object entirely */ - PSREFTRACE(Thread); RtlZeroMemory(Thread, sizeof(ETHREAD)); /* Initialize rundown protection */ @@ -270,7 +299,12 @@ PspCreateThread(OUT PHANDLE ThreadHandle, KeInitializeSpinLock(&Thread->ActiveTimerListLock); /* Acquire rundown protection */ - ExAcquireRundownProtection(&Process->RundownProtect); + if (!ExAcquireRundownProtection (&Process->RundownProtect)) + { + /* Fail */ + ObDereferenceObject(Thread); + return STATUS_PROCESS_IS_TERMINATING; + } /* Now let the kernel initialize the context */ if (ThreadContext) @@ -317,7 +351,6 @@ PspCreateThread(OUT PHANDLE ThreadHandle, } /* Check if we failed */ - PSREFTRACE(Thread); if (!NT_SUCCESS(Status)) { /* Delete the TEB if we had done */ @@ -400,6 +433,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle, /* Dereference completely to kill it */ ObDereferenceObjectEx(Thread, 2); + return Status; } /* Insert the Thread into the Object Manager */ @@ -411,7 +445,6 @@ PspCreateThread(OUT PHANDLE ThreadHandle, &hThread); /* Delete the access state if we had one */ - PSREFTRACE(Thread); if (AccessState) SeDeleteAccessState(AccessState); /* Check for success */ @@ -461,7 +494,6 @@ PspCreateThread(OUT PHANDLE ThreadHandle, ASSERT(!(Thread->CreateTime.HighPart & 0xF0000000)); /* Make sure the thread isn't dead */ - PSREFTRACE(Thread); if (!Thread->DeadThread) { /* Get the thread's SD */ @@ -493,7 +525,6 @@ PspCreateThread(OUT PHANDLE ThreadHandle, SubjectContext.ClientToken = NULL; /* Do the access check */ - if (!SecurityDescriptor) DPRINT1("FIX PS SDs!!\n"); Result = SeAccessCheck(SecurityDescriptor, &SubjectContext, FALSE, @@ -525,14 +556,12 @@ PspCreateThread(OUT PHANDLE ThreadHandle, } /* Dispatch thread */ - PSREFTRACE(Thread); KeReadyThread(&Thread->Tcb); /* Dereference it, leaving only the keep-alive */ ObDereferenceObject(Thread); /* Return */ - PSREFTRACE(Thread); return Status; /* Most annoying failure case ever, where we undo almost all manually */ @@ -541,7 +570,6 @@ Quickie: ExReleasePushLockExclusive(&Process->ProcessLock); /* Uninitailize it */ - PSREFTRACE(Thread); KeUninitThread(&Thread->Tcb); /* If we had a TEB, delete it */ @@ -552,7 +580,6 @@ Quickie: /* Dereference the thread and return failure */ ObDereferenceObject(Thread); - PSREFTRACE(Thread); return STATUS_PROCESS_IS_TERMINATING; } @@ -841,7 +868,7 @@ NtCreateThread(OUT PHANDLE ThreadHandle, "ProcessHandle: %p Context: %p\n", ProcessHandle, ThreadContext); /* Check if this was from user-mode */ - if(KeGetPreviousMode() != KernelMode) + if (KeGetPreviousMode() != KernelMode) { /* Make sure that we got a context */ if (!ThreadContext) return STATUS_INVALID_PARAMETER; @@ -865,14 +892,12 @@ NtCreateThread(OUT PHANDLE ThreadHandle, /* Check the Initial TEB */ ProbeForRead(InitialTeb, sizeof(INITIAL_TEB), sizeof(ULONG)); SafeInitialTeb = *InitialTeb; - } + } _SEH_HANDLE { Status = _SEH_GetExceptionCode(); } _SEH_END; - - /* Handle any failures in our SEH checks */ if (!NT_SUCCESS(Status)) return Status; } else