jail - Rework sysctl configuration variables
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Wed, 21 Aug 2019 00:35:42 +0000 (02:35 +0200)
committerAntonio Huete Jimenez <tuxillo@quantumachine.net>
Wed, 28 Aug 2019 10:37:36 +0000 (12:37 +0200)
- Jail sysctls are now jail-specific so that different jails
  can have different settings.
  Each jail will have its own subtree which can be operated
  directly with sysctl(8).

  Naming convention:

      jail.<n>.<setting>

- All previous sysctls are now moved to 'jail.defaults' and they
  are used as a template for any newly created jail.

  Example:

  # jls
  JID     Hostname        Path            IPs
  2       t02.local       /jails/02       10.0.0.3
  1       t01.local       /jails/01       10.0.0.2

  # sysctl jail
  jail.jailed: 0
  jail.list: 2 t02.local /jails/02 10.0.0.3
  1 t01.local /jails/01 10.0.0.2
  jail.defaults.allow_raw_sockets: 0
  jail.defaults.chflags_allowed: 0
  jail.defaults.sysvipc_allowed: 0
  jail.defaults.socket_unixiproute_only: 1
  jail.defaults.set_hostname_allowed: 1
  jail.1.set_hostname_allowed: 1
  jail.1.socket_unixiproute_only: 1
  jail.1.sysvipc_allowed: 0
  jail.1.chflags_allowed: 0
  jail.1.allow_raw_sockets: 0
  jail.2.set_hostname_allowed: 1
  jail.2.socket_unixiproute_only: 1
  jail.2.sysvipc_allowed: 0
  jail.2.chflags_allowed: 0
  jail.2.allow_raw_sockets: 0

  # sysctl jail.2.allow_raw_sockets=1
  jail.2.allow_raw_sockets: 0 -> 1

  # jexec 2 ping -q -c 1 10.0.0.1
  PING 10.0.0.1 (10.0.0.1): 56 data bytes

  --- 10.0.0.1 ping statistics ---
  1 packets transmitted, 1 packets received, 0.0% packet loss
  round-trip min/avg/max/stddev = 0.766/0.766/0.766/0.000 ms

  # jexec 1 ping -q -c 1 10.0.0.1
  ping: socket: Operation not permitted

  # service jail stop
  Stopping jails: t01.local t02.local.

  # sysctl jail
  jail.jailed: 0
  jail.defaults.allow_raw_sockets: 0
  jail.defaults.chflags_allowed: 0
  jail.defaults.sysvipc_allowed: 0
  jail.defaults.socket_unixiproute_only: 1
  jail.defaults.set_hostname_allowed: 1

sys/kern/kern_jail.c
sys/kern/kern_mib.c
sys/kern/sysv_msg.c
sys/kern/sysv_sem.c
sys/kern/sysv_shm.c
sys/kern/uipc_socket.c
sys/kern/vfs_helper.c
sys/sys/jail.h

index 4363406..1473618 100644 (file)
@@ -54,7 +54,6 @@
 #include <sys/priv.h>
 #include <sys/jail.h>
 #include <sys/socket.h>
-#include <sys/sysctl.h>
 #include <sys/kern_syscall.h>
 #include <net/if.h>
 #include <netinet/in.h>
@@ -68,30 +67,33 @@ static void         prison_ipcache_init(struct prison *);
 MALLOC_DEFINE(M_PRISON, "prison", "Prison structures");
 
 SYSCTL_NODE(, OID_AUTO, jail, CTLFLAG_RW, 0,
-    "Jail rules");
+    "All jails settings");
+
+SYSCTL_NODE(_jail, OID_AUTO, defaults, CTLFLAG_RW, 0,
+    "Default options for jails");
 
 int    jail_set_hostname_allowed = 1;
-SYSCTL_INT(_jail, OID_AUTO, set_hostname_allowed, CTLFLAG_RW,
+SYSCTL_INT(_jail_defaults, OID_AUTO, set_hostname_allowed, CTLFLAG_RW,
     &jail_set_hostname_allowed, 0,
     "Processes in jail can set their hostnames");
 
 int    jail_socket_unixiproute_only = 1;
-SYSCTL_INT(_jail, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW,
+SYSCTL_INT(_jail_defaults, OID_AUTO, socket_unixiproute_only, CTLFLAG_RW,
     &jail_socket_unixiproute_only, 0,
     "Processes in jail are limited to creating UNIX/IPv[46]/route sockets only");
 
 int    jail_sysvipc_allowed = 0;
-SYSCTL_INT(_jail, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
+SYSCTL_INT(_jail_defaults, OID_AUTO, sysvipc_allowed, CTLFLAG_RW,
     &jail_sysvipc_allowed, 0,
     "Processes in jail can use System V IPC primitives");
 
 int    jail_chflags_allowed = 0;
-SYSCTL_INT(_jail, OID_AUTO, chflags_allowed, CTLFLAG_RW,
+SYSCTL_INT(_jail_defaults, OID_AUTO, chflags_allowed, CTLFLAG_RW,
     &jail_chflags_allowed, 0,
     "Processes in jail can alter system file flags");
 
 int    jail_allow_raw_sockets = 0;
-SYSCTL_INT(_jail, OID_AUTO, allow_raw_sockets, CTLFLAG_RW,
+SYSCTL_INT(_jail_defaults, OID_AUTO, allow_raw_sockets, CTLFLAG_RW,
     &jail_allow_raw_sockets, 0,
     "Process in jail can create raw sockets");
 
@@ -178,16 +180,28 @@ kern_jail(struct prison *pr, struct jail *j)
                nlookup_done(&nd);
                return (error);
        }
-               
+
        LIST_INSERT_HEAD(&allprison, pr, pr_list);
        ++prisoncount;
 
+       error = prison_sysctl_create(pr);
+       if (error)
+               goto out;
+
        error = kern_jail_attach(pr->pr_id);
-       if (error) {
-               LIST_REMOVE(pr, pr_list);
-               --prisoncount;
-               varsymset_clean(&pr->pr_varsymset);
-       }
+       if (error)
+               goto out2;
+
+       nlookup_done(&nd);
+       return 0;
+
+out2:
+       prison_sysctl_done(pr);
+
+out:
+       LIST_REMOVE(pr, pr_list);
+       --prisoncount;
+       varsymset_clean(&pr->pr_varsymset);
        nlookup_done(&nd);
        return (error);
 }
@@ -276,6 +290,13 @@ sys_jail(struct jail_args *uap)
        if (error)
                goto out;
 
+       /* Global settings are the default for all jails */
+       pr->pr_set_hostname_allowed = jail_set_hostname_allowed;
+       pr->pr_socket_unixiproute_only = jail_socket_unixiproute_only;
+       pr->pr_sysvipc_allowed = jail_sysvipc_allowed;
+       pr->pr_chflags_allowed = jail_chflags_allowed;
+       pr->pr_allow_raw_sockets = jail_allow_raw_sockets;
+
        error = kern_jail(pr, &j);
        if (error)
                goto out;
@@ -709,6 +730,10 @@ prison_free(struct prison *pr)
        if (pr->pr_linux != NULL)
                kfree(pr->pr_linux, M_PRISON);
        varsymset_clean(&pr->pr_varsymset);
+
+       /* Release the sysctl tree */
+       prison_sysctl_done(pr);
+
        cache_drop(&pr->pr_root);
        kfree(pr, M_PRISON);
 }
@@ -721,6 +746,8 @@ prison_free(struct prison *pr)
 int
 prison_priv_check(struct ucred *cred, int priv)
 {
+       struct prison *pr = cred->cr_prison;
+
        if (!jailed(cred))
                return (0);
 
@@ -784,7 +811,7 @@ prison_priv_check(struct ucred *cred, int priv)
                 * Conditionally allow creating raw sockets in jail.
                 */
        case PRIV_NETINET_RAW:
-               if (jail_allow_raw_sockets)
+               if (pr->pr_allow_raw_sockets)
                        return (0);
                else
                        return (EPERM);
@@ -797,3 +824,171 @@ prison_priv_check(struct ucred *cred, int priv)
                return (EPERM);
        }
 }
+
+static int
+sysctl_prison_switch_int8(SYSCTL_HANDLER_ARGS, int8_t *val)
+{
+       int new_val;
+       int error;
+
+       new_val = *val;
+
+       error = sysctl_handle_int(oidp, &new_val, 0, req);
+       if (error != 0 || req->newptr == NULL)
+               return error;
+
+       if (new_val != 0 && new_val != 1)
+               return EINVAL;
+
+       *val = new_val;
+
+       return error;
+
+}
+
+static int
+sysctl_prison_set_hostname_allowed(SYSCTL_HANDLER_ARGS)
+{
+       struct prison *pr;
+       int error;
+
+       if (arg1 == NULL)
+               return EINVAL;
+       pr = arg1;
+
+       error = sysctl_prison_switch_int8(oidp, arg1, arg2, req,
+           &pr->pr_set_hostname_allowed);
+
+       return error;
+}
+
+static int
+sysctl_prison_socket_unixiproute_only(SYSCTL_HANDLER_ARGS)
+{
+       struct prison *pr;
+       int error;
+
+       if (arg1 == NULL)
+               return EINVAL;
+       pr = arg1;
+
+       error = sysctl_prison_switch_int8(oidp, arg1, arg2, req,
+           &pr->pr_socket_unixiproute_only);
+
+       return error;
+}
+
+static int
+sysctl_prison_sysvipc_allowed(SYSCTL_HANDLER_ARGS)
+{
+       struct prison *pr;
+       int error;
+
+       if (arg1 == NULL)
+               return EINVAL;
+       pr = arg1;
+
+       error = sysctl_prison_switch_int8(oidp, arg1, arg2, req,
+           &pr->pr_sysvipc_allowed);
+
+       return error;
+}
+
+static int
+sysctl_prison_chflags_allowed(SYSCTL_HANDLER_ARGS)
+{
+       struct prison *pr;
+       int error;
+
+       if (arg1 == NULL)
+               return EINVAL;
+       pr = arg1;
+
+       error = sysctl_prison_switch_int8(oidp, arg1, arg2, req,
+           &pr->pr_chflags_allowed);
+
+       return error;
+}
+
+static int
+sysctl_prison_allow_raw_sockets(SYSCTL_HANDLER_ARGS)
+{
+       struct prison *pr;
+       int error;
+
+       if (arg1 == NULL)
+               return EINVAL;
+       pr = arg1;
+
+       error = sysctl_prison_switch_int8(oidp, arg1, arg2, req,
+           &pr->pr_allow_raw_sockets);
+
+       return error;
+}
+
+/*
+ * Create a per-jail sysctl tree to control the prison
+ */
+int
+prison_sysctl_create(struct prison *pr)
+{
+       char id_str[7];
+
+       ksnprintf(id_str, 6, "%d", pr->pr_id);
+
+       pr->pr_sysctl_ctx = (struct sysctl_ctx_list *) kmalloc(
+               sizeof(struct sysctl_ctx_list), M_TEMP, M_WAITOK | M_ZERO);
+
+       sysctl_ctx_init(pr->pr_sysctl_ctx);
+
+       /* Main jail node */
+       pr->pr_sysctl_tree = SYSCTL_ADD_NODE(pr->pr_sysctl_ctx,
+           SYSCTL_STATIC_CHILDREN(_jail),
+           OID_AUTO, id_str, CTLFLAG_RD, 0,
+           "Jail specific settings");
+
+       SYSCTL_ADD_PROC(pr->pr_sysctl_ctx,
+           SYSCTL_CHILDREN(pr->pr_sysctl_tree), OID_AUTO,
+           "set_hostname_allowed", CTLTYPE_INT | CTLFLAG_RW,
+           pr, sizeof(pr->pr_set_hostname_allowed),
+           sysctl_prison_set_hostname_allowed, "I",
+           "Processes in jail can set their hostnames");
+       SYSCTL_ADD_PROC(pr->pr_sysctl_ctx,
+           SYSCTL_CHILDREN(pr->pr_sysctl_tree), OID_AUTO,
+           "socket_unixiproute_only", CTLTYPE_INT | CTLFLAG_RW,
+           pr, sizeof(pr->pr_socket_unixiproute_only),
+           sysctl_prison_socket_unixiproute_only, "I",
+           "Processes in jail are limited to creating UNIX/IPv[46]/route sockets only");
+       SYSCTL_ADD_PROC(pr->pr_sysctl_ctx,
+           SYSCTL_CHILDREN(pr->pr_sysctl_tree), OID_AUTO,
+           "sysvipc_allowed", CTLTYPE_INT | CTLFLAG_RW,
+           pr, sizeof(pr->pr_sysvipc_allowed),
+           sysctl_prison_sysvipc_allowed, "I",
+           "Processes in jail can use System V IPC primitives");
+       SYSCTL_ADD_PROC(pr->pr_sysctl_ctx,
+           SYSCTL_CHILDREN(pr->pr_sysctl_tree), OID_AUTO,
+           "chflags_allowed", CTLTYPE_INT | CTLFLAG_RW,
+           pr, sizeof(pr->pr_chflags_allowed),
+           sysctl_prison_chflags_allowed, "I",
+           "Processes in jail can alter system file flags");
+       SYSCTL_ADD_PROC(pr->pr_sysctl_ctx,
+           SYSCTL_CHILDREN(pr->pr_sysctl_tree), OID_AUTO,
+           "allow_raw_sockets", CTLTYPE_INT | CTLFLAG_RW,
+           pr, sizeof(pr->pr_allow_raw_sockets),
+           sysctl_prison_allow_raw_sockets, "I",
+           "Process in jail can create raw sockets");
+
+       return 0;
+}
+
+int
+prison_sysctl_done(struct prison *pr)
+{
+       if (pr->pr_sysctl_tree) {
+               sysctl_ctx_free(pr->pr_sysctl_ctx);
+               kfree(pr->pr_sysctl_ctx, M_TEMP);
+               pr->pr_sysctl_tree = NULL;
+       }
+
+       return 0;
+}
index 39bae52..d487bd0 100644 (file)
@@ -162,14 +162,17 @@ sysctl_hostname(SYSCTL_HANDLER_ARGS)
 {
        struct thread *td = req->td;
        struct proc *p = td ? td->td_proc : NULL;
+       struct prison *pr;
        int error;
 
        if (req->newptr) {
                SYSCTL_SUNLOCK();
                SYSCTL_XLOCK();
        }
-       if (p && p->p_ucred->cr_prison) {
-               if (!jail_set_hostname_allowed && req->newptr)
+       if (p)
+               pr = p->p_ucred->cr_prison;
+       if (p && pr) {
+               if (!pr->pr_set_hostname_allowed && req->newptr)
                        return(EPERM);
                error = sysctl_handle_string(oidp, 
                    p->p_ucred->cr_prison->pr_host,
index afe4787..58bf570 100644 (file)
@@ -204,6 +204,7 @@ sys_msgctl(struct msgctl_args *uap)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
+       struct prison *pr = p->p_ucred->cr_prison;
        int msqid = uap->msqid;
        int cmd = uap->cmd;
        struct msqid_ds *user_msqptr = uap->buf;
@@ -215,7 +216,7 @@ sys_msgctl(struct msgctl_args *uap)
        kprintf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr);
 #endif
 
-       if (!jail_sysvipc_allowed && td->td_ucred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        lwkt_gettoken(&msg_token);
@@ -344,6 +345,7 @@ int
 sys_msgget(struct msgget_args *uap)
 {
        struct thread *td = curthread;
+       struct prison *pr = td->td_proc->p_ucred->cr_prison;
        int msqid, eval;
        int key = uap->key;
        int msgflg = uap->msgflg;
@@ -353,7 +355,7 @@ sys_msgget(struct msgget_args *uap)
 #ifdef MSG_DEBUG_OK
        kprintf("msgget(0x%x, 0%o)\n", key, msgflg);
 #endif
-       if (!jail_sysvipc_allowed && cred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        eval = 0;
@@ -454,6 +456,7 @@ int
 sys_msgsnd(struct msgsnd_args *uap)
 {
        struct thread *td = curthread;
+       struct prison *pr = td->td_proc->p_ucred->cr_prison;
        int msqid = uap->msqid;
        const void *user_msgp = uap->msgp;
        size_t msgsz = uap->msgsz;
@@ -468,7 +471,7 @@ sys_msgsnd(struct msgsnd_args *uap)
            msgflg);
 #endif
 
-       if (!jail_sysvipc_allowed && td->td_ucred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        lwkt_gettoken(&msg_token);
@@ -785,6 +788,7 @@ int
 sys_msgrcv(struct msgrcv_args *uap)
 {
        struct thread *td = curthread;
+       struct prison *pr = td->td_proc->p_ucred->cr_prison;
        int msqid = uap->msqid;
        void *user_msgp = uap->msgp;
        size_t msgsz = uap->msgsz;
@@ -801,7 +805,7 @@ sys_msgrcv(struct msgrcv_args *uap)
            msgsz, msgtyp, msgflg);
 #endif
 
-       if (!jail_sysvipc_allowed && td->td_ucred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        lwkt_gettoken(&msg_token);
index 6257fd6..5891b4d 100644 (file)
@@ -340,6 +340,7 @@ int
 sys___semctl(struct __semctl_args *uap)
 {
        struct thread *td = curthread;
+       struct prison *pr = td->td_proc->p_ucred->cr_prison;
        int semid = uap->semid;
        int semnum = uap->semnum;
        int cmd = uap->cmd;
@@ -355,7 +356,7 @@ sys___semctl(struct __semctl_args *uap)
        kprintf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg);
 #endif
 
-       if (!jail_sysvipc_allowed && cred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        semid = IPCID_TO_IX(semid);
@@ -566,6 +567,7 @@ int
 sys_semget(struct semget_args *uap)
 {
        struct thread *td = curthread;
+       struct prison *pr = td->td_proc->p_ucred->cr_prison;
        int semid, eval;
        int key = uap->key;
        int nsems = uap->nsems;
@@ -576,7 +578,7 @@ sys_semget(struct semget_args *uap)
        kprintf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg);
 #endif
 
-       if (!jail_sysvipc_allowed && cred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        eval = 0;
@@ -719,6 +721,7 @@ int
 sys_semop(struct semop_args *uap)
 {
        struct thread *td = curthread;
+       struct prison *pr = td->td_proc->p_ucred->cr_prison;
        int semid = uap->semid;
        u_int nsops = uap->nsops;
        struct sembuf sops[MAX_SOPS];
@@ -732,7 +735,7 @@ sys_semop(struct semop_args *uap)
 #ifdef SEM_DEBUG
        kprintf("call to semop(%d, 0x%x, %u)\n", semid, sops, nsops);
 #endif
-       if (!jail_sysvipc_allowed && td->td_ucred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        semid = IPCID_TO_IX(semid);     /* Convert back to zero origin */
index 0acf2ab..52a3614 100644 (file)
@@ -224,10 +224,12 @@ sys_shmdt(struct shmdt_args *uap)
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
        struct shmmap_state *shmmap_s;
+       struct prison *pr = p->p_ucred->cr_prison;
+
        long i;
        int error;
 
-       if (!jail_sysvipc_allowed && td->td_ucred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        lwkt_gettoken(&shm_token);
@@ -259,6 +261,7 @@ sys_shmat(struct shmat_args *uap)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
+       struct prison *pr = p->p_ucred->cr_prison;
        int error, flags;
        long i;
        struct shmid_ds *shmseg;
@@ -270,7 +273,7 @@ sys_shmat(struct shmat_args *uap)
        vm_size_t align;
        int rv;
 
-       if (!jail_sysvipc_allowed && td->td_ucred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        lwkt_gettoken(&shm_token);
@@ -397,11 +400,12 @@ sys_shmctl(struct shmctl_args *uap)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
+       struct prison *pr = p->p_ucred->cr_prison;
        int error;
        struct shmid_ds inbuf;
        struct shmid_ds *shmseg;
 
-       if (!jail_sysvipc_allowed && td->td_ucred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        lwkt_gettoken(&shm_token);
@@ -604,9 +608,10 @@ sys_shmget(struct shmget_args *uap)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
+       struct prison *pr = p->p_ucred->cr_prison;
        int segnum, mode, error;
 
-       if (!jail_sysvipc_allowed && td->td_ucred->cr_prison != NULL)
+       if (pr && !pr->pr_sysvipc_allowed)
                return (ENOSYS);
 
        mode = uap->shmflg & ACCESSPERMS;
index 765ca5d..d5e53ae 100644 (file)
@@ -206,6 +206,7 @@ socreate(int dom, struct socket **aso, int type,
        struct protosw *prp;
        struct socket *so;
        struct pru_attach_info ai;
+       struct prison *pr = p->p_ucred->cr_prison;
        int error;
 
        if (proto)
@@ -216,7 +217,7 @@ socreate(int dom, struct socket **aso, int type,
        if (prp == NULL || prp->pr_usrreqs->pru_attach == 0)
                return (EPROTONOSUPPORT);
 
-       if (p->p_ucred->cr_prison && jail_socket_unixiproute_only &&
+       if (pr && pr->pr_socket_unixiproute_only &&
            prp->pr_domain->dom_family != PF_LOCAL &&
            prp->pr_domain->dom_family != PF_INET &&
            prp->pr_domain->dom_family != PF_INET6 &&
index d582e04..f56d36f 100644 (file)
@@ -182,7 +182,7 @@ vop_helper_setattr_flags(u_int32_t *ino_flags, u_int32_t vaflags,
                return(error);
        }
        if (cred->cr_uid == 0 &&
-           (!jailed(cred)|| jail_chflags_allowed)) {
+           (!jailed(cred) || cred->cr_prison->pr_chflags_allowed)) {
                if ((*ino_flags & (SF_NOUNLINK|SF_IMMUTABLE|SF_APPEND)) &&
                    securelevel > 0)
                        return (EPERM);
index d81b1e1..d6cb217 100644 (file)
 #ifndef _NET_IF_H_
 #include <net/if.h>
 #endif
+#ifndef _SYS_SYSCTL_H_
+#include <sys/sysctl.h>
+#endif
+
 
 struct jail {
        uint32_t        version;
@@ -96,6 +100,15 @@ struct prison {
        void            *pr_linux;                      /* Linux ABI emulation */
        int              pr_securelevel;                /* jail securelevel */
        struct varsymset pr_varsymset;                  /* jail varsyms */
+
+       struct sysctl_ctx_list *pr_sysctl_ctx;
+       struct sysctl_oid *pr_sysctl_tree;
+
+       int8_t          pr_set_hostname_allowed;
+       int8_t          pr_socket_unixiproute_only;
+       int8_t          pr_sysvipc_allowed;
+       int8_t          pr_chflags_allowed;
+       int8_t          pr_allow_raw_sockets;
 };
 
 /*
@@ -121,6 +134,8 @@ struct sockaddr *
 int    prison_priv_check(struct ucred *cred, int priv);
 int    prison_remote_ip(struct thread *td, struct sockaddr *ip);
 int    prison_replace_wildcards(struct thread *td, struct sockaddr *ip);
+int    prison_sysctl_create(struct prison *);
+int    prison_sysctl_done(struct prison *);
 
 /*
  * Return 1 if the passed credential is in a jail, otherwise 0.