xref: /aosp_15_r20/external/cronet/base/process/kill_win.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/process/kill.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <windows.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <io.h>
10*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include <algorithm>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/process/memory.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/process/process_iterator.h"
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker namespace base {
20*6777b538SAndroid Build Coastguard Worker 
GetTerminationStatus(ProcessHandle handle,int * exit_code)21*6777b538SAndroid Build Coastguard Worker TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) {
22*6777b538SAndroid Build Coastguard Worker   DCHECK(exit_code);
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker   DWORD tmp_exit_code = 0;
25*6777b538SAndroid Build Coastguard Worker 
26*6777b538SAndroid Build Coastguard Worker   if (!::GetExitCodeProcess(handle, &tmp_exit_code)) {
27*6777b538SAndroid Build Coastguard Worker     DPLOG(FATAL) << "GetExitCodeProcess() failed";
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker     // This really is a random number.  We haven't received any
30*6777b538SAndroid Build Coastguard Worker     // information about the exit code, presumably because this
31*6777b538SAndroid Build Coastguard Worker     // process doesn't have permission to get the exit code, or
32*6777b538SAndroid Build Coastguard Worker     // because of some other cause for GetExitCodeProcess to fail
33*6777b538SAndroid Build Coastguard Worker     // (MSDN docs don't give the possible failure error codes for
34*6777b538SAndroid Build Coastguard Worker     // this function, so it could be anything).  But we don't want
35*6777b538SAndroid Build Coastguard Worker     // to leave exit_code uninitialized, since that could cause
36*6777b538SAndroid Build Coastguard Worker     // random interpretations of the exit code.  So we assume it
37*6777b538SAndroid Build Coastguard Worker     // terminated "normally" in this case.
38*6777b538SAndroid Build Coastguard Worker     *exit_code = win::kNormalTerminationExitCode;
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker     // Assume the child has exited normally if we can't get the exit
41*6777b538SAndroid Build Coastguard Worker     // code.
42*6777b538SAndroid Build Coastguard Worker     return TERMINATION_STATUS_NORMAL_TERMINATION;
43*6777b538SAndroid Build Coastguard Worker   }
44*6777b538SAndroid Build Coastguard Worker   if (tmp_exit_code == STILL_ACTIVE) {
45*6777b538SAndroid Build Coastguard Worker     DWORD wait_result = WaitForSingleObject(handle, 0);
46*6777b538SAndroid Build Coastguard Worker     if (wait_result == WAIT_TIMEOUT) {
47*6777b538SAndroid Build Coastguard Worker       *exit_code = static_cast<int>(wait_result);
48*6777b538SAndroid Build Coastguard Worker       return TERMINATION_STATUS_STILL_RUNNING;
49*6777b538SAndroid Build Coastguard Worker     }
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker     if (wait_result == WAIT_FAILED) {
52*6777b538SAndroid Build Coastguard Worker       DPLOG(ERROR) << "WaitForSingleObject() failed";
53*6777b538SAndroid Build Coastguard Worker       *exit_code = static_cast<int>(wait_result);
54*6777b538SAndroid Build Coastguard Worker     } else {
55*6777b538SAndroid Build Coastguard Worker       DCHECK_EQ(WAIT_OBJECT_0, wait_result);
56*6777b538SAndroid Build Coastguard Worker       DLOG(ERROR) << "The process used 0x103 (STILL_ACTIVE) as exit code.";
57*6777b538SAndroid Build Coastguard Worker       *exit_code = static_cast<int>(tmp_exit_code);
58*6777b538SAndroid Build Coastguard Worker     }
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker     return TERMINATION_STATUS_ABNORMAL_TERMINATION;
61*6777b538SAndroid Build Coastguard Worker   }
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker   *exit_code = static_cast<int>(tmp_exit_code);
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker   // clang-format off
66*6777b538SAndroid Build Coastguard Worker   switch (tmp_exit_code) {
67*6777b538SAndroid Build Coastguard Worker     case win::kNormalTerminationExitCode:
68*6777b538SAndroid Build Coastguard Worker       return TERMINATION_STATUS_NORMAL_TERMINATION;
69*6777b538SAndroid Build Coastguard Worker     case win::kDebuggerInactiveExitCode:    // STATUS_DEBUGGER_INACTIVE.
70*6777b538SAndroid Build Coastguard Worker     case win::kKeyboardInterruptExitCode:   // Control-C/end session.
71*6777b538SAndroid Build Coastguard Worker     case win::kDebuggerTerminatedExitCode:  // Debugger terminated process.
72*6777b538SAndroid Build Coastguard Worker     case win::kProcessKilledExitCode:       // Task manager kill.
73*6777b538SAndroid Build Coastguard Worker       return TERMINATION_STATUS_PROCESS_WAS_KILLED;
74*6777b538SAndroid Build Coastguard Worker     case win::kSandboxFatalMemoryExceeded:  // Terminated process due to
75*6777b538SAndroid Build Coastguard Worker                                             // exceeding the sandbox job
76*6777b538SAndroid Build Coastguard Worker                                             // object memory limits.
77*6777b538SAndroid Build Coastguard Worker     case win::kOomExceptionCode:            // Ran out of memory.
78*6777b538SAndroid Build Coastguard Worker       return TERMINATION_STATUS_OOM;
79*6777b538SAndroid Build Coastguard Worker     // This exit code means the process failed an OS integrity check.
80*6777b538SAndroid Build Coastguard Worker     // This is tested in ProcessMitigationsTest.* in sandbox.
81*6777b538SAndroid Build Coastguard Worker     case win::kStatusInvalidImageHashExitCode:
82*6777b538SAndroid Build Coastguard Worker       return TERMINATION_STATUS_INTEGRITY_FAILURE;
83*6777b538SAndroid Build Coastguard Worker     default:
84*6777b538SAndroid Build Coastguard Worker       // All other exit codes indicate crashes.
85*6777b538SAndroid Build Coastguard Worker       return TERMINATION_STATUS_PROCESS_CRASHED;
86*6777b538SAndroid Build Coastguard Worker   }
87*6777b538SAndroid Build Coastguard Worker   // clang-format on
88*6777b538SAndroid Build Coastguard Worker }
89*6777b538SAndroid Build Coastguard Worker 
WaitForProcessesToExit(const FilePath::StringType & executable_name,TimeDelta wait,const ProcessFilter * filter)90*6777b538SAndroid Build Coastguard Worker bool WaitForProcessesToExit(const FilePath::StringType& executable_name,
91*6777b538SAndroid Build Coastguard Worker                             TimeDelta wait,
92*6777b538SAndroid Build Coastguard Worker                             const ProcessFilter* filter) {
93*6777b538SAndroid Build Coastguard Worker   bool result = true;
94*6777b538SAndroid Build Coastguard Worker   DWORD start_time = GetTickCount();
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker   NamedProcessIterator iter(executable_name, filter);
97*6777b538SAndroid Build Coastguard Worker   for (const ProcessEntry* entry = iter.NextProcessEntry(); entry;
98*6777b538SAndroid Build Coastguard Worker        entry = iter.NextProcessEntry()) {
99*6777b538SAndroid Build Coastguard Worker     DWORD remaining_wait = static_cast<DWORD>(
100*6777b538SAndroid Build Coastguard Worker         std::max(static_cast<int64_t>(0),
101*6777b538SAndroid Build Coastguard Worker                  wait.InMilliseconds() - (GetTickCount() - start_time)));
102*6777b538SAndroid Build Coastguard Worker     HANDLE process = OpenProcess(SYNCHRONIZE,
103*6777b538SAndroid Build Coastguard Worker                                  FALSE,
104*6777b538SAndroid Build Coastguard Worker                                  entry->th32ProcessID);
105*6777b538SAndroid Build Coastguard Worker     DWORD wait_result = WaitForSingleObject(process, remaining_wait);
106*6777b538SAndroid Build Coastguard Worker     CloseHandle(process);
107*6777b538SAndroid Build Coastguard Worker     result &= (wait_result == WAIT_OBJECT_0);
108*6777b538SAndroid Build Coastguard Worker   }
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker   return result;
111*6777b538SAndroid Build Coastguard Worker }
112*6777b538SAndroid Build Coastguard Worker 
CleanupProcesses(const FilePath::StringType & executable_name,TimeDelta wait,int exit_code,const ProcessFilter * filter)113*6777b538SAndroid Build Coastguard Worker bool CleanupProcesses(const FilePath::StringType& executable_name,
114*6777b538SAndroid Build Coastguard Worker                       TimeDelta wait,
115*6777b538SAndroid Build Coastguard Worker                       int exit_code,
116*6777b538SAndroid Build Coastguard Worker                       const ProcessFilter* filter) {
117*6777b538SAndroid Build Coastguard Worker   if (WaitForProcessesToExit(executable_name, wait, filter))
118*6777b538SAndroid Build Coastguard Worker     return true;
119*6777b538SAndroid Build Coastguard Worker   KillProcesses(executable_name, exit_code, filter);
120*6777b538SAndroid Build Coastguard Worker   return false;
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker }  // namespace base
124