1/* 2 * Copyright (c) 2000-2001,2003-2004 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// unixchild - low-level UNIX process child management. 27// 28// Note that the map-of-children (mChildren) only holds children presumed to 29// be alive. Neither unborn nor dead children are included. This is important 30// for how children are reaped and death notifications dispatched, and should 31// not be changed without prior deep contemplation. 32// 33// A note on locking: 34// All Child objects in this subsystem are mutated under control of a single 35// lock (mChildren). This means that children will not step on each other. 36// However, death callbacks (Child::dying) are made outside the lock's scope 37// to avoid deadlock scenarios with outside locking hierarchies. When Child::dying 38// is called, the child has already transitioned to "dead" state and is no longer 39// in the (live) children map. 40// 41#include "unixchild.h" 42#include <security_utilities/debugging.h> 43#include <signal.h> 44 45 46namespace Security { 47namespace UnixPlusPlus { 48 49 50// 51// All our globals are in a ModuleNexus, for that special lazy-init goodness 52// 53ModuleNexus<Child::Children> Child::mChildren; 54 55 56// 57// Make and break Children 58// 59Child::Child() 60 : mState(unborn), mPid(0), mStatus(0) 61{ 62} 63 64 65Child::~Child() 66{ 67 assert(mState != alive); // not allowed by protocol 68} 69 70 71// 72// Take a Child object that is not alive (i.e. is either unborn or dead), 73// and reset it to unborn, so you can fork() it again. 74// This call forgets everything about the previous process. 75// 76void Child::reset() 77{ 78 switch (mState) { 79 case alive: 80 assert(false); // bad boy; can't do that 81 case unborn: 82 break; // s'okay 83 default: 84 secdebug("unixchild", "%p reset (from state %d)", this, mState); 85 mState = unborn; 86 mPid = 0; 87 mStatus = 0; 88 break; 89 } 90} 91 92 93// 94// Global inquiries and setup 95// 96void Child::sharedChildren(bool s) 97{ 98 StLock<Mutex> _(mChildren()); 99 mChildren().shared = s; 100} 101 102bool Child::sharedChildren() 103{ 104 StLock<Mutex> _(mChildren()); 105 return mChildren().shared; 106} 107 108 109// 110// Check status for one Child 111// 112Child::State Child::check() 113{ 114 Child::State state; 115 bool reaped = false; 116 { 117 StLock<Mutex> _(mChildren()); 118 state = mState; 119 switch (mState) { 120 case alive: 121 reaped = checkStatus(WNOHANG); 122 break; 123 default: 124 break; 125 } 126 } 127 if (reaped) 128 this->dying(); 129 return state; 130} 131 132 133// 134// Wait for a particular child to be dead. 135// This call cannot wait for multiple children; you'll have 136// to program that yourself using whatever event loop you're using. 137// 138void Child::wait() 139{ 140 bool reaped = false; 141 { 142 StLock<Mutex> _(mChildren()); 143 switch (mState) { 144 case alive: 145 reaped = checkStatus(0); // wait for it 146 break; 147 case unborn: 148 assert(false); // don't do that 149 default: 150 break; 151 } 152 } 153 if (reaped) 154 this->dying(); 155} 156 157 158// 159// Common kill code. 160// Requires caller to hold mChildren() lock. 161// 162void Child::tryKill(int signal) 163{ 164 assert(mState == alive); // ... or don't bother us 165 secdebug("unixchild", "%p (pid %d) sending signal(%d)", this, pid(), signal); 166 if (::kill(pid(), signal)) 167 switch (errno) { 168 case ESRCH: // someone else reaped ths child; or things are just wacky 169 secdebug("unixchild", "%p (pid %d) has disappeared!", this, pid()); 170 mState = invalid; 171 mChildren().erase(pid()); 172 // fall through 173 default: 174 UnixError::throwMe(); 175 } 176} 177 178 179// 180// Send a signal to the Child. 181// This will succeed (and do nothing) if the Child is not alive. 182// 183void Child::kill(int signal) 184{ 185 StLock<Mutex> _(mChildren()); 186 if (mState == alive) 187 tryKill(signal); 188 else 189 secdebug("unixchild", "%p (pid %d) not alive; cannot send signal %d", 190 this, pid(), signal); 191} 192 193 194// 195// Kill with prejudice. 196// This will make a serious attempt to *synchronously* kill the process before 197// returning. If that doesn't work for some reason, abandon the child. 198// This is one thing you can do in the destructor of your subclass to legally 199// dispose of your Child's process. 200// 201void Child::kill() 202{ 203 // note that we mustn't hold the lock across these calls 204 if (this->state() == alive) { 205 this->kill(SIGTERM); // shoot it once 206 checkChildren(); // check for quick death 207 if (this->state() == alive) { 208 usleep(200000); // give it some time to die 209 if (this->state() == alive) { // could have been reaped by another thread 210 checkChildren(); // check again 211 if (this->state() == alive) { // it... just... won't... die... 212 this->kill(SIGKILL); // take THAT! 213 checkChildren(); 214 if (this->state() == alive) // stuck zombie 215 this->abandon(); // leave the body behind 216 } 217 } 218 } 219 } else 220 secdebug("unixchild", "%p (pid %d) not alive; ignoring request to kill it", this, pid()); 221} 222 223 224// 225// Take a living child and cut it loose. This sets its state to abandoned 226// and removes it from the child registry. 227// This is one thing you can do in the destructor of your subclass to legally 228// dispose of your child's process. 229// 230void Child::abandon() 231{ 232 StLock<Mutex> _(mChildren()); 233 if (mState == alive) { 234 secdebug("unixchild", "%p (pid %d) abandoned", this, pid()); 235 mState = abandoned; 236 mChildren().erase(pid()); 237 } else { 238 secdebug("unixchild", "%p (pid %d) is not alive; abandon() ignored", 239 this, pid()); 240 } 241} 242 243 244// 245// Forensic examination of the Child's cadaver. 246// Not interlocked because you have to check for state() == dead first, 247// and these values are const ever after. 248// 249int Child::waitStatus() const 250{ 251 assert(mState == dead); 252 return mStatus; 253} 254 255bool Child::bySignal() const 256{ 257 assert(mState == dead); 258 return WIFSIGNALED(mStatus); 259} 260 261int Child::exitCode() const 262{ 263 assert(mState == dead); 264 assert(WIFEXITED(mStatus)); 265 return WEXITSTATUS(mStatus); 266} 267 268int Child::exitSignal() const 269{ 270 assert(mState == dead); 271 assert(WIFSIGNALED(mStatus)); 272 return WTERMSIG(mStatus); 273} 274 275bool Child::coreDumped() const 276{ 277 assert(mState == dead); 278 assert(WIFSIGNALED(mStatus)); 279 return WCOREDUMP(mStatus); 280} 281 282 283// 284// Find a child in the child map, by pid 285// This will only find live children, and return NULL for all others. 286// 287Child *Child::findGeneric(pid_t pid) 288{ 289 StLock<Mutex> _(mChildren()); 290 Children::iterator it = mChildren().find(pid); 291 if (it == mChildren().end()) 292 return NULL; 293 else 294 return it->second; 295} 296 297 298// 299// Do the actual fork job. 300// At this layer, the client side does nothing but run childAction(). Any plumbing 301// or cleanup is up to that function (which runs in the child) and the caller (after 302// fork() returns). If childAction() returns at all, we will call exit(1) to get 303// rid of the child. 304// 305void Child::fork() 306{ 307 static const unsigned maxDelay = 30; // seconds increment, i.e. 5 retries 308 309 assert(mState == unborn); 310 for (unsigned delay = 1; ;) { 311 switch (pid_t pid = ::fork()) { 312 case -1: // fork failed 313 switch (errno) { 314 case EINTR: 315 secdebug("unixchild", "%p fork EINTR; retrying", this); 316 continue; // no problem 317 case EAGAIN: 318 if (delay < maxDelay) { 319 secdebug("unixchild", "%p fork EAGAIN; delaying %d seconds", 320 this, delay); 321 sleep(delay); 322 delay *= 2; 323 continue; 324 } 325 // fall through 326 default: 327 UnixError::throwMe(); 328 } 329 assert(false); // unreached 330 331 case 0: // child 332 //@@@ bother to clean child map? 333 secdebug("unixchild", "%p (child pid %d) running child action", 334 this, getpid()); 335 secdelay("/tmp/delay/unixchild"); 336 try { 337 this->childAction(); 338 secdebug("unixchild", "%p (pid %d) child action returned; exiting", 339 this, getpid()); 340 } catch (...) { 341 secdebug("unixchild", "%p (pid %d) child action had uncaught exception", 342 this, getpid()); 343 } 344 _exit(1); 345 346 default: // parent 347 { 348 StLock<Mutex> _(mChildren()); 349 mState = alive; 350 mPid = pid; 351 mChildren().insert(make_pair(pid, this)); 352 } 353 secdebug("unixchild", "%p (parent) running parent action", this); 354 this->parentAction(); 355 break; 356 } 357 break; 358 } 359} 360 361 362// 363// Check the status of this child by explicitly probing it. 364// Caller must hold master lock. 365// 366bool Child::checkStatus(int options) 367{ 368 assert(state() == alive); 369 secdebug("unixchild", "checking %p (pid %d)", this, this->pid()); 370 int status; 371 again: 372 switch (IFDEBUG(pid_t pid =) ::wait4(this->pid(), &status, options, NULL)) { 373 case pid_t(-1): 374 switch (errno) { 375 case EINTR: 376 goto again; // retry 377 case ECHILD: 378 secdebug("unixchild", "%p (pid=%d) unknown to kernel", this, this->pid()); 379 mState = invalid; 380 mChildren().erase(this->pid()); 381 return false; 382 default: 383 UnixError::throwMe(); 384 } 385 break; // placebo 386 case 0: 387 return false; // child not ready (do nothing) 388 default: 389 assert(pid == this->pid()); 390 bury(status); 391 return true; 392 } 393} 394 395 396// 397// Perform an idempotent check for dead children, as per the UNIX wait() system calls. 398// This can be called at any time, and will reap all children that have died since 399// last time. The obvious time to call this is after a SIGCHLD has been received; 400// however signal dispatch is so - uh, interesting - in UNIX that we don't even try 401// to deal with it at this level. Suffice to say that calling checkChildren directly 402// from within a signal handler is NOT generally safe due to locking constraints. 403// 404// If the shared() flag is on, we explicitly poll each child known to be recently 405// alive. That is less efficient than reaping any and all, but leaves any children 406// alone that someone else may have created without our knowledge. The default is 407// not shared(), which will reap (and discard) any unrelated children without letting 408// the caller know about it. 409// 410void Child::checkChildren() 411{ 412 Bier casualties; 413 { 414 StLock<Mutex> _(mChildren()); 415 if (mChildren().shared) { 416 for (Children::iterator it = mChildren().begin(); it != mChildren().end(); it++) 417 if (it->second->checkStatus(WNOHANG)) 418 casualties.add(it->second); 419 } else if (!mChildren().empty()) { 420 int status; 421 while (pid_t pid = ::wait4(0, &status, WNOHANG, NULL)) { 422 secdebug("unixchild", "universal child check (%ld children known alive)", mChildren().size()); 423 switch (pid) { 424 case pid_t(-1): 425 switch (errno) { 426 case EINTR: 427 secdebug("unixchild", "EINTR on wait4; retrying"); 428 continue; // benign, but retry the wait() 429 case ECHILD: 430 // Should not normally happen (there *is* a child around), 431 // but gets returned anyway if the child is stopped in the debugger. 432 // Treat like a zero return (no children ready to be buried). 433 secdebug("unixchild", "ECHILD with filled nursery (ignored)"); 434 goto no_more; 435 default: 436 UnixError::throwMe(); 437 } 438 break; 439 default: 440 if (Child *child = mChildren()[pid]) { 441 child->bury(status); 442 casualties.add(child); 443 } else 444 secdebug("unixchild", "reaping feral child pid=%d", pid); 445 if (mChildren().empty()) 446 goto no_more; // none left 447 break; 448 } 449 } 450 no_more: ; 451 } else { 452 secdebug("unixchild", "spurious checkChildren (the nursery is empty)"); 453 } 454 } // release master lock 455 casualties.notify(); 456} 457 458 459// 460// Perform the canonical last rites for a formerly alive child. 461// Requires master lock held throughout. 462// 463void Child::bury(int status) 464{ 465 assert(mState == alive); 466 mState = dead; 467 mStatus = status; 468 mChildren().erase(mPid); 469#if !defined(NDEBUG) 470 if (bySignal()) 471 secdebug("unixchild", "%p (pid %d) died by signal %d%s", 472 this, mPid, exitSignal(), 473 coreDumped() ? " and dumped core" : ""); 474 else 475 secdebug("unixchild", "%p (pid %d) died by exit(%d)", 476 this, mPid, exitCode()); 477#endif //NDEBUG 478} 479 480 481// 482// Default hooks 483// 484void Child::parentAction() 485{ /* nothing */ } 486 487void Child::dying() 488{ /* nothing */ } 489 490 491// 492// Biers 493// 494void Child::Bier::notify() 495{ 496 for (const_iterator it = begin(); it != end(); ++it) 497 (*it)->dying(); 498} 499 500 501} // end namespace IPPlusPlus 502} // end namespace Security 503