[CFR] [PATCH] jail mount/unmount patch
Martin Matuska
mm at FreeBSD.org
Wed Jul 27 20:08:47 UTC 2011
Please review my attached patch.
The patch fixes mount/unmount inside a jail for filesystems with the
VFCF_JAIL flag
security.jail.mount_allowed=1 is required.
For "enforce_statfs == 2" it makes no sense to allow mount/unmount
inside a jail so enforce_statfs == 2 implies mount_allowed = 0
The filesystems mounted inside a jail have now a corect f_mntonname.
Tested with:
zfs - works! (both enforce_statfs=0 and enforce_statfs=1)
nullfs (with added VFCF_JAIL flag) - works ! (both enforce_statfs=0 and
enforce_statfs=1)
tmpfs (with added VFCF_JAIL flag) - works ! (both enforce_statfs=0 and
enforce_statfs=1)
I assume other filesystems are going to work correctly, too (e.g nfs).
Fore the future, I suggest a option to allow mounting specific
filesystems in a jail (e.g. zfs, nullfs, tmpfs).
I consider nullfs mounts harmless inside a jail.
With jailed nullfs and tmpfs we can run tinderbox in a jail!
Cheers,
mm
--
Martin Matuska
FreeBSD committer
http://blog.vx.sk
-------------- next part --------------
Index: src/sys/kern/kern_jail.c
===================================================================
--- src/sys/kern/kern_jail.c (revision 224297)
+++ src/sys/kern/kern_jail.c (working copy)
@@ -3858,7 +3858,8 @@
case PRIV_VFS_UNMOUNT:
case PRIV_VFS_MOUNT_NONUSER:
case PRIV_VFS_MOUNT_OWNER:
- if (cred->cr_prison->pr_allow & PR_ALLOW_MOUNT)
+ if (cred->cr_prison->pr_allow & PR_ALLOW_MOUNT &&
+ cred->cr_prison->pr_enforce_statfs != 2)
return (0);
else
return (EPERM);
Index: src/sys/kern/vfs_mount.c
===================================================================
--- src/sys/kern/vfs_mount.c (revision 224297)
+++ src/sys/kern/vfs_mount.c (working copy)
@@ -1007,6 +1007,7 @@
struct vfsconf *vfsp;
struct nameidata nd;
struct vnode *vp;
+ char realfspath[MNAMELEN];
int error;
/*
@@ -1023,6 +1024,21 @@
}
/*
+ * If we are jailed, construct real filesystem path
+ */
+ if (jailed(td->td_ucred) &&
+ strcmp(td->td_ucred->cr_prison->pr_path, "/") != 0) {
+ if (strlen(td->td_ucred->cr_prison->pr_path) +
+ strlen(fspath) >= MNAMELEN)
+ return (ENAMETOOLONG);
+ strlcpy(realfspath, td->td_ucred->cr_prison->pr_path,
+ sizeof(realfspath));
+ strlcat(realfspath, fspath, sizeof(realfspath));
+ } else {
+ strlcpy(realfspath, fspath, sizeof(realfspath));
+ }
+
+ /*
* Do not allow NFS export or MNT_SUIDDIR by unprivileged users.
*/
if (fsflags & MNT_EXPORTED) {
@@ -1070,7 +1086,7 @@
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
if ((fsflags & MNT_UPDATE) == 0) {
- error = vfs_domount_first(td, vfsp, fspath, vp, fsflags,
+ error = vfs_domount_first(td, vfsp, realfspath, vp, fsflags,
optlist);
} else {
error = vfs_domount_update(td, vp, fsflags, optlist);
@@ -1107,6 +1123,7 @@
struct mount *mp;
char *pathbuf;
int error, id0, id1;
+ char realfspath[MNAMELEN];
AUDIT_ARG_VALUE(uap->flags);
if (jailed(td->td_ucred) || usermount == 0) {
@@ -1139,10 +1156,23 @@
}
mtx_unlock(&mountlist_mtx);
} else {
- AUDIT_ARG_UPATH1(td, pathbuf);
+ /*
+ * If we are jailed and enforce_statfs=1
+ * construct real filesystem path
+ */
+ if (jailed(td->td_ucred) &&
+ td->td_ucred->cr_prison->pr_enforce_statfs == 1 &&
+ strcmp(td->td_ucred->cr_prison->pr_path, "/") != 0) {
+ strlcpy(realfspath, td->td_ucred->cr_prison->pr_path,
+ sizeof(realfspath));
+ strlcat(realfspath, pathbuf, sizeof(realfspath));
+ } else {
+ strlcpy(realfspath, pathbuf, sizeof(realfspath));
+ }
+ AUDIT_ARG_UPATH1(td, realfspath);
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
- if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0)
+ if (strcmp(mp->mnt_stat.f_mntonname, realfspath) == 0)
break;
}
mtx_unlock(&mountlist_mtx);
More information about the zfs-devel
mailing list