From nobody Mon Jan 20 00:28:00 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Ybrlj1tQRz5jxZt; Mon, 20 Jan 2025 00:28:01 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Ybrlh55Ftz3dpC; Mon, 20 Jan 2025 00:28:00 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1737332880; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=YQBNE3EkhmuUpH/M6Qv/7lbiAfQ9jn5zPkTMDF3jD5o=; b=OxiShi0M83nnlxclcIc7Jxo+UMbq3+970pa0ndRSOQ8UkN00/sSoZG+BVVOsLu9fbr68F1 ahODvLiFo/b0WFTj3YWISGYtrnGoNc9h6QTqnjV0D1b3yP5jbw99wndFZVgw9JWyyAuXr3 JjihczWNlXOAqCS6TfzPqLaR+zQUwpS0VV1JkJl7YDdg+nPMu5fq61cfTaRx4ECaUftvcy 9Wr6R+lFRZGxK2T4KwCntWnwquojxQ4if7YB943R+XOsKl0DY3lbWSODhQ5JgRrG6IsNTM 2C9DM10dLJYRLJ7cLsmkMSkHgcFUQqDtIuNoO1oV/R60vQ0baY/RHN3f0W+Dmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1737332880; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=YQBNE3EkhmuUpH/M6Qv/7lbiAfQ9jn5zPkTMDF3jD5o=; b=iOygzJcE4zk9Ksx4+wpN38p2FVQFWyNqKg2koeooh4gzGgj9vrS2H/9BjIUWfXj58tdxHI gQ61lDuLNL/ebUyjtlxGjjdBQlvM4vgMNffNhJOicBThObXcHs0BMM7a9Y+Zno2INrq3xZ B4ywGd+ferqWOACSf2mUI+PGqFHr5lfHKVgFzWwZd3m9R7nGbav5O/x8e2Q3ks3CkyURml wHV06BRosSqrRUa7jnORTy9aZkfAYAUakROZhaDxiYy/oR2ChHxs9PeVP9dtA4V61RKmc6 ri/H0GpGUcSsyvsG32O9CbCHaFff7aL8NYNtC4YHhN6L/6M9BTmNbPD+HPVJ/g== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1737332880; a=rsa-sha256; cv=none; b=A7/QETDrXi7MQMjA0GHYtcGH7E5tvPw1K/F8PgLwoVsEninTh7TVMZxb2d5PQ/hDJ8Yli7 JOtCclee3H1KPSJDdE+wwpsw8uiwOrn1JqCER3Qp5QwVc2j+6rATMpJ1Zsa2tk/crXffg6 +PzGoZfG9kGfwI1wSfp+nr69XJmJ813qtpRn4zKG40Xk3mHsvomZ5VXyS888ugS6lUYfFf NJFll4oDFDsE67Ln+8BWytnz3mjiED4ks41faquAx4yyXY9uLR3cGOoWuYPvjoFGX87NXf 60ZQAQfnkEoZHck1FTc1CXVAFXRB5EzRubgHu/HrkfDm9l7434nKBfsKO0/Z+g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none 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 4Ybrlh4gT8z1Bjm; Mon, 20 Jan 2025 00:28:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 50K0S0LU019083; Mon, 20 Jan 2025 00:28:00 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 50K0S0YU019080; Mon, 20 Jan 2025 00:28:00 GMT (envelope-from git) Date: Mon, 20 Jan 2025 00:28:00 GMT Message-Id: <202501200028.50K0S0YU019080@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: bd40a5abb1f8 - stable/14 - jail: Avoid a potential use-after-free when destroying jails List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: bd40a5abb1f8810310a8841c34e469019002993f Auto-Submitted: auto-generated The branch stable/14 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=bd40a5abb1f8810310a8841c34e469019002993f commit bd40a5abb1f8810310a8841c34e469019002993f Author: Mark Johnston AuthorDate: 2025-01-06 22:53:38 +0000 Commit: Mark Johnston CommitDate: 2025-01-20 00:26:43 +0000 jail: Avoid a potential use-after-free when destroying jails prison_deref() and prison_deref_kill() have to handle the case where destruction of a jail will release the final reference on the jail's parent, resulting in destruction of the parent jail. They thus maintain a list of jails whose references have gone away; the loop at the end of prison_deref() then goes through the list and deallocates resources associated with each jail. In particular, if a jail's VNET is not the same as that of its parent, this loop destroys the VNET. Suppose prison_deref() removes the last reference on a jail, releasing a reference to its parent and causing the jail to be placed in the "freeprison" list. Suppose then that the parent jail is destroyed before the "freeprison" list is processed. When destroying the now-orphaned child jail, prison_deref() derefences its parent to see whether the child jail's VNET needs to be freed, but if this race occurs, this is a use-after-free. Fix the problem by using PR_VNET to decide whether the jail's VNET is to be destroyed, rather than dereferencing the parent jail pointer. Set it earlier so that a subsequent failure in kern_jail_set() cleans up the nascent VNET. Reviewed by: zlei (previous version), jamie MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D47992 (cherry picked from commit 8c75c15d43e4123bc51f24f5bf99319289c45a6c) --- sys/kern/kern_jail.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 6f2b4f7fc336..103b44cc00b9 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -1701,9 +1701,18 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) sizeof(pr->pr_osrelease)); #ifdef VIMAGE - /* Allocate a new vnet if specified. */ - pr->pr_vnet = (pr_flags & PR_VNET) - ? vnet_alloc() : ppr->pr_vnet; + /* + * Allocate a new vnet if specified. + * + * Set PR_VNET now if so, so that the vnet is disposed of + * properly when the jail is destroyed. + */ + if (pr_flags & PR_VNET) { + pr->pr_flags |= PR_VNET; + pr->pr_vnet = vnet_alloc(); + } else { + pr->pr_vnet = ppr->pr_vnet; + } #endif /* * Allocate a dedicated cpuset for each jail. @@ -3173,9 +3182,12 @@ prison_deref(struct prison *pr, int flags) * Removing a prison frees references * from its parent. */ + ppr = pr->pr_parent; + pr->pr_parent = NULL; mtx_unlock(&pr->pr_mtx); + + pr = ppr; flags &= ~PD_LOCKED; - pr = pr->pr_parent; flags |= PD_DEREF | PD_DEUREF; continue; } @@ -3202,7 +3214,7 @@ prison_deref(struct prison *pr, int flags) */ TAILQ_FOREACH_SAFE(rpr, &freeprison, pr_list, tpr) { #ifdef VIMAGE - if (rpr->pr_vnet != rpr->pr_parent->pr_vnet) + if (rpr->pr_flags & PR_VNET) vnet_destroy(rpr->pr_vnet); #endif if (rpr->pr_root != NULL)