From nobody Fri Jan 16 00:24:17 2026 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 4dsgZt3vrQz6NQFc for ; Fri, 16 Jan 2026 00:24:22 +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 "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4dsgZt1fRCz3ZWK for ; Fri, 16 Jan 2026 00:24:22 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1768523062; 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=bKegVE+9QRzwRXfHZS6sJAP4+EeLqAUetfpe5JpudNI=; b=kAmn7ZazT5J5XQYbNtWBr5pxgBDgec79aVtsvuT/2SSd0MTRLJVaRVZs5bJusWPsf2Dc5G 8ff5lAQwO8UD6XDnFZSa6pIYG42ScyFAh0ZztVmLFuBIF3wBS6s/kzKm3Rp6Jll0GycRpO A/AgWcpGZtHzJyGfs5lTIGCbtYgDfJeAjcAlxBB4joc+fwh8JmXJOgR72A+/8/yDkMBMef Wfen0oH1gX39RVH3Lbe+9Wi0R58I8HOmfYzkTK1+CE1bqtQlT3lX+1rmsMYeh1qNuRItoF v64qJaYdClCVE4Mx5Fl7Bfe2gDgWDbABdaYZTCtSJEEU8p2BJeBiYpUa3/O+eQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1768523062; 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=bKegVE+9QRzwRXfHZS6sJAP4+EeLqAUetfpe5JpudNI=; b=DO8XSkgYDKBgxVCE38sVGZtBx8k1DhBdRrKnduvbXlnW2ecEDR89N7xj4UPKod2hQHMu7E 4siZcFZ3ZXEw1BJOIXXBJjcbhmbNHupFcBLpA1W7cXEtXoSLubKiSLWxxhRsVrTqHMxiRN 2hOFEyqpQMpfscfvxcYNwsm+N5xuAsfTvjJutJJ9v1/vgsKmwhIALx54/LC2FyGKaY7LYS olHuTbS2uMLPt2v8y490oLn5cPB1cGct9lg68FVbAifxg7UCdp5RorcKZmZD5o4205Wa3D ENRQpCsiYZOADmPqge5zmHDo+W21fY6GFwl+FhFg85kj+lIXfzDpjiolka/pFw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1768523062; a=rsa-sha256; cv=none; b=Jlta++ifCja63elFTaWnWdyIfhijr+G03ZRo3db9sjLAw5ilcHUIjCxI+EhK/jYdY8qN6f 6p51whu8WekhGexqKUTJA2t+WcUZLxiwrcYIwFfEpPKUI0cimMh247IYzYinOJ3bLEpWXj IUqRl7wonR4rgZSele3WVwkDHIsFyHO3TdXxDu73QHW31IhCZJ3vlD0VrIddbXznxKJeBQ EzNgMktPGyYAm4ZxfXkHn4/ryye+yEu4EWe0NZcH7191gAk9Y08s4o14n244EFdETF5KmW lI3x9Mf86lmJiU0nQ5AZuaeHDtvABFF+9M30l06AHC7fEqLXv+2X/w2wie8sIQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4dsgZn19lPzqqB for ; Fri, 16 Jan 2026 00:24:17 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3a85d by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 16 Jan 2026 00:24:17 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kyle Evans Subject: git: 11d6ea47f06a - main - kern: mac: add a MAC label to struct prison 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: kevans X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 11d6ea47f06a38f66536b173e85ddf2674da6aff Auto-Submitted: auto-generated Date: Fri, 16 Jan 2026 00:24:17 +0000 Message-Id: <69698531.3a85d.6888870a@gitrepo.freebsd.org> The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=11d6ea47f06a38f66536b173e85ddf2674da6aff commit 11d6ea47f06a38f66536b173e85ddf2674da6aff Author: Kyle Evans AuthorDate: 2025-10-04 03:46:03 +0000 Commit: Kyle Evans CommitDate: 2026-01-16 00:23:39 +0000 kern: mac: add a MAC label to struct prison Reviewed by: olce Differential Revision: https://reviews.freebsd.org/D53953 --- sys/conf/files | 1 + sys/kern/kern_jail.c | 26 +++++++ sys/security/mac/mac_framework.c | 1 + sys/security/mac/mac_framework.h | 6 ++ sys/security/mac/mac_internal.h | 9 +++ sys/security/mac/mac_policy.h | 20 ++++++ sys/security/mac/mac_prison.c | 144 +++++++++++++++++++++++++++++++++++++++ sys/sys/jail.h | 1 + 8 files changed, 208 insertions(+) diff --git a/sys/conf/files b/sys/conf/files index d0c4ea5f544d..a6a76dec433a 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -5264,6 +5264,7 @@ security/mac/mac_net.c optional mac security/mac/mac_pipe.c optional mac security/mac/mac_posix_sem.c optional mac security/mac/mac_posix_shm.c optional mac +security/mac/mac_prison.c optional mac security/mac/mac_priv.c optional mac security/mac/mac_process.c optional mac security/mac/mac_socket.c optional mac diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index f803be76a70e..8c224597bdf5 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -275,8 +275,17 @@ prison0_init(void) uint8_t *file, *data; size_t size; char buf[sizeof(prison0.pr_hostuuid)]; +#ifdef MAC + int error __diagused; +#endif bool valid; +#ifdef MAC + error = mac_prison_init(&prison0, M_WAITOK); + MPASS(error == 0); + + mtx_unlock(&prison0.pr_mtx); +#endif prison0.pr_cpuset = cpuset_ref(thread0.td_cpuset); prison0.pr_osreldate = osreldate; strlcpy(prison0.pr_osrelease, osrelease, sizeof(prison0.pr_osrelease)); @@ -1828,7 +1837,14 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags) if (error) goto done_deref; +#ifdef MAC + error = mac_prison_init(pr, M_WAITOK); + MPASS(error == 0); + + mtx_assert(&pr->pr_mtx, MA_OWNED); +#else mtx_lock(&pr->pr_mtx); +#endif drflags |= PD_LOCKED; } else { /* @@ -3540,6 +3556,16 @@ prison_deref(struct prison *pr, int flags) KASSERT( refcount_load(&prison0.pr_ref) != 0, ("prison0 pr_ref=0")); +#ifdef MAC + /* + * The MAC framework will call into any + * policies that want to hook + * prison_destroy_label, so ideally we + * call this prior to any final state + * invalidation to be safe. + */ + mac_prison_destroy(pr); +#endif pr->pr_state = PRISON_STATE_INVALID; TAILQ_REMOVE(&allprison, pr, pr_list); LIST_REMOVE(pr, pr_sibling); diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c index b0776160cc74..fec63b99c0e0 100644 --- a/sys/security/mac/mac_framework.c +++ b/sys/security/mac/mac_framework.c @@ -374,6 +374,7 @@ mac_policy_getlabeled(struct mac_policy_conf *mpc) MPC_FLAG(mount_init_label, MPC_OBJECT_MOUNT); MPC_FLAG(posixsem_init_label, MPC_OBJECT_POSIXSEM); MPC_FLAG(posixshm_init_label, MPC_OBJECT_POSIXSHM); + MPC_FLAG(prison_init_label, MPC_OBJECT_PRISON); MPC_FLAG(sysvmsg_init_label, MPC_OBJECT_SYSVMSG); MPC_FLAG(sysvmsq_init_label, MPC_OBJECT_SYSVMSQ); MPC_FLAG(sysvsem_init_label, MPC_OBJECT_SYSVSEM); diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h index 1233cd30f211..f14e8d7d1e7d 100644 --- a/sys/security/mac/mac_framework.h +++ b/sys/security/mac/mac_framework.h @@ -73,6 +73,7 @@ struct mount; struct msg; struct msqid_kernel; struct pipepair; +struct prison; struct proc; struct semid_kernel; struct shmfd; @@ -346,6 +347,11 @@ void mac_posixshm_create(struct ucred *cred, struct shmfd *shmfd); void mac_posixshm_destroy(struct shmfd *); void mac_posixshm_init(struct shmfd *); +int mac_prison_init(struct prison *pr, int flag); +void mac_prison_relabel(struct ucred *cred, struct prison *pr, + struct label *newlabel); +void mac_prison_destroy(struct prison *pr); + int mac_priv_check_impl(struct ucred *cred, int priv); #ifdef MAC extern bool mac_priv_check_fp_flag; diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h index aeef59017d18..a882a476d1b0 100644 --- a/sys/security/mac/mac_internal.h +++ b/sys/security/mac/mac_internal.h @@ -177,6 +177,7 @@ struct label { #define MPC_OBJECT_SYSVSHM 0x0000000000020000 #define MPC_OBJECT_SYNCACHE 0x0000000000040000 #define MPC_OBJECT_IP6Q 0x0000000000080000 +#define MPC_OBJECT_PRISON 0x0000000000100000 /* * MAC Framework global variables. @@ -252,6 +253,14 @@ int mac_pipe_externalize_label(struct label *label, char *elements, char *outbuf, size_t outbuflen); int mac_pipe_internalize_label(struct label *label, char *string); +int mac_prison_check_relabel(struct ucred *cred, struct prison *pr, + struct label *newlabel); +int mac_prison_externalize_label(struct label *label, char *elements, + char *outbuf, size_t outbuflen); +int mac_prison_internalize_label(struct label *label, char *string); +void mac_prison_relabel(struct ucred *cred, struct prison *pr, + struct label *newlabel); + int mac_socket_label_set(struct ucred *cred, struct socket *so, struct label *label); void mac_socket_copy_label(struct label *src, struct label *dest); diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h index f0a1f0863c96..fba1f4a1c85e 100644 --- a/sys/security/mac/mac_policy.h +++ b/sys/security/mac/mac_policy.h @@ -88,6 +88,7 @@ struct mount; struct msg; struct msqid_kernel; struct pipepair; +struct prison; struct proc; struct sbuf; struct semid_kernel; @@ -407,6 +408,18 @@ typedef void (*mpo_posixshm_create_t)(struct ucred *cred, typedef void (*mpo_posixshm_destroy_label_t)(struct label *label); typedef void (*mpo_posixshm_init_label_t)(struct label *label); +typedef int (*mpo_prison_init_label_t)(struct label *label, int flag); +typedef int (*mpo_prison_check_relabel_t)(struct ucred *cred, + struct prison *pr, struct label *prlabel, + struct label *newlabel); +typedef void (*mpo_prison_destroy_label_t)(struct label *label); +typedef int (*mpo_prison_externalize_label_t)(struct label *label, + char *element_name, struct sbuf *sb, int *claimed); +typedef int (*mpo_prison_internalize_label_t)(struct label *label, + char *element_name, char *element_data, int *claimed); +typedef void (*mpo_prison_relabel_t)(struct ucred *cred, struct prison *pr, + struct label *prlabel, struct label *newlabel); + typedef int (*mpo_priv_check_t)(struct ucred *cred, int priv); typedef int (*mpo_priv_grant_t)(struct ucred *cred, int priv); @@ -863,6 +876,13 @@ struct mac_policy_ops { mpo_posixshm_destroy_label_t mpo_posixshm_destroy_label; mpo_posixshm_init_label_t mpo_posixshm_init_label; + mpo_prison_init_label_t mpo_prison_init_label; + mpo_prison_check_relabel_t mpo_prison_check_relabel; + mpo_prison_destroy_label_t mpo_prison_destroy_label; + mpo_prison_externalize_label_t mpo_prison_externalize_label; + mpo_prison_internalize_label_t mpo_prison_internalize_label; + mpo_prison_relabel_t mpo_prison_relabel; + mpo_priv_check_t mpo_priv_check; mpo_priv_grant_t mpo_priv_grant; diff --git a/sys/security/mac/mac_prison.c b/sys/security/mac/mac_prison.c new file mode 100644 index 000000000000..e24ffa9e698d --- /dev/null +++ b/sys/security/mac/mac_prison.c @@ -0,0 +1,144 @@ +/*- + * Copyright (c) 2025 Kyle Evans + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include "opt_mac.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static void +mac_prison_label_free(struct label *label) +{ + if (label == NULL) + return; + + MAC_POLICY_PERFORM_NOSLEEP(prison_destroy_label, label); + mac_labelzone_free(label); +} + +static struct label * +mac_prison_label_alloc(int flag) +{ + struct label *label; + int error; + + label = mac_labelzone_alloc(flag); + if (label == NULL) + return (NULL); + + if (flag & M_WAITOK) + MAC_POLICY_CHECK(prison_init_label, label, flag); + else + MAC_POLICY_CHECK_NOSLEEP(prison_init_label, label, flag); + if (error) { + mac_prison_label_free(label); + return (NULL); + } + return (label); +} + +/* + * The caller's expecting us to return with the prison locked if we were + * successful, since we're also setting pr->pr_label. On error, it remains + * unlocked. + */ +int +mac_prison_init(struct prison *pr, int flag) +{ + struct label *prlabel; + + mtx_assert(&pr->pr_mtx, MA_NOTOWNED); + if ((mac_labeled & MPC_OBJECT_PRISON) == 0) { + mtx_lock(&pr->pr_mtx); + pr->pr_label = NULL; + return (0); + } + + prlabel = mac_prison_label_alloc(flag); + if (prlabel == NULL) { + KASSERT((flag & M_WAITOK) == 0, + ("MAC policy prison_init_label failed under M_WAITOK")); + return (ENOMEM); + } + + mtx_lock(&pr->pr_mtx); + pr->pr_label = prlabel; + return (0); +} + +void +mac_prison_destroy(struct prison *pr) +{ + mtx_assert(&pr->pr_mtx, MA_OWNED); + mac_prison_label_free(pr->pr_label); + pr->pr_label = NULL; +} + +int +mac_prison_externalize_label(struct label *label, char *elements, + char *outbuf, size_t outbuflen) +{ + int error; + + MAC_POLICY_EXTERNALIZE(prison, label, elements, outbuf, outbuflen); + return (error); +} + +int +mac_prison_internalize_label(struct label *label, char *string) +{ + int error; + + MAC_POLICY_INTERNALIZE(prison, label, string); + return (error); +} + +void +mac_prison_relabel(struct ucred *cred, struct prison *pr, + struct label *newlabel) +{ + mtx_assert(&pr->pr_mtx, MA_OWNED); + MAC_POLICY_PERFORM_NOSLEEP(prison_relabel, cred, pr, pr->pr_label, + newlabel); +} + +MAC_CHECK_PROBE_DEFINE4(prison_check_relabel, "struct ucred *", + "struct prison *", "struct label *", "struct label *"); +int +mac_prison_check_relabel(struct ucred *cred, struct prison *pr, + struct label *newlabel) +{ + int error; + + mtx_assert(&pr->pr_mtx, MA_OWNED); + MAC_POLICY_CHECK_NOSLEEP(prison_check_relabel, cred, pr, + pr->pr_label, newlabel); + MAC_CHECK_PROBE4(prison_check_relabel, error, cred, pr, + pr->pr_label, newlabel); + + return (error); +} diff --git a/sys/sys/jail.h b/sys/sys/jail.h index e6a13e6719dd..5ac4c5f9008d 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -198,6 +198,7 @@ struct prison { struct prison_ip *pr_addrs[PR_FAMILY_MAX]; /* (p,n) IPs of jail */ struct prison_racct *pr_prison_racct; /* (c) racct jail proxy */ struct knlist *pr_klist; /* (m) attached knotes */ + struct label *pr_label; /* (m) MAC label */ LIST_HEAD(, jaildesc) pr_descs; /* (a) attached descriptors */ void *pr_sparep; int pr_childcount; /* (a) number of child jails */