mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
Bug found by arty, thanks to alex for helping fix it:
Process termination fixes part 1: don't suicide our process when we're killing a sibling. - Clarify the use of KillByHandle. It does *not* mean "suicide". - In fact, we had considered the use of KillByHandle backward, that is, our process would commit suicide if it was killing a sibling process. - Make suicide contingent on killing the same process. - Properly handle DBG_TERMINATE_PROCESS semidocumented debugger hack. svn path=/trunk/; revision=28451
This commit is contained in:
parent
2858198372
commit
01d8c61545
2 changed files with 30 additions and 19 deletions
|
@ -58,6 +58,10 @@
|
|||
#define PSREFTRACE(x)
|
||||
#endif
|
||||
|
||||
#define PspSetProcessFlag(Process, Flag) \
|
||||
InterlockedOr((PLONG)&Process->Flags, Flag)
|
||||
|
||||
|
||||
//
|
||||
// Maximum Count of Notification Routines
|
||||
//
|
||||
|
|
|
@ -1108,12 +1108,21 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
|
|||
PSTRACE(PS_KILL_DEBUG,
|
||||
"ProcessHandle: %p ExitStatus: %p\n", ProcessHandle, ExitStatus);
|
||||
|
||||
/* Remember how we will kill it */
|
||||
KillByHandle = (ProcessHandle != NULL);
|
||||
/* Were we passed a process handle? */
|
||||
if (ProcessHandle)
|
||||
{
|
||||
/* Yes we were, use it */
|
||||
KillByHandle = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We weren't... we assume this is suicide */
|
||||
KillByHandle = FALSE;
|
||||
ProcessHandle = NtCurrentProcess();
|
||||
}
|
||||
|
||||
/* Get the Process Object */
|
||||
Status = ObReferenceObjectByHandle((KillByHandle) ?
|
||||
ProcessHandle : NtCurrentProcess(),
|
||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||
PROCESS_TERMINATE,
|
||||
PsProcessType,
|
||||
KeGetPreviousMode(),
|
||||
|
@ -1138,9 +1147,8 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
|
|||
return STATUS_PROCESS_IS_TERMINATING;
|
||||
}
|
||||
|
||||
/* Set the delete flag */
|
||||
if (!KillByHandle) InterlockedOr((PLONG)&Process->Flags,
|
||||
PSF_PROCESS_DELETE_BIT);
|
||||
/* Set the delete flag, unless the process is comitting suicide */
|
||||
if (KillByHandle) PspSetProcessFlag(Process, PSF_PROCESS_DELETE_BIT);
|
||||
|
||||
/* Get the first thread */
|
||||
Status = STATUS_NOTHING_TO_TERMINATE;
|
||||
|
@ -1169,23 +1177,22 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
|
|||
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||
|
||||
/* Check if we are killing ourselves */
|
||||
if (Process != CurrentProcess)
|
||||
if (Process == CurrentProcess)
|
||||
{
|
||||
/* Check for the DBG_TERMINATE_PROCESS exit code */
|
||||
if (ExitStatus == DBG_TERMINATE_PROCESS)
|
||||
/* Also make sure the caller gave us our handle */
|
||||
if (KillByHandle)
|
||||
{
|
||||
/* Disable debugging on this process */
|
||||
DbgkClearProcessDebugObject(Process, NULL);
|
||||
/* Dereference the project */
|
||||
ObDereferenceObject(Process);
|
||||
|
||||
/* Terminate ourselves */
|
||||
PspTerminateThreadByPointer(CurrentThread, ExitStatus, TRUE);
|
||||
}
|
||||
}
|
||||
/* Make sure that we got a handle */
|
||||
else if (KillByHandle)
|
||||
else if (ExitStatus == DBG_TERMINATE_PROCESS)
|
||||
{
|
||||
/* Dereference the project */
|
||||
ObDereferenceObject(Process);
|
||||
|
||||
/* Terminate ourselves */
|
||||
PspTerminateThreadByPointer(CurrentThread, ExitStatus, TRUE);
|
||||
/* Disable debugging on this process */
|
||||
DbgkClearProcessDebugObject(Process, NULL);
|
||||
}
|
||||
|
||||
/* Check if there was nothing to terminate, or if we have a Debug Port */
|
||||
|
|
Loading…
Reference in a new issue