mirror of
https://github.com/reactos/reactos.git
synced 2025-05-20 09:36:16 +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)
|
#define PSREFTRACE(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define PspSetProcessFlag(Process, Flag) \
|
||||||
|
InterlockedOr((PLONG)&Process->Flags, Flag)
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Maximum Count of Notification Routines
|
// Maximum Count of Notification Routines
|
||||||
//
|
//
|
||||||
|
|
|
@ -1108,12 +1108,21 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
|
||||||
PSTRACE(PS_KILL_DEBUG,
|
PSTRACE(PS_KILL_DEBUG,
|
||||||
"ProcessHandle: %p ExitStatus: %p\n", ProcessHandle, ExitStatus);
|
"ProcessHandle: %p ExitStatus: %p\n", ProcessHandle, ExitStatus);
|
||||||
|
|
||||||
/* Remember how we will kill it */
|
/* Were we passed a process handle? */
|
||||||
KillByHandle = (ProcessHandle != NULL);
|
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 */
|
/* Get the Process Object */
|
||||||
Status = ObReferenceObjectByHandle((KillByHandle) ?
|
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||||
ProcessHandle : NtCurrentProcess(),
|
|
||||||
PROCESS_TERMINATE,
|
PROCESS_TERMINATE,
|
||||||
PsProcessType,
|
PsProcessType,
|
||||||
KeGetPreviousMode(),
|
KeGetPreviousMode(),
|
||||||
|
@ -1138,9 +1147,8 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
|
||||||
return STATUS_PROCESS_IS_TERMINATING;
|
return STATUS_PROCESS_IS_TERMINATING;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the delete flag */
|
/* Set the delete flag, unless the process is comitting suicide */
|
||||||
if (!KillByHandle) InterlockedOr((PLONG)&Process->Flags,
|
if (KillByHandle) PspSetProcessFlag(Process, PSF_PROCESS_DELETE_BIT);
|
||||||
PSF_PROCESS_DELETE_BIT);
|
|
||||||
|
|
||||||
/* Get the first thread */
|
/* Get the first thread */
|
||||||
Status = STATUS_NOTHING_TO_TERMINATE;
|
Status = STATUS_NOTHING_TO_TERMINATE;
|
||||||
|
@ -1169,17 +1177,10 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
|
||||||
ExReleaseRundownProtection(&Process->RundownProtect);
|
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||||
|
|
||||||
/* Check if we are killing ourselves */
|
/* Check if we are killing ourselves */
|
||||||
if (Process != CurrentProcess)
|
if (Process == CurrentProcess)
|
||||||
{
|
{
|
||||||
/* Check for the DBG_TERMINATE_PROCESS exit code */
|
/* Also make sure the caller gave us our handle */
|
||||||
if (ExitStatus == DBG_TERMINATE_PROCESS)
|
if (KillByHandle)
|
||||||
{
|
|
||||||
/* Disable debugging on this process */
|
|
||||||
DbgkClearProcessDebugObject(Process, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Make sure that we got a handle */
|
|
||||||
else if (KillByHandle)
|
|
||||||
{
|
{
|
||||||
/* Dereference the project */
|
/* Dereference the project */
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
|
@ -1187,6 +1188,12 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
|
||||||
/* Terminate ourselves */
|
/* Terminate ourselves */
|
||||||
PspTerminateThreadByPointer(CurrentThread, ExitStatus, TRUE);
|
PspTerminateThreadByPointer(CurrentThread, ExitStatus, TRUE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (ExitStatus == DBG_TERMINATE_PROCESS)
|
||||||
|
{
|
||||||
|
/* Disable debugging on this process */
|
||||||
|
DbgkClearProcessDebugObject(Process, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if there was nothing to terminate, or if we have a Debug Port */
|
/* Check if there was nothing to terminate, or if we have a Debug Port */
|
||||||
if ((Status == STATUS_NOTHING_TO_TERMINATE) ||
|
if ((Status == STATUS_NOTHING_TO_TERMINATE) ||
|
||||||
|
|
Loading…
Reference in a new issue