Avoid the user-visible effect of setting SA_NOCLDWAIT when the
SIGCHLD handler is SIG_IGN. This is a reimplementation of the problematic revision 1.131 of kern_exit.c. To avoid accessing process UPAGES, we set a new procsig flag when the SIGCHLD handler is SIG_IGN and use that instead.
This commit is contained in:
@@ -368,10 +368,10 @@ exit1(td, rv)
|
||||
|
||||
/*
|
||||
* Notify parent that we're gone. If parent has the PS_NOCLDWAIT
|
||||
* flag set, notify process 1 instead (and hope it will handle
|
||||
* this situation).
|
||||
* flag set, or if the handler is set to SIG_IGN, notify process
|
||||
* 1 instead (and hope it will handle this situation).
|
||||
*/
|
||||
if (p->p_pptr->p_procsig->ps_flag & PS_NOCLDWAIT) {
|
||||
if (p->p_pptr->p_procsig->ps_flag & (PS_NOCLDWAIT | PS_CLDSIGIGN)) {
|
||||
struct proc *pp = p->p_pptr;
|
||||
PROC_UNLOCK(pp);
|
||||
proc_reparent(p, initproc);
|
||||
|
||||
+6
-3
@@ -304,8 +304,7 @@ do_sigaction(p, sig, act, oact, old)
|
||||
p->p_procsig->ps_flag |= PS_NOCLDSTOP;
|
||||
else
|
||||
p->p_procsig->ps_flag &= ~PS_NOCLDSTOP;
|
||||
if ((act->sa_flags & SA_NOCLDWAIT) ||
|
||||
ps->ps_sigact[_SIG_IDX(SIGCHLD)] == SIG_IGN) {
|
||||
if (act->sa_flags & SA_NOCLDWAIT) {
|
||||
/*
|
||||
* Paranoia: since SA_NOCLDWAIT is implemented
|
||||
* by reparenting the dying child to PID 1 (and
|
||||
@@ -318,6 +317,10 @@ do_sigaction(p, sig, act, oact, old)
|
||||
p->p_procsig->ps_flag |= PS_NOCLDWAIT;
|
||||
} else
|
||||
p->p_procsig->ps_flag &= ~PS_NOCLDWAIT;
|
||||
if (ps->ps_sigact[_SIG_IDX(SIGCHLD)] == SIG_IGN)
|
||||
p->p_procsig->ps_flag |= PS_CLDSIGIGN;
|
||||
else
|
||||
p->p_procsig->ps_flag &= ~PS_CLDSIGIGN;
|
||||
}
|
||||
/*
|
||||
* Set bit in p_sigignore for signals that are set to SIG_IGN,
|
||||
@@ -499,7 +502,7 @@ execsigs(p)
|
||||
/*
|
||||
* Reset no zombies if child dies flag as Solaris does.
|
||||
*/
|
||||
p->p_procsig->ps_flag &= ~PS_NOCLDWAIT;
|
||||
p->p_procsig->ps_flag &= ~(PS_NOCLDWAIT | PS_CLDSIGIGN);
|
||||
if (ps->ps_sigact[_SIG_IDX(SIGCHLD)] == SIG_IGN)
|
||||
ps->ps_sigact[_SIG_IDX(SIGCHLD)] = SIG_DFL;
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
@@ -106,6 +106,7 @@ struct procsig {
|
||||
|
||||
#define PS_NOCLDWAIT 0x0001 /* No zombies if child dies */
|
||||
#define PS_NOCLDSTOP 0x0002 /* No SIGCHLD when children stop. */
|
||||
#define PS_CLDSIGIGN 0x0004 /* The SIGCHLD handler is SIG_IGN. */
|
||||
|
||||
/*
|
||||
* pargs, used to hold a copy of the command line, if it had a sane length.
|
||||
|
||||
Reference in New Issue
Block a user