diff options
author | ed <ed@FreeBSD.org> | 2009-06-20 14:50:32 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-06-20 14:50:32 +0000 |
commit | 63a4c7f5226e69853f4c0d15a1c6d0e35ea5523e (patch) | |
tree | f0fd4ecb52c9718823a0b05d1efd9e87c9c6be2c /sys/fs | |
parent | 51b981d72bb852d8a1bf8627132b440a55357373 (diff) | |
download | FreeBSD-src-63a4c7f5226e69853f4c0d15a1c6d0e35ea5523e.zip FreeBSD-src-63a4c7f5226e69853f4c0d15a1c6d0e35ea5523e.tar.gz |
Improve nested jail awareness of devfs by handling credentials.
Now that we start to use credentials on character devices more often
(because of MPSAFE TTY), move the prison-checks that are in place in the
TTY code into devfs.
Instead of strictly comparing the prisons, use the more common
prison_check() function to compare credentials. This means that
pseudo-terminals are only visible in devfs by processes within the same
jail and parent jails.
Even though regular users in parent jails can now interact with
pseudo-terminals from child jails, this seems to be the right approach.
These processes are also capable of interacting with the jailed
processes anyway, through signals for example.
Reviewed by: kib, rwatson (older version)
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/devfs/devfs_vnops.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index f24e12e..3d6e0f0 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -48,6 +48,7 @@ #include <sys/file.h> #include <sys/filedesc.h> #include <sys/filio.h> +#include <sys/jail.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/malloc.h> @@ -706,6 +707,22 @@ devfs_kqfilter_f(struct file *fp, struct knote *kn) return (error); } +static inline int +devfs_prison_check(struct devfs_dirent *de, struct ucred *tcr) +{ + struct cdev_priv *cdp; + struct ucred *dcr; + + cdp = de->de_cdp; + if (cdp == NULL) + return (0); + dcr = cdp->cdp_c.si_cred; + if (dcr == NULL) + return (0); + + return (prison_check(tcr, dcr)); +} + static int devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) { @@ -831,6 +848,9 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) return (ENOENT); } + if (devfs_prison_check(de, td->td_ucred)) + return (ENOENT); + if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) { error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td); if (error) @@ -1106,6 +1126,8 @@ devfs_readdir(struct vop_readdir_args *ap) KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__)); if (dd->de_flags & DE_WHITEOUT) continue; + if (devfs_prison_check(dd, ap->a_cred)) + continue; if (dd->de_dirent->d_type == DT_DIR) de = dd->de_dir; else |