Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Feb 2021 01:04:38 GMT
From:      Jamie Gritton <jamie@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 0a2a96f35a4c - main - jail: Don't allow jails under dying parents
Message-ID:  <202102230104.11N14caN003615@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by jamie:

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

commit 0a2a96f35a4c2dab3486438680fa289e12971e4b
Author:     Jamie Gritton <jamie@FreeBSD.org>
AuthorDate: 2021-02-23 01:04:06 +0000
Commit:     Jamie Gritton <jamie@FreeBSD.org>
CommitDate: 2021-02-23 01:04:06 +0000

    jail: Don't allow jails under dying parents
    
    If a jail is created with jail_set(...JAIL_DYING), and it has a parent
    currently in a dying state, that will bring the parent jail back to
    life.  Restrict that to require that the parent itself be explicitly
    brought back first, and not implicitly created along with the new
    child jail.
    
    Differential Revision:  https://reviews.freebsd.org/D28515
---
 sys/kern/kern_jail.c | 40 +++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 89dd039685a8..4f434637ccfa 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -990,7 +990,6 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
 	 * This abuses the file error codes ENOENT and EEXIST.
 	 */
 	pr = NULL;
-	ppr = mypr;
 	inspr = NULL;
 	if (cuflags == JAIL_CREATE && jid == 0 && name != NULL) {
 		namelc = strrchr(name, '.');
@@ -999,6 +998,12 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
 			jid = 0;
 	}
 	sx_xlock(&allprison_lock);
+	ppr = mypr;
+	if (!prison_isalive(ppr)) {
+		/* This jail is dying.  This process will surely follow. */
+		error = EAGAIN;
+		goto done_deref;
+	}
 	drflags = PD_LIST_XLOCKED;
 	if (jid != 0) {
 		if (jid < 0) {
@@ -1022,7 +1027,6 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
 			break;
 		}
 		if (pr != NULL) {
-			ppr = pr->pr_parent;
 			/* Create: jid must not exist. */
 			if (cuflags == JAIL_CREATE) {
 				/*
@@ -1044,6 +1048,13 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
 				vfs_opterror(opts, "jail %d not found", jid);
 				goto done_deref;
 			}
+			ppr = pr->pr_parent;
+			if (!prison_isalive(ppr)) {
+				error = ENOENT;
+				vfs_opterror(opts, "jail %d is dying",
+				    ppr->pr_id);
+				goto done_deref;
+			}
 			if (!prison_isalive(pr)) {
 				if (!(flags & JAIL_DYING)) {
 					error = ENOENT;
@@ -1109,15 +1120,13 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
 					    "jail \"%s\" not found", name);
 					goto done_deref;
 				}
-				if (!(flags & JAIL_DYING) &&
-				    !prison_isalive(ppr)) {
-					mtx_unlock(&ppr->pr_mtx);
+				mtx_unlock(&ppr->pr_mtx);
+				if (!prison_isalive(ppr)) {
 					error = ENOENT;
 					vfs_opterror(opts,
 					    "jail \"%s\" is dying", name);
 					goto done_deref;
 				}
-				mtx_unlock(&ppr->pr_mtx);
 				*namelc = '.';
 			}
 			namelc++;
@@ -1196,26 +1205,9 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
 				vfs_opterror(opts, "prison limit exceeded");
 				goto done_deref;
 			}
-		prison_hold(ppr);
-		if (!refcount_acquire_if_not_zero(&ppr->pr_uref)) {
-			/* This brings the parent back to life. */
-			mtx_lock(&ppr->pr_mtx);
-			refcount_acquire(&ppr->pr_uref);
-			ppr->pr_state = PRISON_STATE_ALIVE;
-			mtx_unlock(&ppr->pr_mtx);
-			error = osd_jail_call(ppr, PR_METHOD_CREATE, opts);
-			if (error) {
-				pr = ppr;
-				drflags |= PD_DEREF | PD_DEUREF;
-				goto done_deref;
-			}
-		}
-
 		if (jid == 0 && (jid = get_next_prid(&inspr)) == 0) {
 			error = EAGAIN;
 			vfs_opterror(opts, "no available jail IDs");
-			pr = ppr;
-			drflags |= PD_DEREF | PD_DEUREF;
 			goto done_deref;
 		}
 
@@ -1235,6 +1227,8 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
 			TAILQ_INSERT_TAIL(&allprison, pr, pr_list);
 
 		pr->pr_parent = ppr;
+		prison_hold(ppr);
+		prison_proc_hold(ppr);
 		LIST_INSERT_HEAD(&ppr->pr_children, pr, pr_sibling);
 		for (tpr = ppr; tpr != NULL; tpr = tpr->pr_parent)
 			tpr->pr_childcount++;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102230104.11N14caN003615>