diff options
-rw-r--r-- | sys/kern/kern_jail.c | 1 | ||||
-rw-r--r-- | sys/kern/vfs_mount.c | 5 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 24 |
3 files changed, 25 insertions, 5 deletions
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 1573f5a..f61b301 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -704,6 +704,7 @@ prison_priv_check(struct ucred *cred, int priv) case PRIV_VFS_MOUNT: case PRIV_VFS_UNMOUNT: case PRIV_VFS_MOUNT_NONUSER: + case PRIV_VFS_MOUNT_OWNER: if (jail_mount_allowed) return (0); else diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 5182249..16b6c25 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -865,11 +865,6 @@ vfs_domount( return (EINVAL); } mp = vp->v_mount; - vfsp = mp->mnt_vfc; - if (jailed(td->td_ucred) && !(vfsp->vfc_flags & VFCF_JAIL)) { - vput(vp); - return (EPERM); - } MNT_ILOCK(mp); flag = mp->mnt_flag; /* diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 32f34e6..0b0c939 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include <sys/extattr.h> #include <sys/file.h> #include <sys/fcntl.h> +#include <sys/jail.h> #include <sys/kdb.h> #include <sys/kernel.h> #include <sys/kthread.h> @@ -405,6 +406,29 @@ 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 (jailed(td->td_ucred) && !(mp->mnt_vfc->vfc_flags & VFCF_JAIL)) + return (EPERM); + + /* + * If the file system was mounted outside a jail and a jailed thread + * tries to access it, deny immediately. + */ + if (!jailed(mp->mnt_cred) && jailed(td->td_ucred)) + return (EPERM); + + /* + * If the file system was mounted inside different jail that the jail of + * the calling thread, deny immediately. + */ + if (jailed(mp->mnt_cred) && jailed(td->td_ucred) && + mp->mnt_cred->cr_prison != td->td_ucred->cr_prison) { + return (EPERM); + } + if ((mp->mnt_flag & MNT_USER) == 0 || mp->mnt_cred->cr_uid != td->td_ucred->cr_uid) { if ((error = priv_check(td, PRIV_VFS_MOUNT_OWNER)) != 0) |