svn commit: r232059 - in head: sys/fs/devfs sys/fs/nullfs sys/kern
sys/sys usr.sbin/jail
Martin Matuska
mm at FreeBSD.org
Thu Feb 23 18:51:25 UTC 2012
Author: mm
Date: Thu Feb 23 18:51:24 2012
New Revision: 232059
URL: http://svn.freebsd.org/changeset/base/232059
Log:
To improve control over the use of mount(8) inside a jail(8), introduce
a new jail parameter node with the following parameters:
allow.mount.devfs:
allow mounting the devfs filesystem inside a jail
allow.mount.nullfs:
allow mounting the nullfs filesystem inside a jail
Both parameters are disabled by default (equals the behavior before
devfs and nullfs in jails). Administrators have to explicitly allow
mounting devfs and nullfs for each jail. The value "-1" of the
devfs_ruleset parameter is removed in favor of the new allow setting.
Reviewed by: jamie
Suggested by: pjd
MFC after: 2 weeks
Modified:
head/sys/fs/devfs/devfs_vfsops.c
head/sys/fs/nullfs/null_vfsops.c
head/sys/kern/kern_jail.c
head/sys/sys/jail.h
head/usr.sbin/jail/jail.8
Modified: head/sys/fs/devfs/devfs_vfsops.c
==============================================================================
--- head/sys/fs/devfs/devfs_vfsops.c Thu Feb 23 18:50:19 2012 (r232058)
+++ head/sys/fs/devfs/devfs_vfsops.c Thu Feb 23 18:51:24 2012 (r232059)
@@ -71,7 +71,7 @@ devfs_mount(struct mount *mp)
struct devfs_mount *fmp;
struct vnode *rvp;
struct thread *td = curthread;
- int rsnum;
+ int injail, rsnum;
if (devfs_unr == NULL)
devfs_unr = new_unrhdr(0, INT_MAX, NULL);
@@ -81,7 +81,11 @@ 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);
if (mp->mnt_optnew != NULL) {
if (vfs_filteropt(mp->mnt_optnew, devfs_opts))
@@ -89,24 +93,20 @@ devfs_mount(struct mount *mp)
if (vfs_getopt(mp->mnt_optnew, "ruleset", NULL, NULL) == 0 &&
(vfs_scanopt(mp->mnt_optnew, "ruleset", "%d",
- &rsnum) != 1 || rsnum < 0 || rsnum > 65535))
- error = EINVAL;
- }
+ &rsnum) != 1 || rsnum < 0 || rsnum > 65535)) {
+ vfs_mount_error(mp, "%s",
+ "invalid ruleset specification");
+ return (EINVAL);
+ }
- /* jails enforce their ruleset, prison0 has no restrictions */
- if (td->td_ucred->cr_prison->pr_devfs_rsnum != 0) {
- rsnum = td->td_ucred->cr_prison->pr_devfs_rsnum;
- if (rsnum == -1)
+ if (injail && rsnum != 0 &&
+ rsnum != td->td_ucred->cr_prison->pr_devfs_rsnum)
return (EPERM);
- /* check rsnum for sanity, devfs_rsnum is uint16_t */
- if (rsnum < 0 || rsnum > 65535)
- error = EINVAL;
}
- if (error) {
- vfs_mount_error(mp, "%s", "invalid ruleset specification");
- return (error);
- }
+ /* jails enforce their ruleset */
+ if (injail)
+ rsnum = td->td_ucred->cr_prison->pr_devfs_rsnum;
if (mp->mnt_flag & MNT_UPDATE) {
if (rsnum != 0) {
Modified: head/sys/fs/nullfs/null_vfsops.c
==============================================================================
--- head/sys/fs/nullfs/null_vfsops.c Thu Feb 23 18:50:19 2012 (r232058)
+++ head/sys/fs/nullfs/null_vfsops.c Thu Feb 23 18:51:24 2012 (r232059)
@@ -50,6 +50,7 @@
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/vnode.h>
+#include <sys/jail.h>
#include <fs/nullfs/null.h>
@@ -75,12 +76,16 @@ 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/kern/kern_jail.c
==============================================================================
--- head/sys/kern/kern_jail.c Thu Feb 23 18:50:19 2012 (r232058)
+++ head/sys/kern/kern_jail.c Thu Feb 23 18:51:24 2012 (r232059)
@@ -201,6 +201,8 @@ static char *pr_allow_names[] = {
"allow.mount",
"allow.quotas",
"allow.socket_af",
+ "allow.mount.devfs",
+ "allow.mount.nullfs",
};
const size_t pr_allow_names_size = sizeof(pr_allow_names);
@@ -212,12 +214,14 @@ static char *pr_allow_nonames[] = {
"allow.nomount",
"allow.noquotas",
"allow.nosocket_af",
+ "allow.mount.nodevfs",
+ "allow.mount.nonullfs",
};
const size_t pr_allow_nonames_size = sizeof(pr_allow_nonames);
#define JAIL_DEFAULT_ALLOW PR_ALLOW_SET_HOSTNAME
#define JAIL_DEFAULT_ENFORCE_STATFS 2
-#define JAIL_DEFAULT_DEVFS_RSNUM -1
+#define JAIL_DEFAULT_DEVFS_RSNUM 0
static unsigned jail_default_allow = JAIL_DEFAULT_ALLOW;
static int jail_default_enforce_statfs = JAIL_DEFAULT_ENFORCE_STATFS;
static int jail_default_devfs_rsnum = JAIL_DEFAULT_DEVFS_RSNUM;
@@ -1279,7 +1283,7 @@ kern_jail_set(struct thread *td, struct
pr->pr_securelevel = ppr->pr_securelevel;
pr->pr_allow = JAIL_DEFAULT_ALLOW & ppr->pr_allow;
pr->pr_enforce_statfs = JAIL_DEFAULT_ENFORCE_STATFS;
- pr->pr_devfs_rsnum = JAIL_DEFAULT_DEVFS_RSNUM;
+ pr->pr_devfs_rsnum = ppr->pr_devfs_rsnum;
LIST_INIT(&pr->pr_children);
mtx_init(&pr->pr_mtx, "jail mutex", NULL, MTX_DEF | MTX_DUPOK);
@@ -1361,21 +1365,19 @@ kern_jail_set(struct thread *td, struct
if (gotrsnum) {
/*
* devfs_rsnum is a uint16_t
- * value of -1 disables devfs mounts
*/
- if (rsnum < -1 || rsnum > 65535) {
+ if (rsnum < 0 || rsnum > 65535) {
error = EINVAL;
goto done_deref_locked;
}
/*
- * Nested jails may inherit parent's devfs ruleset
- * or disable devfs
+ * Nested jails always inherit parent's devfs ruleset
*/
if (jailed(td->td_ucred)) {
if (rsnum > 0 && rsnum != ppr->pr_devfs_rsnum) {
error = EPERM;
goto done_deref_locked;
- } else if (rsnum == 0)
+ } else
rsnum = ppr->pr_devfs_rsnum;
}
}
@@ -1623,8 +1625,7 @@ kern_jail_set(struct thread *td, struct
pr->pr_devfs_rsnum = rsnum;
/* Pass this restriction on to the children. */
FOREACH_PRISON_DESCENDANT_LOCKED(pr, tpr, descend)
- if (tpr->pr_devfs_rsnum != -1)
- tpr->pr_devfs_rsnum = rsnum;
+ tpr->pr_devfs_rsnum = rsnum;
}
if (name != NULL) {
if (ppr == &prison0)
@@ -4195,6 +4196,14 @@ SYSCTL_PROC(_security_jail, OID_AUTO, mo
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");
+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/unmount the devfs file system");
+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/unmount the nullfs file system");
static int
sysctl_jail_default_level(SYSCTL_HANDLER_ARGS)
@@ -4329,13 +4338,19 @@ SYSCTL_JAIL_PARAM(_allow, raw_sockets, C
"B", "Jail may create raw sockets");
SYSCTL_JAIL_PARAM(_allow, chflags, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may alter system file flags");
-SYSCTL_JAIL_PARAM(_allow, mount, CTLTYPE_INT | CTLFLAG_RW,
- "B", "Jail may mount/unmount jail-friendly file systems");
SYSCTL_JAIL_PARAM(_allow, quotas, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may set file quotas");
SYSCTL_JAIL_PARAM(_allow, socket_af, CTLTYPE_INT | CTLFLAG_RW,
"B", "Jail may create sockets other than just UNIX/IPv4/IPv6/route");
+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/unmount the devfs file system");
+SYSCTL_JAIL_PARAM(_allow_mount, nullfs, CTLTYPE_INT | CTLFLAG_RW,
+ "B", "Jail may mount/unmount the nullfs file system");
+
void
prison_racct_foreach(void (*callback)(struct racct *racct,
void *arg2, void *arg3), void *arg2, void *arg3)
Modified: head/sys/sys/jail.h
==============================================================================
--- head/sys/sys/jail.h Thu Feb 23 18:50:19 2012 (r232058)
+++ head/sys/sys/jail.h Thu Feb 23 18:51:24 2012 (r232059)
@@ -223,7 +223,9 @@ struct prison_racct {
#define PR_ALLOW_MOUNT 0x0010
#define PR_ALLOW_QUOTAS 0x0020
#define PR_ALLOW_SOCKET_AF 0x0040
-#define PR_ALLOW_ALL 0x007f
+#define PR_ALLOW_MOUNT_DEVFS 0x0080
+#define PR_ALLOW_MOUNT_NULLFS 0x0100
+#define PR_ALLOW_ALL 0x01ff
/*
* OSD methods
@@ -338,6 +340,8 @@ SYSCTL_DECL(_security_jail_param);
sysctl_jail_param, fmt, descr)
#define SYSCTL_JAIL_PARAM_NODE(module, descr) \
SYSCTL_NODE(_security_jail_param, OID_AUTO, module, 0, 0, descr)
+#define SYSCTL_JAIL_PARAM_SUBNODE(parent, module, descr) \
+ SYSCTL_NODE(_security_jail_param_##parent, OID_AUTO, module, 0, 0, descr)
#define SYSCTL_JAIL_PARAM_SYS_NODE(module, access, descr) \
SYSCTL_JAIL_PARAM_NODE(module, descr); \
SYSCTL_JAIL_PARAM(_##module, , CTLTYPE_INT | (access), "E,jailsys", \
Modified: head/usr.sbin/jail/jail.8
==============================================================================
--- head/usr.sbin/jail/jail.8 Thu Feb 23 18:50:19 2012 (r232058)
+++ head/usr.sbin/jail/jail.8 Thu Feb 23 18:51:24 2012 (r232059)
@@ -34,7 +34,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 9, 2012
+.Dd February 23, 2012
.Dt JAIL 8
.Os
.Sh NAME
@@ -303,15 +303,16 @@ If the system securelevel is changed, an
least as secure.
.It Va devfs_ruleset
The number of the devfs ruleset that is enforced for mounting devfs in
-this jail and its descendants. A value of zero means no ruleset is enforced
-or if set inside a jail for a descendant jail, the parent jails's devfs
-ruleset enforcement is inherited. A value of -1 (default) means mounting a
-devfs filesystem is not allowed. Mounting devfs inside a jail is possible
-only if the
+this jail. A value of zero (default) means no ruleset is enforced. Descendant
+jails inherit the parent jail's devfs ruleset enforcement. Mounting devfs
+inside a jail is possible only if the
.Va allow.mount
-permission is effective and
+and
+.Va allow.mount.devfs
+permissions are effective and
.Va enforce_statfs
-is set to a value lower than 2.
+is set to a value lower than 2. Devfs rules and rulesets cannot be viewed or
+modified from inside a jail.
.It Va children.max
The number of child jails allowed to be created by this jail (or by
other jails under this jail).
@@ -407,6 +408,25 @@ within a jail.
This permission is effective only if
.Va enforce_statfs
is set to a value lower than 2.
+.It Va allow.mount.devfs
+privileged users inside the jail will be able to mount and unmount the
+devfs file system.
+This permission is effective only together with
+.Va allow.mount
+and if
+.Va enforce_statfs
+is set to a value lower than 2. Please consider restricting the devfs ruleset
+with the
+.Va devfs_ruleset
+option.
+.It Va allow.mount.nullfs
+privileged users inside the jail will be able to mount and unmount the
+nullfs file system.
+This permission is effective only together with
+.Va allow.mount
+and if
+.Va enforce_statfs
+is set to a value lower than 2.
.It Va allow.quotas
The prison root may administer quotas on the jail's filesystem(s).
This includes filesystems that the jail may share with other jails or
More information about the svn-src-all
mailing list