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
This commit is contained in:
parent
0a50333302
commit
bf3db8aa65
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=232059
@ -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) {
|
||||
|
@ -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);
|
||||
/*
|
||||
|
@ -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 uio *optuio, int flags)
|
||||
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 uio *optuio, int flags)
|
||||
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 uio *optuio, int flags)
|
||||
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, 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");
|
||||
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, CTLTYPE_INT | CTLFLAG_RW,
|
||||
"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)
|
||||
|
@ -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", \
|
||||
|
@ -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, any jail securelevels will be at
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user