The branch main has been updated by kevans:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=8254b0dec02b376dae259cd2043513842d827bd8

commit 8254b0dec02b376dae259cd2043513842d827bd8
Author:     Kyle Evans <[email protected]>
AuthorDate: 2025-10-21 03:42:50 +0000
Commit:     Kyle Evans <[email protected]>
CommitDate: 2026-01-16 00:23:39 +0000

    kern: mac: add various jail MAC hooks
    
    This adds the following hooks:
     - mpo_prison_check_attach: check for subject capability to attach to
        a given jail
     - mpo_prison_check_create: check for subject capability to create a
        jail with the given option set
     - mpo_prison_check_get: check for subject capability to fetch the
        given parameters for a jail
     - mpo_prison_check_set: check for subject capability to set the
        given parameters for a jail
     - mpo_prison_check_remove: check for subject capability to remove the
        jail
    
    check_get wouldn't typically be a privileged operation, but is included
    to give MAC policies a wider range of capabilities at a relatively low
    cost.  We also add two more for the purpose of label propagation:
     - mpo_prison_created: surface the creation of a jail so that one can
        do propagation to, e.g., the root vnode or any mounts
     - mpo_prison_attached: attach an existing process to the jail so that
        one can propagate the jail label to the process, as appropriate.
    
    It is unclear if this is preferred vs. having separate associate entry
    points for each type of object we might associate.  That would split
    these up like so:
    
     - prison_created -> prison_associate_vnode
     - prison_attached -> prison_associate_proc
    
    Some sample policy ideas that should be feasible to implement with this
    set of hooks, in case it's inspiring:
     - mac_bomb: policy that allows a poudriere user to construct jails
        without root privilege, given a restricted set of jail parameters.
        Slap a warning label on it.
     - mac_capsule: policy that realizes the capsule idea that I pitched[0]
        on -jail@ to create jails that are effectively immutable once
        sealed, using these hooks and a label.
    
    Perhaps a silly idea, but a downstream could consider a scenario where
    it can implement special jail enumeration using a MAC policy and a
    cooperating application that specifies non-parameter options to filter
    the results.
    
    [0] 
https://lists.freebsd.org/archives/freebsd-jail/2025-September/000550.html
    
    Reviewed by:    olce (slightly earlier version)
    Differential Revision:  https://reviews.freebsd.org/D53954
---
 share/man/man4/mac.4             |   2 +
 sys/kern/kern_jail.c             | 126 ++++++++++++++++++++++++------
 sys/security/mac/mac_framework.h |  12 +++
 sys/security/mac/mac_policy.h    |  25 ++++++
 sys/security/mac/mac_prison.c    |  87 +++++++++++++++++++++
 sys/security/mac_stub/mac_stub.c |  83 ++++++++++++++++++++
 sys/security/mac_test/mac_test.c | 161 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 474 insertions(+), 22 deletions(-)

diff --git a/share/man/man4/mac.4 b/share/man/man4/mac.4
index 134086139f53..2e2abbdb2c06 100644
--- a/share/man/man4/mac.4
+++ b/share/man/man4/mac.4
@@ -115,6 +115,8 @@ Policy enforcement is divided into the following areas of 
the system:
 .Bl -ohang
 .It Sy "File System"
 File system mounts, modifying directories, modifying files, etc.
+.It Sy Jails
+Creating, modifying, removing, and attaching to jails
 .It Sy KLD
 Loading, unloading, and retrieving statistics on loaded kernel modules
 .It Sy Network
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 8c224597bdf5..b5f61e3957d9 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -36,6 +36,7 @@
 
 #include <sys/param.h>
 #include <sys/types.h>
+#include <sys/ctype.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/errno.h>
@@ -1701,6 +1702,11 @@ kern_jail_set(struct thread *td, struct uio *optuio, int 
flags)
        /* If there's no prison to update, create a new one and link it in. */
        created = pr == NULL;
        if (created) {
+#ifdef MAC
+               error = mac_prison_check_create(td->td_ucred, opts, flags);
+               if (error != 0)
+                       goto done_deref;
+#endif
                for (tpr = mypr; tpr != NULL; tpr = tpr->pr_parent)
                        if (tpr->pr_childcount >= tpr->pr_childmax) {
                                error = EPERM;
@@ -1855,6 +1861,11 @@ kern_jail_set(struct thread *td, struct uio *optuio, int 
flags)
                        prison_hold(pr);
                        drflags |= PD_DEREF;
                }
+#ifdef MAC
+               error = mac_prison_check_set(td->td_ucred, pr, opts, flags);
+               if (error != 0)
+                       goto done_deref;
+#endif
 #if defined(VIMAGE) && (defined(INET) || defined(INET6))
                if ((pr->pr_flags & PR_VNET) &&
                    (ch_flags & (PR_IP4_USER | PR_IP6_USER))) {
@@ -2246,6 +2257,13 @@ kern_jail_set(struct thread *td, struct uio *optuio, int 
flags)
        if (created) {
                sx_assert(&allprison_lock, SX_XLOCKED);
                prison_knote(ppr, NOTE_JAIL_CHILD | pr->pr_id);
+#ifdef MAC
+               /*
+                * Note that mac_prison_created() assumes that it's called in a
+                * sleepable context.
+                */
+               mac_prison_created(td->td_ucred, pr);
+#endif
                mtx_lock(&pr->pr_mtx);
                drflags |= PD_LOCKED;
                pr->pr_state = PRISON_STATE_ALIVE;
@@ -2253,6 +2271,14 @@ kern_jail_set(struct thread *td, struct uio *optuio, int 
flags)
 
        /* Attach this process to the prison if requested. */
        if (flags & JAIL_ATTACH) {
+#ifdef MAC
+               error = mac_prison_check_attach(td->td_ucred, pr);
+               if (error != 0) {
+                       vfs_opterror(opts,
+                           "attach operation denied by MAC policy");
+                       goto done_deref;
+               }
+#endif
                error = do_jail_attach(td, pr,
                    prison_lock_xlock(pr, drflags & PD_LOCK_FLAGS));
                drflags &= ~(PD_LOCKED | PD_LIST_XLOCKED);
@@ -2556,12 +2582,6 @@ kern_jail_get(struct thread *td, struct uio *optuio, int 
flags)
                        drflags |= PD_DEREF;
                        mtx_lock(&pr->pr_mtx);
                        drflags |= PD_LOCKED;
-                       if (!(prison_isalive(pr) || (flags & JAIL_DYING))) {
-                               error = ENOENT;
-                               vfs_opterror(opts, "jail %d is dying",
-                                   pr->pr_id);
-                               goto done;
-                       }
                        goto found_prison;
                }
                if (flags & JAIL_AT_DESC) {
@@ -2593,7 +2613,29 @@ kern_jail_get(struct thread *td, struct uio *optuio, int 
flags)
                            prison_ischild(mypr, pr)) {
                                mtx_lock(&pr->pr_mtx);
                                drflags |= PD_LOCKED;
+#ifdef MAC
+                               /*
+                                * We special-case this one check because we
+                                * don't want MAC to break jail enumeration.  We
+                                * need to just move on to the next accessible
+                                * and alive prison.
+                                */
+                               error = mac_prison_check_get(td->td_ucred, pr,
+                                   opts, flags);
+                               if (error != 0) {
+                                       mtx_unlock(&pr->pr_mtx);
+                                       drflags &= ~PD_LOCKED;
+                                       continue;
+                               }
+
+                               /*
+                                * Avoid potentially expensive trip back into
+                                * the MAC framework.
+                                */
+                               goto found_prison_nomac_alive;
+#else
                                goto found_prison;
+#endif
                        }
                }
                error = ENOENT;
@@ -2608,13 +2650,6 @@ kern_jail_get(struct thread *td, struct uio *optuio, int 
flags)
                        pr = prison_find_child(mypr, jid);
                        if (pr != NULL) {
                                drflags |= PD_LOCKED;
-                               if (!(prison_isalive(pr) ||
-                                   (flags & JAIL_DYING))) {
-                                       error = ENOENT;
-                                       vfs_opterror(opts, "jail %d is dying",
-                                           jid);
-                                       goto done;
-                               }
                                goto found_prison;
                        }
                        error = ENOENT;
@@ -2633,12 +2668,6 @@ kern_jail_get(struct thread *td, struct uio *optuio, int 
flags)
                pr = prison_find_name(mypr, name);
                if (pr != NULL) {
                        drflags |= PD_LOCKED;
-                       if (!(prison_isalive(pr) || (flags & JAIL_DYING))) {
-                               error = ENOENT;
-                               vfs_opterror(opts, "jail \"%s\" is dying",
-                                   name);
-                               goto done;
-                       }
                        goto found_prison;
                }
                error = ENOENT;
@@ -2652,6 +2681,25 @@ kern_jail_get(struct thread *td, struct uio *optuio, int 
flags)
        goto done;
 
  found_prison:
+#ifdef MAC
+       error = mac_prison_check_get(td->td_ucred, pr, opts, flags);
+       if (error != 0)
+               goto done;
+#endif
+       if (!(prison_isalive(pr) || (flags & JAIL_DYING))) {
+               error = ENOENT;
+               if (pr->pr_name[0] != '0' && isdigit(pr->pr_name[0])) {
+                       vfs_opterror(opts, "jail %d is dying",
+                           pr->pr_id);
+               } else {
+                       vfs_opterror(opts, "jail \"%s\" (%d) is dying",
+                           pr->pr_name, pr->pr_id);
+               }
+               goto done;
+       }
+#ifdef MAC
+ found_prison_nomac_alive:
+#endif
        /* Get the parameters of the prison. */
        if (!(drflags & PD_DEREF)) {
                prison_hold(pr);
@@ -2891,6 +2939,14 @@ sys_jail_remove(struct thread *td, struct 
jail_remove_args *uap)
                sx_xunlock(&allprison_lock);
                return (EINVAL);
        }
+#ifdef MAC
+       error = mac_prison_check_remove(td->td_ucred, pr);
+       if (error != 0) {
+               mtx_unlock(&pr->pr_mtx);
+               sx_xunlock(&allprison_lock);
+               return (error);
+       }
+#endif
        prison_hold(pr);
        prison_remove(pr);
        return (0);
@@ -2913,6 +2969,10 @@ sys_jail_remove_jd(struct thread *td, struct 
jail_remove_jd_args *uap)
                return (error);
        error = priv_check_cred(jdcred, PRIV_JAIL_REMOVE);
        crfree(jdcred);
+#ifdef MAC
+       if (error == 0)
+               error = mac_prison_check_remove(td->td_ucred, pr);
+#endif
        if (error) {
                prison_free(pr);
                return (error);
@@ -2957,14 +3017,25 @@ sys_jail_attach(struct thread *td, struct 
jail_attach_args *uap)
                return (EINVAL);
        }
 
+#ifdef MAC
+       error = mac_prison_check_attach(td->td_ucred, pr);
+       if (error != 0)
+               goto unlock;
+#endif
+
        /* Do not allow a process to attach to a prison that is not alive. */
        if (!prison_isalive(pr)) {
-               mtx_unlock(&pr->pr_mtx);
-               sx_sunlock(&allprison_lock);
-               return (EINVAL);
+               error = EINVAL;
+               goto unlock;
        }
 
        return (do_jail_attach(td, pr, PD_LOCKED | PD_LIST_SLOCKED));
+
+unlock:
+
+       mtx_unlock(&pr->pr_mtx);
+       sx_sunlock(&allprison_lock);
+       return (error);
 }
 
 /*
@@ -2986,6 +3057,10 @@ sys_jail_attach_jd(struct thread *td, struct 
jail_attach_jd_args *uap)
                goto fail;
        drflags |= PD_DEREF;
        error = priv_check_cred(jdcred, PRIV_JAIL_ATTACH);
+#ifdef MAC
+       if (error == 0)
+               error = mac_prison_check_attach(td->td_ucred, pr);
+#endif
        crfree(jdcred);
        if (error)
                goto fail;
@@ -3086,6 +3161,13 @@ do_jail_attach(struct thread *td, struct prison *pr, int 
drflags)
        prison_deref(oldcred->cr_prison, drflags);
        crfree(oldcred);
        prison_knote(pr, NOTE_JAIL_ATTACH | td->td_proc->p_pid);
+#ifdef MAC
+       /*
+        * Note that mac_prison_attached() assumes that it's called in a
+        * sleepable context.
+        */
+       mac_prison_attached(td->td_ucred, pr, td->td_proc);
+#endif
 
        /*
         * If the prison was killed while changing credentials, die along
diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h
index f14e8d7d1e7d..5e13434e5ecc 100644
--- a/sys/security/mac/mac_framework.h
+++ b/sys/security/mac/mac_framework.h
@@ -86,6 +86,7 @@ struct thread;
 struct timespec;
 struct ucred;
 struct vattr;
+struct vfsoptlist;
 struct vnode;
 struct vop_setlabel_args;
 
@@ -351,6 +352,17 @@ 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_prison_check_attach(struct ucred *cred, struct prison *pr);
+int    mac_prison_check_create(struct ucred *cred, struct vfsoptlist *opts,
+           int flags);
+int    mac_prison_check_get(struct ucred *cred, struct prison *pr,
+           struct vfsoptlist *opts, int flags);
+int    mac_prison_check_set(struct ucred *cred, struct prison *pr,
+           struct vfsoptlist *opts, int flags);
+int    mac_prison_check_remove(struct ucred *cred, struct prison *pr);
+void   mac_prison_created(struct ucred *cred, struct prison *pr);
+void   mac_prison_attached(struct ucred *cred, struct prison *pr,
+           struct proc *p);
 
 int    mac_priv_check_impl(struct ucred *cred, int priv);
 #ifdef MAC
diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h
index fba1f4a1c85e..7693eb309534 100644
--- a/sys/security/mac/mac_policy.h
+++ b/sys/security/mac/mac_policy.h
@@ -101,6 +101,7 @@ struct sysctl_req;
 struct thread;
 struct ucred;
 struct vattr;
+struct vfsoptlist;
 struct vnode;
 
 struct in_addr;
@@ -419,6 +420,23 @@ 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_prison_check_attach_t)(struct ucred *cred,
+                   struct prison *pr, struct label *prlabel);
+typedef int    (*mpo_prison_check_create_t)(struct ucred *cred,
+                   struct vfsoptlist *opts, int flags);
+typedef int    (*mpo_prison_check_get_t)(struct ucred *cred,
+                   struct prison *pr, struct label *prlabel,
+                   struct vfsoptlist *opts, int flags);
+typedef int    (*mpo_prison_check_set_t)(struct ucred *cred,
+                   struct prison *pr, struct label *prlabel,
+                   struct vfsoptlist *opts, int flags);
+typedef int    (*mpo_prison_check_remove_t)(struct ucred *cred,
+                   struct prison *pr, struct label *prlabel);
+typedef void   (*mpo_prison_created_t)(struct ucred *cred,
+                   struct prison *pr, struct label *prlabel);
+typedef void   (*mpo_prison_attached_t)(struct ucred *cred,
+                   struct prison *pr, struct label *prlabel, struct proc *p,
+                   struct label *proclabel);
 
 typedef int    (*mpo_priv_check_t)(struct ucred *cred, int priv);
 typedef int    (*mpo_priv_grant_t)(struct ucred *cred, int priv);
@@ -882,6 +900,13 @@ struct mac_policy_ops {
        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_prison_check_attach_t               mpo_prison_check_attach;
+       mpo_prison_check_create_t               mpo_prison_check_create;
+       mpo_prison_check_get_t                  mpo_prison_check_get;
+       mpo_prison_check_set_t                  mpo_prison_check_set;
+       mpo_prison_check_remove_t               mpo_prison_check_remove;
+       mpo_prison_created_t                    mpo_prison_created;
+       mpo_prison_attached_t                   mpo_prison_attached;
 
        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
index e24ffa9e698d..3f787c6b3647 100644
--- a/sys/security/mac/mac_prison.c
+++ b/sys/security/mac/mac_prison.c
@@ -142,3 +142,90 @@ mac_prison_check_relabel(struct ucred *cred, struct prison 
*pr,
 
        return (error);
 }
+
+MAC_CHECK_PROBE_DEFINE3(prison_check_attach, "struct ucred *",
+    "struct prison *", "struct label *");
+int
+mac_prison_check_attach(struct ucred *cred, struct prison *pr)
+{
+       int error;
+
+       MAC_POLICY_CHECK_NOSLEEP(prison_check_attach, cred, pr, pr->pr_label);
+       MAC_CHECK_PROBE3(prison_check_attach, error, cred, pr, pr->pr_label);
+
+       return (error);
+}
+
+MAC_CHECK_PROBE_DEFINE3(prison_check_create, "struct ucred *",
+    "struct vfsoptlist *", "int");
+int
+mac_prison_check_create(struct ucred *cred, struct vfsoptlist *opts,
+    int flags)
+{
+       int error;
+
+       MAC_POLICY_CHECK_NOSLEEP(prison_check_create, cred, opts, flags);
+       MAC_CHECK_PROBE3(prison_check_create, error, cred, opts, flags);
+
+       return (error);
+}
+
+MAC_CHECK_PROBE_DEFINE5(prison_check_get, "struct ucred *",
+    "struct prison *", "struct label *", "struct vfsoptlist *", "int");
+int
+mac_prison_check_get(struct ucred *cred, struct prison *pr,
+    struct vfsoptlist *opts, int flags)
+{
+       int error;
+
+       MAC_POLICY_CHECK_NOSLEEP(prison_check_get, cred, pr, pr->pr_label,
+           opts, flags);
+       MAC_CHECK_PROBE5(prison_check_get, error, cred, pr, pr->pr_label, opts,
+           flags);
+
+       return (error);
+}
+
+MAC_CHECK_PROBE_DEFINE5(prison_check_set, "struct ucred *",
+    "struct prison *", "struct label *", "struct vfsoptlist *", "int");
+int
+mac_prison_check_set(struct ucred *cred, struct prison *pr,
+    struct vfsoptlist *opts, int flags)
+{
+       int error;
+
+       MAC_POLICY_CHECK_NOSLEEP(prison_check_set, cred, pr, pr->pr_label,
+           opts, flags);
+       MAC_CHECK_PROBE5(prison_check_set, error, cred, pr, pr->pr_label, opts,
+           flags);
+
+       return (error);
+}
+
+MAC_CHECK_PROBE_DEFINE3(prison_check_remove, "struct ucred *",
+    "struct prison *", "struct label *");
+int
+mac_prison_check_remove(struct ucred *cred, struct prison *pr)
+{
+       int error;
+
+       MAC_POLICY_CHECK_NOSLEEP(prison_check_remove, cred, pr, pr->pr_label);
+       MAC_CHECK_PROBE3(prison_check_remove, error, cred, pr, pr->pr_label);
+
+       return (error);
+}
+
+void
+mac_prison_created(struct ucred *cred, struct prison *pr)
+{
+
+       MAC_POLICY_PERFORM(prison_created, cred, pr, pr->pr_label);
+}
+
+void
+mac_prison_attached(struct ucred *cred, struct prison *pr, struct proc *p)
+{
+
+       MAC_POLICY_PERFORM(prison_attached, cred, pr, pr->pr_label, p,
+           p->p_label);
+}
diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c
index ac5d5b58e5db..20b04d4acf58 100644
--- a/sys/security/mac_stub/mac_stub.c
+++ b/sys/security/mac_stub/mac_stub.c
@@ -52,6 +52,7 @@
 #include <sys/acl.h>
 #include <sys/conf.h>
 #include <sys/extattr.h>
+#include <sys/jail.h>
 #include <sys/kdb.h>
 #include <sys/kernel.h>
 #include <sys/ksem.h>
@@ -852,6 +853,74 @@ stub_posixshm_create(struct ucred *cred, struct shmfd 
*shmfd,
 
 }
 
+static void
+stub_prison_relabel(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct label *newlabel)
+{
+
+}
+
+static int
+stub_prison_check_relabel(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct label *newlabel)
+{
+
+       return (0);
+}
+
+static int
+stub_prison_check_attach(struct ucred *cred, struct prison *pr,
+    struct label *prlabel)
+{
+
+       return (0);
+}
+
+static int
+stub_prison_check_create(struct ucred *cred, struct vfsoptlist *opts, int 
flags)
+{
+
+       return (0);
+}
+
+static int
+stub_prison_check_get(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct vfsoptlist *opts, int flags)
+{
+
+       return (0);
+}
+
+static int
+stub_prison_check_set(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct vfsoptlist *opts, int flags)
+{
+
+       return (0);
+}
+
+static int
+stub_prison_check_remove(struct ucred *cred, struct prison *pr,
+    struct label *prlabel)
+{
+
+       return (0);
+}
+
+static void
+stub_prison_created(struct ucred *cred, struct prison *pr,
+    struct label *prlabel)
+{
+
+}
+
+static void
+stub_prison_attached(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct proc *p, struct label *proclabel)
+{
+
+}
+
 static int
 stub_priv_check(struct ucred *cred, int priv)
 {
@@ -1841,6 +1910,20 @@ static struct mac_policy_ops stub_ops =
        .mpo_posixshm_destroy_label = stub_destroy_label,
        .mpo_posixshm_init_label = stub_init_label,
 
+       .mpo_prison_init_label = stub_init_label_waitcheck,
+       .mpo_prison_destroy_label = stub_destroy_label,
+       .mpo_prison_externalize_label = stub_externalize_label,
+       .mpo_prison_internalize_label = stub_internalize_label,
+       .mpo_prison_relabel = stub_prison_relabel,
+       .mpo_prison_check_relabel = stub_prison_check_relabel,
+       .mpo_prison_check_attach = stub_prison_check_attach,
+       .mpo_prison_check_create = stub_prison_check_create,
+       .mpo_prison_check_get = stub_prison_check_get,
+       .mpo_prison_check_set = stub_prison_check_set,
+       .mpo_prison_check_remove = stub_prison_check_remove,
+       .mpo_prison_created = stub_prison_created,
+       .mpo_prison_attached = stub_prison_attached,
+
        .mpo_priv_check = stub_priv_check,
        .mpo_priv_grant = stub_priv_grant,
 
diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c
index c447eeef010d..72af48edb00f 100644
--- a/sys/security/mac_test/mac_test.c
+++ b/sys/security/mac_test/mac_test.c
@@ -51,6 +51,7 @@
 
 #include <sys/param.h>
 #include <sys/acl.h>
+#include <sys/jail.h>
 #include <sys/kdb.h>
 #include <sys/kernel.h>
 #include <sys/ksem.h>
@@ -99,6 +100,7 @@ static SYSCTL_NODE(_security_mac, OID_AUTO, test,
 #define        MAGIC_PIPE      0xdc6c9919
 #define        MAGIC_POSIX_SEM 0x78ae980c
 #define        MAGIC_POSIX_SHM 0x4e853fc9
+#define        MAGIC_PRISON    0x9639acdb
 #define        MAGIC_PROC      0x3b4be98f
 #define        MAGIC_CRED      0x9a5a4987
 #define        MAGIC_VNODE     0x1a67a45c
@@ -1591,6 +1593,151 @@ test_posixshm_init_label(struct label *label)
        COUNTER_INC(posixshm_init_label);
 }
 
+COUNTER_DECL(prison_init_label);
+static int
+test_prison_init_label(struct label *label, int flag)
+{
+
+       if (flag & M_WAITOK)
+               WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
+                   "test_prison_init_label() at %s:%d", __FILE__,
+                   __LINE__);
+
+       LABEL_INIT(label, MAGIC_PRISON);
+       COUNTER_INC(prison_init_label);
+       return (0);
+}
+
+COUNTER_DECL(prison_destroy_label);
+static void
+test_prison_destroy_label(struct label *label)
+{
+
+       LABEL_DESTROY(label, MAGIC_PRISON);
+       COUNTER_INC(prison_destroy_label);
+}
+
+COUNTER_DECL(prison_externalize_label);
+static int
+test_prison_externalize_label(struct label *label, char *element_name,
+    struct sbuf *sb, int *claimed)
+{
+
+       LABEL_CHECK(label, MAGIC_PRISON);
+       COUNTER_INC(prison_externalize_label);
+
+       return (0);
+}
+
+COUNTER_DECL(prison_internalize_label);
+static int
+test_prison_internalize_label(struct label *label, char *element_name,
+    char *element_data, int *claimed)
+{
+
+       LABEL_CHECK(label, MAGIC_PRISON);
+       COUNTER_INC(prison_internalize_label);
+
+       return (0);
+}
+
+COUNTER_DECL(prison_relabel);
+static void
+test_prison_relabel(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct label *newlabel)
+{
+
+       LABEL_CHECK(prlabel, MAGIC_PRISON);
+       LABEL_CHECK(newlabel, MAGIC_PRISON);
+       COUNTER_INC(prison_relabel);
+}
+
+COUNTER_DECL(prison_check_relabel);
+static int
+test_prison_check_relabel(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct label *newlabel)
+{
+
+       LABEL_CHECK(prlabel, MAGIC_PRISON);
+       LABEL_CHECK(newlabel, MAGIC_PRISON);
+       COUNTER_INC(prison_check_relabel);
+       return (0);
+}
+
+COUNTER_DECL(prison_check_attach);
+static int
+test_prison_check_attach(struct ucred *cred, struct prison *pr,
+    struct label *prlabel)
+{
+
+       LABEL_CHECK(prlabel, MAGIC_PRISON);
+       COUNTER_INC(prison_check_attach);
+       return (0);
+}
+
+COUNTER_DECL(prison_check_create);
+static int
+test_prison_check_create(struct ucred *cred, struct vfsoptlist *opts, int 
flags)
+{
+
+       COUNTER_INC(prison_check_create);
+       return (0);
+}
+
+COUNTER_DECL(prison_check_get);
+static int
+test_prison_check_get(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct vfsoptlist *opts, int flags)
+{
+
+       LABEL_CHECK(prlabel, MAGIC_PRISON);
+       COUNTER_INC(prison_check_get);
+       return (0);
+}
+
+COUNTER_DECL(prison_check_set);
+static int
+test_prison_check_set(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct vfsoptlist *opts, int flags)
+{
+
+       LABEL_CHECK(prlabel, MAGIC_PRISON);
+       COUNTER_INC(prison_check_set);
+       return (0);
+}
+
+COUNTER_DECL(prison_check_remove);
+static int
+test_prison_check_remove(struct ucred *cred, struct prison *pr,
+    struct label *prlabel)
+{
+
+       LABEL_CHECK(prlabel, MAGIC_PRISON);
+       COUNTER_INC(prison_check_remove);
+       return (0);
+}
+
+COUNTER_DECL(prison_created);
+static void
+test_prison_created(struct ucred *cred, struct prison *pr,
+    struct label *prlabel)
+{
+
+       LABEL_CHECK(prlabel, MAGIC_PRISON);
+       COUNTER_INC(prison_created);
+}
+
+COUNTER_DECL(prison_attached);
+static void
+test_prison_attached(struct ucred *cred, struct prison *pr,
+    struct label *prlabel, struct proc *p, struct label *proclabel)
+{
+
+       LABEL_CHECK(prlabel, MAGIC_PRISON);
+       LABEL_CHECK(proclabel, MAGIC_PROC);
+       COUNTER_INC(prison_attached);
+}
+
 COUNTER_DECL(proc_check_debug);
 static int
 test_proc_check_debug(struct ucred *cred, struct proc *p)
@@ -3208,6 +3355,20 @@ static struct mac_policy_ops test_ops =
        .mpo_posixshm_destroy_label = test_posixshm_destroy_label,
        .mpo_posixshm_init_label = test_posixshm_init_label,
 
+       .mpo_prison_init_label = test_prison_init_label,
+       .mpo_prison_destroy_label = test_prison_destroy_label,
+       .mpo_prison_externalize_label = test_prison_externalize_label,
+       .mpo_prison_internalize_label = test_prison_internalize_label,
+       .mpo_prison_relabel = test_prison_relabel,
+       .mpo_prison_check_relabel = test_prison_check_relabel,
+       .mpo_prison_check_attach = test_prison_check_attach,
+       .mpo_prison_check_create = test_prison_check_create,
+       .mpo_prison_check_get = test_prison_check_get,
+       .mpo_prison_check_set = test_prison_check_set,
+       .mpo_prison_check_remove = test_prison_check_remove,
+       .mpo_prison_created = test_prison_created,
+       .mpo_prison_attached = test_prison_attached,
+
        .mpo_proc_check_debug = test_proc_check_debug,
        .mpo_proc_check_sched = test_proc_check_sched,
        .mpo_proc_check_signal = test_proc_check_signal,

Reply via email to