svn commit: r333263 - in head: lib/libjail sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/compat/linprocfs sys/compat/linsysfs sys/fs/devfs sys/fs/fdescfs sys/fs/nullfs sys/fs/procfs sys/fs/pse...

Jamie Gritton jamie at FreeBSD.org
Fri May 4 20:54:30 UTC 2018


Author: jamie
Date: Fri May  4 20:54:27 2018
New Revision: 333263
URL: https://svnweb.freebsd.org/changeset/base/333263

Log:
  Make it easier for filesystems to count themselves as jail-enabled,
  by doing most of the work in a new function prison_add_vfs in kern_jail.c
  Now a jail-enabled filesystem need only mark itself with VFCF_JAIL, and
  the rest is taken care of.  This includes adding a jail parameter like
  allow.mount.foofs, and a sysctl like security.jail.mount_foofs_allowed.
  Both of these used to be a static list of known filesystems, with
  predefined permission bits.
  
  Reviewed by:	kib
  Differential Revision:	D14681

Modified:
  head/lib/libjail/jail.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  head/sys/compat/linprocfs/linprocfs.c
  head/sys/compat/linsysfs/linsysfs.c
  head/sys/fs/devfs/devfs_vfsops.c
  head/sys/fs/fdescfs/fdesc_vfsops.c
  head/sys/fs/nullfs/null_vfsops.c
  head/sys/fs/procfs/procfs.c
  head/sys/fs/pseudofs/pseudofs.h
  head/sys/fs/tmpfs/tmpfs_vfsops.c
  head/sys/kern/kern_jail.c
  head/sys/kern/vfs_init.c
  head/sys/kern/vfs_mount.c
  head/sys/kern/vfs_subr.c
  head/sys/sys/jail.h
  head/sys/sys/mount.h
  head/usr.sbin/jail/jail.8

Modified: head/lib/libjail/jail.c
==============================================================================
--- head/lib/libjail/jail.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/lib/libjail/jail.c	Fri May  4 20:54:27 2018	(r333263)
@@ -1048,7 +1048,13 @@ kldload_param(const char *name)
 	else if (strcmp(name, "sysvmsg") == 0 || strcmp(name, "sysvsem") == 0 ||
 	    strcmp(name, "sysvshm") == 0)
 		kl = kldload(name);
-	else {
+	else if (strncmp(name, "allow.mount.", 12) == 0) {
+		/* Load the matching filesystem */
+		kl = kldload(name + 12);
+		if (kl < 0 && errno == ENOENT &&
+		    strncmp(name + 12, "no", 2) == 0)
+			kl = kldload(name + 14);
+	} else {
 		errno = ENOENT;
 		return (-1);
 	}

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Fri May  4 20:54:27 2018	(r333263)
@@ -1640,9 +1640,6 @@ zfs_mount(vfs_t *vfsp)
 
 	osname = spn.pn_path;
 #else	/* !illumos */
-	if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_ZFS))
-		return (SET_ERROR(EPERM));
-
 	if (vfs_getopt(vfsp->mnt_optnew, "from", (void **)&osname, NULL))
 		return (SET_ERROR(EINVAL));
 

Modified: head/sys/compat/linprocfs/linprocfs.c
==============================================================================
--- head/sys/compat/linprocfs/linprocfs.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/compat/linprocfs/linprocfs.c	Fri May  4 20:54:27 2018	(r333263)
@@ -1652,7 +1652,7 @@ linprocfs_uninit(PFS_INIT_ARGS)
 	return (0);
 }
 
-PSEUDOFS(linprocfs, 1, PR_ALLOW_MOUNT_LINPROCFS);
+PSEUDOFS(linprocfs, 1, VFCF_JAIL);
 #if defined(__amd64__)
 MODULE_DEPEND(linprocfs, linux_common, 1, 1, 1);
 #else

Modified: head/sys/compat/linsysfs/linsysfs.c
==============================================================================
--- head/sys/compat/linsysfs/linsysfs.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/compat/linsysfs/linsysfs.c	Fri May  4 20:54:27 2018	(r333263)
@@ -556,7 +556,7 @@ linsysfs_uninit(PFS_INIT_ARGS)
 	return (0);
 }
 
-PSEUDOFS(linsysfs, 1, PR_ALLOW_MOUNT_LINSYSFS);
+PSEUDOFS(linsysfs, 1, VFCF_JAIL);
 #if defined(__amd64__)
 MODULE_DEPEND(linsysfs, linux_common, 1, 1, 1);
 #else

Modified: head/sys/fs/devfs/devfs_vfsops.c
==============================================================================
--- head/sys/fs/devfs/devfs_vfsops.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/fs/devfs/devfs_vfsops.c	Fri May  4 20:54:27 2018	(r333263)
@@ -83,9 +83,6 @@ devfs_mount(struct mount *mp)
 	if (mp->mnt_flag & MNT_ROOTFS)
 		return (EOPNOTSUPP);
 
-	if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_DEVFS))
-		return (EPERM);
-
 	rsnum = 0;
 	injail = jailed(td->td_ucred);
 

Modified: head/sys/fs/fdescfs/fdesc_vfsops.c
==============================================================================
--- head/sys/fs/fdescfs/fdesc_vfsops.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/fs/fdescfs/fdesc_vfsops.c	Fri May  4 20:54:27 2018	(r333263)
@@ -81,12 +81,8 @@ static int
 fdesc_mount(struct mount *mp)
 {
 	struct fdescmount *fmp;
-	struct thread *td = curthread;
 	struct vnode *rvp;
 	int error;
-
-	if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_FDESCFS))
-		return (EPERM);
 
 	/*
 	 * Update is a no-op

Modified: head/sys/fs/nullfs/null_vfsops.c
==============================================================================
--- head/sys/fs/nullfs/null_vfsops.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/fs/nullfs/null_vfsops.c	Fri May  4 20:54:27 2018	(r333263)
@@ -78,15 +78,12 @@ nullfs_mount(struct mount *mp)
 	struct vnode *lowerrootvp, *vp;
 	struct vnode *nullm_rootvp;
 	struct null_mount *xmp;
-	struct thread *td = curthread;
 	char *target;
 	int isvnunlocked = 0, len;
 	struct nameidata nd, *ndp = &nd;
 
 	NULLFSDEBUG("nullfs_mount(mp = %p)\n", (void *)mp);
 
-	if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_NULLFS))
-		return (EPERM);
 	if (mp->mnt_flag & MNT_ROOTFS)
 		return (EOPNOTSUPP);
 

Modified: head/sys/fs/procfs/procfs.c
==============================================================================
--- head/sys/fs/procfs/procfs.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/fs/procfs/procfs.c	Fri May  4 20:54:27 2018	(r333263)
@@ -215,4 +215,4 @@ procfs_uninit(PFS_INIT_ARGS)
 	return (0);
 }
 
-PSEUDOFS(procfs, 1, PR_ALLOW_MOUNT_PROCFS);
+PSEUDOFS(procfs, 1, VFCF_JAIL);

Modified: head/sys/fs/pseudofs/pseudofs.h
==============================================================================
--- head/sys/fs/pseudofs/pseudofs.h	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/fs/pseudofs/pseudofs.h	Fri May  4 20:54:27 2018	(r333263)
@@ -272,7 +272,7 @@ int		 pfs_destroy	(struct pfs_node *pn);
 /*
  * Now for some initialization magic...
  */
-#define PSEUDOFS(name, version, jflag)					\
+#define PSEUDOFS(name, version, flags)					\
 									\
 static struct pfs_info name##_info = {					\
 	#name,								\
@@ -282,8 +282,6 @@ static struct pfs_info name##_info = {					\
 									\
 static int								\
 _##name##_mount(struct mount *mp) {					\
-        if (jflag && !prison_allow(curthread->td_ucred, jflag))		\
-                return (EPERM);						\
 	return (pfs_mount(&name##_info, mp));				\
 }									\
 									\
@@ -306,7 +304,7 @@ static struct vfsops name##_vfsops = {					\
 	.vfs_uninit =		_##name##_uninit,			\
 	.vfs_unmount =		pfs_unmount,				\
 };									\
-VFS_SET(name##_vfsops, name, VFCF_SYNTHETIC | (jflag ? VFCF_JAIL : 0));	\
+VFS_SET(name##_vfsops, name, VFCF_SYNTHETIC | flags);			\
 MODULE_VERSION(name, version);						\
 MODULE_DEPEND(name, pseudofs, 1, 1, 1);
 

Modified: head/sys/fs/tmpfs/tmpfs_vfsops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vfsops.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/fs/tmpfs/tmpfs_vfsops.c	Fri May  4 20:54:27 2018	(r333263)
@@ -141,7 +141,6 @@ tmpfs_mount(struct mount *mp)
 	    sizeof(struct tmpfs_dirent) + sizeof(struct tmpfs_node));
 	struct tmpfs_mount *tmp;
 	struct tmpfs_node *root;
-	struct thread *td = curthread;
 	int error;
 	bool nonc;
 	/* Size counters. */
@@ -154,9 +153,6 @@ tmpfs_mount(struct mount *mp)
 	mode_t root_mode;
 
 	struct vattr va;
-
-	if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_TMPFS))
-		return (EPERM);
 
 	if (vfs_filteropt(mp->mnt_optnew, tmpfs_opts))
 		return (EINVAL);

Modified: head/sys/kern/kern_jail.c
==============================================================================
--- head/sys/kern/kern_jail.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/kern/kern_jail.c	Fri May  4 20:54:27 2018	(r333263)
@@ -111,7 +111,7 @@ struct prison prison0 = {
 #else
 	.pr_flags	= PR_HOST|_PR_IP_SADDRSEL,
 #endif
-	.pr_allow	= PR_ALLOW_ALL,
+	.pr_allow	= PR_ALLOW_ALL_STATIC,
 };
 MTX_SYSINIT(prison0, &prison0.pr_mtx, "jail mutex", MTX_DEF);
 
@@ -181,7 +181,8 @@ static struct jailsys_flags pr_flag_jailsys[] = {
 };
 const size_t pr_flag_jailsys_size = sizeof(pr_flag_jailsys);
 
-static struct bool_flags pr_flag_allow[] = {
+/* Make this array full-size so dynamic parameters can be added. */
+static struct bool_flags pr_flag_allow[NBBY * NBPW] = {
 	{"allow.set_hostname", "allow.noset_hostname", PR_ALLOW_SET_HOSTNAME},
 	{"allow.sysvipc", "allow.nosysvipc", PR_ALLOW_SYSVIPC},
 	{"allow.raw_sockets", "allow.noraw_sockets", PR_ALLOW_RAW_SOCKETS},
@@ -189,17 +190,6 @@ static struct bool_flags pr_flag_allow[] = {
 	{"allow.mount", "allow.nomount", PR_ALLOW_MOUNT},
 	{"allow.quotas", "allow.noquotas", PR_ALLOW_QUOTAS},
 	{"allow.socket_af", "allow.nosocket_af", PR_ALLOW_SOCKET_AF},
-	{"allow.mount.devfs", "allow.mount.nodevfs", PR_ALLOW_MOUNT_DEVFS},
-	{"allow.mount.nullfs", "allow.mount.nonullfs", PR_ALLOW_MOUNT_NULLFS},
-	{"allow.mount.zfs", "allow.mount.nozfs", PR_ALLOW_MOUNT_ZFS},
-	{"allow.mount.procfs", "allow.mount.noprocfs", PR_ALLOW_MOUNT_PROCFS},
-	{"allow.mount.tmpfs", "allow.mount.notmpfs", PR_ALLOW_MOUNT_TMPFS},
-	{"allow.mount.fdescfs", "allow.mount.nofdescfs",
-	 PR_ALLOW_MOUNT_FDESCFS},
-	{"allow.mount.linprocfs", "allow.mount.nolinprocfs",
-	 PR_ALLOW_MOUNT_LINPROCFS},
-	{"allow.mount.linsysfs", "allow.mount.nolinsysfs",
-	 PR_ALLOW_MOUNT_LINSYSFS},
 	{"allow.reserved_ports", "allow.noreserved_ports",
 	 PR_ALLOW_RESERVED_PORTS},
 };
@@ -318,7 +308,8 @@ kern_jail(struct thread *td, struct jail *j)
 	/* Set permissions for top-level jails from sysctls. */
 	if (!jailed(td->td_ucred)) {
 		for (bf = pr_flag_allow;
-		     bf < pr_flag_allow + nitems(pr_flag_allow);
+		     bf < pr_flag_allow + nitems(pr_flag_allow) &&
+			bf->flag != 0;
 		     bf++) {
 			optiov[opt.uio_iovcnt].iov_base = __DECONST(char *,
 			    (jail_default_allow & bf->flag)
@@ -654,7 +645,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, i
 
 	pr_allow = ch_allow = 0;
 	for (bf = pr_flag_allow;
-	     bf < pr_flag_allow + nitems(pr_flag_allow);
+	     bf < pr_flag_allow + nitems(pr_flag_allow) && bf->flag != 0;
 	     bf++) {
 		vfs_flagopt(opts, bf->name, &pr_allow, bf->flag);
 		vfs_flagopt(opts, bf->noname, &ch_allow, bf->flag);
@@ -2115,7 +2106,7 @@ kern_jail_get(struct thread *td, struct uio *optuio, i
 			goto done_deref;
 	}
 	for (bf = pr_flag_allow;
-	     bf < pr_flag_allow + nitems(pr_flag_allow);
+	     bf < pr_flag_allow + nitems(pr_flag_allow) && bf->flag != 0;
 	     bf++) {
 		i = (pr->pr_allow & bf->flag) ? 1 : 0;
 		error = vfs_setopt(opts, bf->name, &i, sizeof(i));
@@ -3615,38 +3606,6 @@ SYSCTL_PROC(_security_jail, OID_AUTO, mount_allowed,
     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
     NULL, PR_ALLOW_MOUNT, sysctl_jail_default_allow, "I",
     "Processes in jail can mount/unmount jail-friendly file systems (deprecated)");
-SYSCTL_PROC(_security_jail, OID_AUTO, mount_devfs_allowed,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    NULL, PR_ALLOW_MOUNT_DEVFS, sysctl_jail_default_allow, "I",
-    "Processes in jail can mount the devfs file system (deprecated)");
-SYSCTL_PROC(_security_jail, OID_AUTO, mount_fdescfs_allowed,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    NULL, PR_ALLOW_MOUNT_FDESCFS, sysctl_jail_default_allow, "I",
-    "Processes in jail can mount the fdescfs file system (deprecated)");
-SYSCTL_PROC(_security_jail, OID_AUTO, mount_nullfs_allowed,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    NULL, PR_ALLOW_MOUNT_NULLFS, sysctl_jail_default_allow, "I",
-    "Processes in jail can mount the nullfs file system (deprecated)");
-SYSCTL_PROC(_security_jail, OID_AUTO, mount_procfs_allowed,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    NULL, PR_ALLOW_MOUNT_PROCFS, sysctl_jail_default_allow, "I",
-    "Processes in jail can mount the procfs file system (deprecated)");
-SYSCTL_PROC(_security_jail, OID_AUTO, mount_linprocfs_allowed,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    NULL, PR_ALLOW_MOUNT_LINPROCFS, sysctl_jail_default_allow, "I",
-    "Processes in jail can mount the linprocfs file system (deprecated)");
-SYSCTL_PROC(_security_jail, OID_AUTO, mount_linsysfs_allowed,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    NULL, PR_ALLOW_MOUNT_LINSYSFS, sysctl_jail_default_allow, "I",
-    "Processes in jail can mount the linsysfs file system (deprecated)");
-SYSCTL_PROC(_security_jail, OID_AUTO, mount_tmpfs_allowed,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    NULL, PR_ALLOW_MOUNT_TMPFS, sysctl_jail_default_allow, "I",
-    "Processes in jail can mount the tmpfs file system (deprecated)");
-SYSCTL_PROC(_security_jail, OID_AUTO, mount_zfs_allowed,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
-    NULL, PR_ALLOW_MOUNT_ZFS, sysctl_jail_default_allow, "I",
-    "Processes in jail can mount the zfs file system (deprecated)");
 
 static int
 sysctl_jail_default_level(SYSCTL_HANDLER_ARGS)
@@ -3799,23 +3758,111 @@ SYSCTL_JAIL_PARAM(_allow, reserved_ports, CTLTYPE_INT 
 SYSCTL_JAIL_PARAM_SUBNODE(allow, mount, "Jail mount/unmount permission flags");
 SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW,
     "B", "Jail may mount/unmount jail-friendly file systems in general");
-SYSCTL_JAIL_PARAM(_allow_mount, devfs, CTLTYPE_INT | CTLFLAG_RW,
-    "B", "Jail may mount the devfs file system");
-SYSCTL_JAIL_PARAM(_allow_mount, fdescfs, CTLTYPE_INT | CTLFLAG_RW,
-    "B", "Jail may mount the fdescfs file system");
-SYSCTL_JAIL_PARAM(_allow_mount, nullfs, CTLTYPE_INT | CTLFLAG_RW,
-    "B", "Jail may mount the nullfs file system");
-SYSCTL_JAIL_PARAM(_allow_mount, procfs, CTLTYPE_INT | CTLFLAG_RW,
-    "B", "Jail may mount the procfs file system");
-SYSCTL_JAIL_PARAM(_allow_mount, linprocfs, CTLTYPE_INT | CTLFLAG_RW,
-    "B", "Jail may mount the linprocfs file system");
-SYSCTL_JAIL_PARAM(_allow_mount, linsysfs, CTLTYPE_INT | CTLFLAG_RW,
-    "B", "Jail may mount the linsysfs file system");
-SYSCTL_JAIL_PARAM(_allow_mount, tmpfs, CTLTYPE_INT | CTLFLAG_RW,
-    "B", "Jail may mount the tmpfs file system");
-SYSCTL_JAIL_PARAM(_allow_mount, zfs, CTLTYPE_INT | CTLFLAG_RW,
-    "B", "Jail may mount the zfs file system");
 
+/*
+ * The VFS system will register jail-aware filesystems here.  They each get
+ * a parameter allow.mount.xxxfs and a flag to check when a jailed user
+ * attempts to mount.
+ */
+void
+prison_add_vfs(struct vfsconf *vfsp)
+{
+	char *allow_name, *allow_noname, *mount_allowed;
+	struct bool_flags *bf;
+#ifndef NO_SYSCTL_DESCR
+	char *descr;
+#endif
+	unsigned allow_flag;
+
+	if (asprintf(&allow_name, M_PRISON, "allow.mount.%s", vfsp->vfc_name) <
+	    0 || asprintf(&allow_noname, M_PRISON, "allow.mount.no%s",
+	    vfsp->vfc_name) < 0) {
+		free(allow_name, M_PRISON);
+		return;
+	}
+
+	/*
+	 * See if this parameter has already beed added, i.e. if the filesystem
+	 * was previously loaded/unloaded.
+	 */
+	mtx_lock(&prison0.pr_mtx);
+	for (bf = pr_flag_allow;
+	     bf < pr_flag_allow + nitems(pr_flag_allow) && bf->flag != 0;
+	     bf++) {
+		if (strcmp(bf->name, allow_name) == 0) {
+			vfsp->vfc_prison_flag = bf->flag;
+			goto no_add;
+		}
+	}
+
+	/*
+	 * Find a free bit in prison0's pr_allow, failing if there are none
+	 * (which shouldn't happen as long as we keep track of how many
+	 * filesystems are jail-aware).
+	 */
+	for (allow_flag = 1;; allow_flag <<= 1) {
+		if (allow_flag == 0)
+			goto no_add;
+		if ((prison0.pr_allow & allow_flag) == 0)
+			break;
+	}
+
+	/*
+	 * Note the parameter in the next open slot in pr_flag_allow.
+	 * Set the flag last so code that checks pr_flag_allow can do so
+	 * without locking.
+	 */
+	for (bf = pr_flag_allow; bf->flag != 0; bf++)
+		if (bf == pr_flag_allow + nitems(pr_flag_allow)) {
+			/* This should never happen, but is not fatal. */
+			goto no_add;
+		}
+	prison0.pr_allow |= allow_flag;
+	bf->name = allow_name;
+	bf->noname = allow_noname;
+	bf->flag = allow_flag;
+	vfsp->vfc_prison_flag = allow_flag;
+	mtx_unlock(&prison0.pr_mtx);
+
+	/*
+	 * Create sysctls for the paramter, and the back-compat global
+	 * permission.
+	 */
+#ifndef NO_SYSCTL_DESCR
+	(void)asprintf(&descr, M_TEMP, "Jail may mount the %s file system",
+	    vfsp->vfc_name);
+#endif
+	(void)SYSCTL_ADD_PROC(NULL,
+	    SYSCTL_CHILDREN(&sysctl___security_jail_param_allow_mount),
+	    OID_AUTO, vfsp->vfc_name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+	    NULL, 0, sysctl_jail_param, "B", descr);
+#ifndef NO_SYSCTL_DESCR
+	free(descr, M_TEMP);
+#endif
+	if (asprintf(&mount_allowed, M_TEMP, "mount_%s_allowed",
+		vfsp->vfc_name) >= 0) {
+#ifndef NO_SYSCTL_DESCR
+		(void)asprintf(&descr, M_TEMP,
+		  "Processes in jail can mount the %s file system (deprecated)",
+		  vfsp->vfc_name);
+#endif
+		(void)SYSCTL_ADD_PROC(NULL,
+		    SYSCTL_CHILDREN(&sysctl___security_jail), OID_AUTO,
+		    mount_allowed, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+		    NULL, allow_flag, sysctl_jail_default_allow, "I", descr);
+#ifndef NO_SYSCTL_DESCR
+		free(descr, M_TEMP);
+#endif
+		free(mount_allowed, M_TEMP);
+	}
+	return;
+
+ no_add:
+	mtx_unlock(&prison0.pr_mtx);
+	free(allow_name, M_PRISON);
+	free(allow_noname, M_PRISON);
+}
+
 #ifdef RACCT
 void
 prison_racct_foreach(void (*callback)(struct racct *racct,
@@ -4050,7 +4097,7 @@ db_show_prison(struct prison *pr)
 	}
 	db_printf(" allow           = 0x%x", pr->pr_allow);
 	for (bf = pr_flag_allow;
-	     bf < pr_flag_allow + nitems(pr_flag_allow);
+	     bf < pr_flag_allow + nitems(pr_flag_allow) && bf->flag != 0;
 	     bf++)
 		if (pr->pr_allow & bf->flag)
 			db_printf(" %s", bf->name);

Modified: head/sys/kern/vfs_init.c
==============================================================================
--- head/sys/kern/vfs_init.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/kern/vfs_init.c	Fri May  4 20:54:27 2018	(r333263)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/fnv_hash.h>
+#include <sys/jail.h>
 #include <sys/kernel.h>
 #include <sys/linker.h>
 #include <sys/mount.h>
@@ -276,7 +277,10 @@ vfs_register(struct vfsconf *vfc)
 		vfsops->vfs_extattrctl = vfs_stdextattrctl;
 	if (vfsops->vfs_sysctl == NULL)
 		vfsops->vfs_sysctl = vfs_stdsysctl;
-	
+
+	if (vfc->vfc_flags & VFCF_JAIL)
+		prison_add_vfs(vfc);
+
 	/*
 	 * Call init function for this VFS...
 	 */

Modified: head/sys/kern/vfs_mount.c
==============================================================================
--- head/sys/kern/vfs_mount.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/kern/vfs_mount.c	Fri May  4 20:54:27 2018	(r333263)
@@ -843,6 +843,16 @@ vfs_domount_first(
 	KASSERT((fsflags & MNT_UPDATE) == 0, ("MNT_UPDATE shouldn't be here"));
 
 	/*
+	 * If the jail of the calling thread lacks permission for this type of
+	 * file system, deny immediately.
+	 */
+	if (jailed(td->td_ucred) && !prison_allow(td->td_ucred,
+	    vfsp->vfc_prison_flag)) {
+		vput(vp);
+		return (EPERM);
+	}
+
+	/*
 	 * If the user is not root, ensure that they own the directory
 	 * onto which we are attempting to mount.
 	 */
@@ -1149,8 +1159,6 @@ vfs_domount(
 			vfsp = vfs_byname_kld(fstype, td, &error);
 		if (vfsp == NULL)
 			return (ENODEV);
-		if (jailed(td->td_ucred) && !(vfsp->vfc_flags & VFCF_JAIL))
-			return (EPERM);
 	}
 
 	/*

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/kern/vfs_subr.c	Fri May  4 20:54:27 2018	(r333263)
@@ -683,19 +683,21 @@ vfs_suser(struct mount *mp, struct thread *td)
 {
 	int error;
 
-	/*
-	 * If the thread is jailed, but this is not a jail-friendly file
-	 * system, deny immediately.
-	 */
-	if (!(mp->mnt_vfc->vfc_flags & VFCF_JAIL) && jailed(td->td_ucred))
-		return (EPERM);
+	if (jailed(td->td_ucred)) {
+		/*
+		 * If the jail of the calling thread lacks permission for
+		 * this type of file system, deny immediately.
+		 */
+		if (!prison_allow(td->td_ucred, mp->mnt_vfc->vfc_prison_flag))
+			return (EPERM);
 
-	/*
-	 * If the file system was mounted outside the jail of the calling
-	 * thread, deny immediately.
-	 */
-	if (prison_check(td->td_ucred, mp->mnt_cred) != 0)
-		return (EPERM);
+		/*
+		 * If the file system was mounted outside the jail of the
+		 * calling thread, deny immediately.
+		 */
+		if (prison_check(td->td_ucred, mp->mnt_cred) != 0)
+			return (EPERM);
+	}
 
 	/*
 	 * If file system supports delegated administration, we don't check

Modified: head/sys/sys/jail.h
==============================================================================
--- head/sys/sys/jail.h	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/sys/jail.h	Fri May  4 20:54:27 2018	(r333263)
@@ -216,7 +216,10 @@ struct prison_racct {
 #define	PR_IP6		0x04000000	/* IPv6 restricted or disabled */
 					/* by this jail or an ancestor */
 
-/* Flags for pr_allow */
+/*
+ * Flags for pr_allow
+ * Bits not noted here may be used for dynamic allow.mount.xxxfs.
+ */
 #define	PR_ALLOW_SET_HOSTNAME		0x00000001
 #define	PR_ALLOW_SYSVIPC		0x00000002
 #define	PR_ALLOW_RAW_SOCKETS		0x00000004
@@ -224,17 +227,9 @@ struct prison_racct {
 #define	PR_ALLOW_MOUNT			0x00000010
 #define	PR_ALLOW_QUOTAS			0x00000020
 #define	PR_ALLOW_SOCKET_AF		0x00000040
-#define	PR_ALLOW_MOUNT_DEVFS		0x00000080
-#define	PR_ALLOW_MOUNT_NULLFS		0x00000100
-#define	PR_ALLOW_MOUNT_ZFS		0x00000200
-#define	PR_ALLOW_MOUNT_PROCFS		0x00000400
-#define	PR_ALLOW_MOUNT_TMPFS		0x00000800
-#define	PR_ALLOW_MOUNT_FDESCFS		0x00001000
-#define	PR_ALLOW_MOUNT_LINPROCFS	0x00002000
-#define	PR_ALLOW_MOUNT_LINSYSFS		0x00004000
 #define	PR_ALLOW_RESERVED_PORTS		0x00008000
 #define	PR_ALLOW_KMEM_ACCESS		0x00010000	/* reserved, not used yet */
-#define	PR_ALLOW_ALL			0x0001ffff
+#define	PR_ALLOW_ALL_STATIC		0x0001807f
 
 /*
  * OSD methods
@@ -364,6 +359,7 @@ struct ucred;
 struct mount;
 struct sockaddr;
 struct statfs;
+struct vfsconf;
 int jailed(struct ucred *cred);
 int jailed_without_vnet(struct ucred *);
 void getcredhostname(struct ucred *, char *, size_t);
@@ -413,6 +409,7 @@ int prison_if(struct ucred *cred, struct sockaddr *sa)
 char *prison_name(struct prison *, struct prison *);
 int prison_priv_check(struct ucred *cred, int priv);
 int sysctl_jail_param(SYSCTL_HANDLER_ARGS);
+void prison_add_vfs(struct vfsconf *vfsp);
 void prison_racct_foreach(void (*callback)(struct racct *racct,
     void *arg2, void *arg3), void (*pre)(void), void (*post)(void),
     void *arg2, void *arg3);

Modified: head/sys/sys/mount.h
==============================================================================
--- head/sys/sys/mount.h	Fri May  4 20:38:26 2018	(r333262)
+++ head/sys/sys/mount.h	Fri May  4 20:54:27 2018	(r333263)
@@ -516,6 +516,7 @@ struct vfsconf {
 	int	vfc_typenum;		/* historic filesystem type number */
 	int	vfc_refcount;		/* number mounted of this type */
 	int	vfc_flags;		/* permanent flags */
+	int	vfc_prison_flag;	/* prison allow.mount.* flag */
 	struct	vfsoptdecl *vfc_opts;	/* mount options */
 	TAILQ_ENTRY(vfsconf) vfc_list;	/* list of vfscons */
 };
@@ -851,7 +852,8 @@ vfs_statfs_t	__vfs_statfs;
  */
 #define VFS_VERSION_00	0x19660120
 #define VFS_VERSION_01	0x20121030
-#define VFS_VERSION	VFS_VERSION_01
+#define VFS_VERSION_02	0x20180504
+#define VFS_VERSION	VFS_VERSION_02
 
 #define VFS_SET(vfsops, fsname, flags) \
 	static struct vfsconf fsname ## _vfsconf = {		\

Modified: head/usr.sbin/jail/jail.8
==============================================================================
--- head/usr.sbin/jail/jail.8	Fri May  4 20:38:26 2018	(r333262)
+++ head/usr.sbin/jail/jail.8	Fri May  4 20:54:27 2018	(r333263)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 5, 2017
+.Dd May 4, 2018
 .Dt JAIL 8
 .Os
 .Sh NAME
@@ -545,6 +545,33 @@ is set to a value lower than 2.
 The devfs ruleset should be restricted from the default by using the
 .Va devfs_ruleset
 option.
+.It Va allow.quotas
+The jail root may administer quotas on the jail's filesystem(s).
+This includes filesystems that the jail may share with other jails or
+with non-jailed parts of the system.
+.It Va allow.socket_af
+Sockets within a jail are normally restricted to IPv4, IPv6, local
+(UNIX), and route.  This allows access to other protocol stacks that
+have not had jail functionality added to them.
+.It Va allow.reserved_ports
+The jail root may bind to ports lower than 1024.
+.El
+.El
+.Pp
+Kernel modules may add their own parameters, which only exist when the
+module is loaded.
+These are typically headed under a parameter named after the module,
+with values of
+.Dq inherit
+to give the jail full use of the module,
+.Dq new
+to encapsulate the jail in some module-specific way,
+and
+.Dq disable
+to make the module unavailable to the jail.
+There also may be other parameters to define jail behavior within the module.
+Module-specific parameters include:
+.Bl -tag -width indent
 .It Va allow.mount.fdescfs
 privileged users inside the jail will be able to mount and unmount the
 fdescfs file system.
@@ -605,33 +632,6 @@ See
 .Xr zfs 8
 for information on how to configure the ZFS filesystem to operate from
 within a jail.
-.It Va allow.quotas
-The jail root may administer quotas on the jail's filesystem(s).
-This includes filesystems that the jail may share with other jails or
-with non-jailed parts of the system.
-.It Va allow.socket_af
-Sockets within a jail are normally restricted to IPv4, IPv6, local
-(UNIX), and route.  This allows access to other protocol stacks that
-have not had jail functionality added to them.
-.It Va allow.reserved_ports
-The jail root may bind to ports lower than 1024.
-.El
-.El
-.Pp
-Kernel modules may add their own parameters, which only exist when the
-module is loaded.
-These are typically headed under a parameter named after the module,
-with values of
-.Dq inherit
-to give the jail full use of the module,
-.Dq new
-to encapsulate the jail in some module-specific way,
-and
-.Dq disable
-to make the module unavailable to the jail.
-There also may be other parameters to define jail behavior within the module.
-Module-specific parameters include:
-.Bl -tag -width indent
 .It Va linux
 Determine how a jail's Linux emulation environment appears.
 A value of


More information about the svn-src-head mailing list