1 // 2 // Copyright (C) 2015 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include "shill/process_manager.h" 18 19 #include <signal.h> 20 #include <stdlib.h> 21 #include <sys/prctl.h> 22 23 #include "shill/event_dispatcher.h" 24 #include "shill/logging.h" 25 26 using base::Closure; 27 using std::map; 28 using std::string; 29 using std::vector; 30 31 namespace shill { 32 33 namespace Logging { 34 static auto kModuleLogScope = ScopeLogger::kManager; 35 static string ObjectID(const ProcessManager* pm) { return "process_manager"; } 36 } 37 38 namespace { 39 40 base::LazyInstance<ProcessManager> g_process_manager = 41 LAZY_INSTANCE_INITIALIZER; 42 43 static const int kTerminationTimeoutSeconds = 2; 44 static const int kWaitpidPollTimesForSIGTERM = 10; 45 static const int kWaitpidPollTimesForSIGKILL = 8; 46 static const unsigned int kWaitpidPollIntervalUpperBoundMilliseconds = 2000; 47 static const unsigned int kWaitpidPollInitialIntervalMilliseconds = 4; 48 49 bool SetupChild(const map<string, string>& env, bool terminate_with_parent) { 50 // Setup environment variables. 51 clearenv(); 52 for (const auto& key_value : env) { 53 setenv(key_value.first.c_str(), key_value.second.c_str(), 0); 54 } 55 if (terminate_with_parent) { 56 prctl(PR_SET_PDEATHSIG, SIGTERM); 57 } 58 return true; 59 } 60 61 } // namespace 62 63 ProcessManager::ProcessManager() {} 64 65 ProcessManager::~ProcessManager() {} 66 67 // static 68 ProcessManager* ProcessManager::GetInstance() { 69 return g_process_manager.Pointer(); 70 } 71 72 void ProcessManager::Init(EventDispatcher* dispatcher) { 73 SLOG(this, 2) << __func__; 74 CHECK(!async_signal_handler_); 75 async_signal_handler_.reset(new brillo::AsynchronousSignalHandler()); 76 async_signal_handler_->Init(); 77 process_reaper_.Register(async_signal_handler_.get()); 78 dispatcher_ = dispatcher; 79 minijail_ = brillo::Minijail::GetInstance(); 80 } 81 82 void ProcessManager::Stop() { 83 SLOG(this, 2) << __func__; 84 CHECK(async_signal_handler_); 85 process_reaper_.Unregister(); 86 async_signal_handler_.reset(); 87 } 88 89 pid_t ProcessManager::StartProcess( 90 const tracked_objects::Location& spawn_source, 91 const base::FilePath& program, 92 const vector<string>& arguments, 93 const map<string, string>& environment, 94 bool terminate_with_parent, 95 const base::Callback<void(int)>& exit_callback) { 96 SLOG(this, 2) << __func__ << "(" << program.value() << ")"; 97 98 // Setup/create child process. 99 std::unique_ptr<brillo::Process> process(new brillo::ProcessImpl()); 100 process->AddArg(program.value()); 101 for (const auto& option : arguments) { 102 process->AddArg(option); 103 } 104 process->SetCloseUnusedFileDescriptors(true); 105 process->SetPreExecCallback( 106 base::Bind(&SetupChild, environment, terminate_with_parent)); 107 if (!process->Start()) { 108 LOG(ERROR) << "Failed to start child process for " << program.value(); 109 return -1; 110 } 111 112 // Setup watcher for the child process. 113 pid_t pid = process->pid(); 114 CHECK(process_reaper_.WatchForChild( 115 spawn_source, 116 pid, 117 base::Bind(&ProcessManager::OnProcessExited, 118 weak_factory_.GetWeakPtr(), 119 pid))); 120 121 // Release ownership of the child process from the |process| object, so that 122 // child process will not get killed on destruction of |process| object. 123 process->Release(); 124 125 watched_processes_.emplace(pid, exit_callback); 126 return pid; 127 } 128 129 pid_t ProcessManager::StartProcessInMinijailWithPipes( 130 const tracked_objects::Location& spawn_source, 131 const base::FilePath& program, 132 const std::vector<std::string>& arguments, 133 const std::string& user, 134 const std::string& group, 135 uint64_t capmask, 136 const base::Callback<void(int)>& exit_callback, 137 int* stdin_fd, 138 int* stdout_fd, 139 int* stderr_fd) { 140 SLOG(this, 2) << __func__ << "(" << program.value() << ")"; 141 142 vector<char*> args; 143 args.push_back(const_cast<char*>(program.value().c_str())); 144 for (const auto& arg : arguments) { 145 args.push_back(const_cast<char*>(arg.c_str())); 146 } 147 args.push_back(nullptr); 148 149 struct minijail* jail = minijail_->New(); 150 151 if (!minijail_->DropRoot(jail, user.c_str(), group.c_str())) { 152 LOG(ERROR) << "Minijail failed to drop root privileges?"; 153 return -1; 154 } 155 #if !defined(__ANDROID__) 156 // Don't call UseCapabilities on Android since capabilities are not supported 157 // without LD_PRELOAD, which is not used on Android. 158 minijail_->UseCapabilities(jail, capmask); 159 #endif // __ANDROID__ 160 minijail_->ResetSignalMask(jail); 161 162 pid_t pid; 163 if (!minijail_->RunPipesAndDestroy( 164 jail, args, &pid, stdin_fd, stdout_fd, stderr_fd)) { 165 LOG(ERROR) << "Unable to spawn " << program.value() << " in a jail."; 166 return -1; 167 } 168 169 CHECK(process_reaper_.WatchForChild( 170 spawn_source, 171 pid, 172 base::Bind(&ProcessManager::OnProcessExited, 173 weak_factory_.GetWeakPtr(), 174 pid))); 175 176 watched_processes_.emplace(pid, exit_callback); 177 return pid; 178 } 179 180 bool ProcessManager::StopProcess(pid_t pid) { 181 SLOG(this, 2) << __func__ << "(" << pid << ")"; 182 183 if (pending_termination_processes_.find(pid) != 184 pending_termination_processes_.end()) { 185 LOG(ERROR) << "Process " << pid << " already being stopped."; 186 return false; 187 } 188 189 if (watched_processes_.find(pid) == watched_processes_.end()) { 190 LOG(ERROR) << "Process " << pid << " not being watched"; 191 return false; 192 } 193 // Caller not interested in watching this process anymore, since the 194 // process termination is initiated by the caller. 195 watched_processes_.erase(pid); 196 197 // Attempt to send SIGTERM signal first. 198 return TerminateProcess(pid, false); 199 } 200 201 bool ProcessManager::StopProcessAndBlock(pid_t pid) { 202 SLOG(this, 2) << __func__ << "(" << pid << ")"; 203 204 auto terminated_process = pending_termination_processes_.find(pid); 205 206 if (terminated_process != pending_termination_processes_.end()) { 207 LOG(INFO) << "Process " << pid << " already being stopped."; 208 terminated_process->second->Cancel(); 209 pending_termination_processes_.erase(terminated_process); 210 } else { 211 if (watched_processes_.find(pid) == watched_processes_.end()) { 212 LOG(ERROR) << "Process " << pid << " not being watched"; 213 return false; 214 } 215 // Caller not interested in watching this process anymore, since the 216 // process termination is initiated by the caller. 217 watched_processes_.erase(pid); 218 } 219 220 // We are no longer interested in tracking the exit of this process. 221 // Also, we will hopefully reap this process ourselves, so remove any 222 // record of this pid from process_reaper_. 223 process_reaper_.ForgetChild(pid); 224 225 // Try SIGTERM firstly. 226 // Send SIGKILL signal if SIGTERM was not handled in a timely manner. 227 if (KillProcessWithTimeout(pid, false) || 228 KillProcessWithTimeout(pid, true)) { 229 return true; 230 } 231 232 // In case of killing failure. 233 LOG(ERROR) << "Timeout waiting for process " << pid << " to be killed."; 234 235 return false; 236 } 237 238 bool ProcessManager::KillProcessWithTimeout(pid_t pid, bool kill_signal) { 239 SLOG(this, 2) << __func__ << "(pid: " << pid << ")"; 240 241 bool killed = false; 242 if (KillProcess(pid, kill_signal ? SIGKILL : SIGTERM, &killed)) { 243 if (killed) { 244 return true; 245 } 246 247 int poll_times = kill_signal ? kWaitpidPollTimesForSIGKILL : 248 kWaitpidPollTimesForSIGTERM; 249 250 if (WaitpidWithTimeout(pid, kWaitpidPollInitialIntervalMilliseconds, 251 kWaitpidPollIntervalUpperBoundMilliseconds, 252 poll_times)) { 253 return true; 254 } 255 } 256 return false; 257 } 258 259 bool ProcessManager::KillProcess(pid_t pid, int signal, bool* killed) { 260 SLOG(this, 2) << __func__ << "(pid: " << pid << ")"; 261 262 if (kill(pid, signal) < 0) { 263 if (errno == ESRCH) { 264 SLOG(this, 2) << "Process " << pid << " has exited."; 265 *killed = true; 266 return true; 267 } 268 PLOG(ERROR) << "Failed to send " << signal <<"signal to process " << pid; 269 return false; 270 } 271 return true; 272 } 273 274 bool ProcessManager::WaitpidWithTimeout(pid_t pid, 275 unsigned int sleep_ms, 276 unsigned int upper_bound_ms, 277 int tries) { 278 SLOG(this, 2) << __func__ << "(pid: " << pid << ")"; 279 280 while (tries-- > 0) { 281 if (waitpid(pid, NULL, WNOHANG) == pid) { 282 return true; 283 } 284 usleep(sleep_ms * 1000); 285 if (2 * sleep_ms < upper_bound_ms) { 286 sleep_ms *= 2; 287 } 288 } 289 return false; 290 } 291 292 bool ProcessManager::UpdateExitCallback( 293 pid_t pid, 294 const base::Callback<void(int)>& new_callback) { 295 SLOG(this, 2) << __func__ << "(pid: " << pid << ")"; 296 297 const auto process_entry = watched_processes_.find(pid); 298 if (process_entry == watched_processes_.end()) { 299 LOG(ERROR) << "Process " << pid << " not being watched"; 300 return false; 301 } 302 303 process_entry->second = new_callback; 304 return true; 305 } 306 307 void ProcessManager::OnProcessExited(pid_t pid, const siginfo_t& info) { 308 SLOG(this, 2) << __func__ << "(pid: " << pid << ")"; 309 310 // Invoke the exit callback if the process is being watched. 311 auto watched_process = watched_processes_.find(pid); 312 if (watched_process != watched_processes_.end()) { 313 base::Callback<void(int)> callback = watched_process->second; 314 watched_processes_.erase(watched_process); 315 callback.Run(info.si_status); 316 return; 317 } 318 319 // Process terminated by us, cancel timeout handler. 320 auto terminated_process = pending_termination_processes_.find(pid); 321 if (terminated_process != pending_termination_processes_.end()) { 322 terminated_process->second->Cancel(); 323 pending_termination_processes_.erase(terminated_process); 324 return; 325 } 326 327 NOTREACHED() << "Unknown process " << pid << " status " << info.si_status; 328 } 329 330 void ProcessManager::ProcessTerminationTimeoutHandler(pid_t pid, 331 bool kill_signal) { 332 SLOG(this, 2) << __func__ << "(pid: " << pid << ")"; 333 334 CHECK(pending_termination_processes_.find(pid) != 335 pending_termination_processes_.end()); 336 pending_termination_processes_.erase(pid); 337 // Process still not killed after SIGKILL signal. 338 if (kill_signal) { 339 LOG(ERROR) << "Timeout waiting for process " << pid << " to be killed."; 340 return; 341 } 342 343 // Retry using SIGKILL signal. 344 TerminateProcess(pid, true); 345 } 346 347 bool ProcessManager::TerminateProcess(pid_t pid, bool kill_signal) { 348 SLOG(this, 2) << __func__ 349 << "(pid: " << pid << ", " 350 << "use_sigkill: " << kill_signal << ")"; 351 352 int signal = (kill_signal) ? SIGKILL : SIGTERM; 353 bool killed = false; 354 if (!KillProcess(pid, signal, &killed)) { 355 return false; 356 } 357 if (killed) { 358 return true; 359 } 360 std::unique_ptr<TerminationTimeoutCallback> termination_callback( 361 new TerminationTimeoutCallback( 362 base::Bind(&ProcessManager::ProcessTerminationTimeoutHandler, 363 weak_factory_.GetWeakPtr(), 364 pid, 365 kill_signal))); 366 dispatcher_->PostDelayedTask(termination_callback->callback(), 367 kTerminationTimeoutSeconds * 1000); 368 pending_termination_processes_.emplace(pid, std::move(termination_callback)); 369 return true; 370 } 371 372 } // namespace shill 373