From owner-dev-commits-src-all@freebsd.org Fri Mar 12 18:49:57 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id DCC765A9F0F; Fri, 12 Mar 2021 18:49:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Dxvxx5wBqz4jdB; Fri, 12 Mar 2021 18:49:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id BDDFA1CC08; Fri, 12 Mar 2021 18:49:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 12CInvXO047437; Fri, 12 Mar 2021 18:49:57 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 12CInvSA047436; Fri, 12 Mar 2021 18:49:57 GMT (envelope-from git) Date: Fri, 12 Mar 2021 18:49:57 GMT Message-Id: <202103121849.12CInvSA047436@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Jamie Gritton Subject: git: d2bbfc375487 - stable/13 - MFC jail: Don't allow jails under dying parents MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jamie X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: d2bbfc3754871f08e487ac59e5c03a088c8acad2 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Mar 2021 18:49:58 -0000 The branch stable/13 has been updated by jamie: URL: https://cgit.FreeBSD.org/src/commit/?id=d2bbfc3754871f08e487ac59e5c03a088c8acad2 commit d2bbfc3754871f08e487ac59e5c03a088c8acad2 Author: Jamie Gritton AuthorDate: 2021-02-23 01:04:06 +0000 Commit: Jamie Gritton CommitDate: 2021-03-12 18:49:13 +0000 MFC 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 (cherry picked from commit 0a2a96f35a4c2dab3486438680fa289e12971e4b) MFC jail: Fix locking on an early jail_set error. I had locked allprison_lock without immediately setting PD_LIST_LOCKED. (cherry picked from commit 108a9384e9e945cccba73c959f7e9cdb023cbcad) --- 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 547fca778dcf..b5c8f6ebf9be 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -992,7 +992,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, '.'); @@ -1002,6 +1001,12 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) } sx_xlock(&allprison_lock); drflags = PD_LIST_XLOCKED; + ppr = mypr; + if (!prison_isalive(ppr)) { + /* This jail is dying. This process will surely follow. */ + error = EAGAIN; + goto done_deref; + } if (jid != 0) { if (jid < 0) { error = EINVAL; @@ -1024,7 +1029,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) { /* @@ -1046,6 +1050,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; @@ -1111,15 +1122,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++; @@ -1198,26 +1207,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; } @@ -1237,6 +1229,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++;