git: e0343eacf365 - main - reap_kill_subtree(): hold the reaper when entering it into the queue to handle later

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 13 Jun 2022 19:33:41 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=e0343eacf36588bf503c7a59c0cc436294223839

commit e0343eacf36588bf503c7a59c0cc436294223839
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-05-15 22:52:09 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-06-13 19:30:03 +0000

    reap_kill_subtree(): hold the reaper when entering it into the queue to handle later
    
    We drop proctree_lock, which allows the process to exit while memoized
    in the list to proceed.
    
    Reported and tested by: pho
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
    Differential revision:  https://reviews.freebsd.org/D35310
---
 sys/kern/kern_procctl.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/sys/kern/kern_procctl.c b/sys/kern/kern_procctl.c
index 02469f25bc3d..b32a4156dafb 100644
--- a/sys/kern/kern_procctl.c
+++ b/sys/kern/kern_procctl.c
@@ -336,11 +336,25 @@ reap_kill_sched(struct reap_kill_tracker_head *tracker, struct proc *p2)
 {
 	struct reap_kill_tracker *t;
 
+	PROC_LOCK(p2);
+	if ((p2->p_flag2 & P2_WEXIT) != 0) {
+		PROC_UNLOCK(p2);
+		return;
+	}
+	_PHOLD_LITE(p2);
+	PROC_UNLOCK(p2);
 	t = malloc(sizeof(struct reap_kill_tracker), M_TEMP, M_WAITOK);
 	t->parent = p2;
 	TAILQ_INSERT_TAIL(tracker, t, link);
 }
 
+static void
+reap_kill_sched_free(struct reap_kill_tracker *t)
+{
+	PRELE(t->parent);
+	free(t, M_TEMP);
+}
+
 static void
 reap_kill_children(struct thread *td, struct proc *reaper,
     struct procctl_reaper_kill *rk, ksiginfo_t *ksi, int *error)
@@ -379,7 +393,7 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper,
 		 * reaper, which should handle it.
 		 */
 		if ((t->parent->p_treeflag & P_TREE_REAPER) == 0) {
-			free(t, M_TEMP);
+			reap_kill_sched_free(t);
 			res = true;
 			continue;
 		}
@@ -396,7 +410,7 @@ reap_kill_subtree_once(struct thread *td, struct proc *p, struct proc *reaper,
 			reap_kill_proc(td, p2, ksi, rk, error);
 			res = true;
 		}
-		free(t, M_TEMP);
+		reap_kill_sched_free(t);
 	}
 	return (res);
 }