From owner-svn-src-all@FreeBSD.ORG Thu Feb 23 18:51:25 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5A0831065740; Thu, 23 Feb 2012 18:51:25 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 433DE8FC1C; Thu, 23 Feb 2012 18:51:25 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q1NIpOpL018335; Thu, 23 Feb 2012 18:51:24 GMT (envelope-from mm@svn.freebsd.org) Received: (from mm@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q1NIpOxH018329; Thu, 23 Feb 2012 18:51:24 GMT (envelope-from mm@svn.freebsd.org) Message-Id: <201202231851.q1NIpOxH018329@svn.freebsd.org> From: Martin Matuska Date: Thu, 23 Feb 2012 18:51:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r232059 - in head: sys/fs/devfs sys/fs/nullfs sys/kern sys/sys usr.sbin/jail X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Feb 2012 18:51:25 -0000 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 #include #include +#include #include @@ -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