Avoid reusing p_ksi while it is on queue.
When sending SIGCHLD informing reaper that a zombie was reparented to it, we might race with the situation where the previous parent still not finished delivering SIGCHLD and having its p_ksi structure on the signal queue. While on queue, the ksi should not be used for another send. Fix this by copying p_ksi into newly allocated ksi, which is directly put onto reaper sigqueue. The later ensures that siginfo for reaper SIGCHLD is always present, similar to guarantees for siginfo of child. Reported by: bdrewery Discussed with: jilles Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
2b6d1a639b
commit
9a2dde8013
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=315159
@ -189,6 +189,7 @@ exit1(struct thread *td, int rval, int signo)
|
||||
{
|
||||
struct proc *p, *nq, *q, *t;
|
||||
struct thread *tdt;
|
||||
ksiginfo_t *ksi, *ksi1;
|
||||
|
||||
mtx_assert(&Giant, MA_NOTOWNED);
|
||||
KASSERT(rval == 0 || signo == 0, ("exit1 rv %d sig %d", rval, signo));
|
||||
@ -449,14 +450,32 @@ exit1(struct thread *td, int rval, int signo)
|
||||
wakeup(q->p_reaper);
|
||||
for (; q != NULL; q = nq) {
|
||||
nq = LIST_NEXT(q, p_sibling);
|
||||
ksi = ksiginfo_alloc(TRUE);
|
||||
PROC_LOCK(q);
|
||||
q->p_sigparent = SIGCHLD;
|
||||
|
||||
if (!(q->p_flag & P_TRACED)) {
|
||||
proc_reparent(q, q->p_reaper);
|
||||
if (q->p_state == PRS_ZOMBIE) {
|
||||
/*
|
||||
* Inform reaper about the reparented
|
||||
* zombie, since wait(2) has something
|
||||
* new to report. Guarantee queueing
|
||||
* of the SIGCHLD signal, similar to
|
||||
* the _exit() behaviour, by providing
|
||||
* our ksiginfo. Ksi is freed by the
|
||||
* signal delivery.
|
||||
*/
|
||||
if (q->p_ksi == NULL) {
|
||||
ksi1 = NULL;
|
||||
} else {
|
||||
ksiginfo_copy(q->p_ksi, ksi);
|
||||
ksi->ksi_flags |= KSI_INS;
|
||||
ksi1 = ksi;
|
||||
ksi = NULL;
|
||||
}
|
||||
PROC_LOCK(q->p_reaper);
|
||||
pksignal(q->p_reaper, SIGCHLD, q->p_ksi);
|
||||
pksignal(q->p_reaper, SIGCHLD, ksi1);
|
||||
PROC_UNLOCK(q->p_reaper);
|
||||
}
|
||||
} else {
|
||||
@ -489,6 +508,8 @@ exit1(struct thread *td, int rval, int signo)
|
||||
kern_psignal(q, SIGKILL);
|
||||
}
|
||||
PROC_UNLOCK(q);
|
||||
if (ksi != NULL)
|
||||
ksiginfo_free(ksi);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user