diff options
author | pjd <pjd@FreeBSD.org> | 2007-04-13 23:54:22 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2007-04-13 23:54:22 +0000 |
commit | ad49fbe326807d31cbb5c33e73cd8dd65d29f317 (patch) | |
tree | f01b3fd08bcd6ec0fb37b3bcffbb4f20ca54d35d /sys/kern | |
parent | e6d8ff48cac534bd7efd0048f2e700bd605df778 (diff) | |
download | FreeBSD-src-ad49fbe326807d31cbb5c33e73cd8dd65d29f317.zip FreeBSD-src-ad49fbe326807d31cbb5c33e73cd8dd65d29f317.tar.gz |
Fix jails and jail-friendly file systems handling:
- We need to allow for PRIV_VFS_MOUNT_OWNER inside a jail.
- Move security checks to vfs_suser() and deny unmounting and updating
for jailed root from different jails, etc.
OK'ed by: rwatson
Diffstat (limited to 'sys/kern')
-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) |