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