git: 79af745f4c29 - main - jail: Fix a race in prison_deref()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 25 Sep 2026 17:00:45 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=79af745f4c29ab3df037fcf0a4b4fb1ea393825f
commit 79af745f4c29ab3df037fcf0a4b4fb1ea393825f
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-09-25 15:16:24 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-25 16:50:41 +0000
jail: Fix a race in prison_deref()
If we're killing a jail which has some user refs pending, then we would
first drop our ref and then kill all processes in the prison. However,
it's possible for the prison to be freed before we finish that
operation, generally if the processes exit on their own before
prison_proc_iterate() returns.
Thus, defer the release of the prison refcount until after we've killed
all procs.
Reviewed by: jamie
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D59984
---
sys/kern/kern_jail.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 31b7c4a1e4f6..79922c3a0d38 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -3723,8 +3723,10 @@ prison_deref(struct prison *pr, int flags)
* that need to be killed, either in this prison or its
* descendants.
*/
- if (refcount_load(&pr->pr_uref) > 0)
+ if (refcount_load(&pr->pr_uref) > 0) {
killpr = pr;
+ flags &= ~PD_DEREF;
+ }
/* Make sure the parent prison doesn't get killed. */
flags &= ~PD_KILL;
}
@@ -3794,8 +3796,10 @@ prison_deref(struct prison *pr, int flags)
sx_xunlock(&allprison_lock);
/* Kill any processes attached to a killed prison. */
- if (killpr != NULL)
+ if (killpr != NULL) {
prison_proc_iterate(killpr, prison_kill_processes_cb, NULL);
+ prison_free(killpr);
+ }
/*
* Finish removing any unreferenced prisons, which couldn't happen