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 | |
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)
-rw-r--r-- | sys/fs/devfs/devfs_vnops.c | 22 | ||||
-rw-r--r-- | sys/kern/tty.c | 7 | ||||
-rw-r--r-- | sys/sys/priv.h | 1 |
3 files changed, 22 insertions, 8 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 diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 2603cac..61c8785 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -219,13 +219,6 @@ ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) struct tty *tp = dev->si_drv1; int error = 0; - /* Disallow access when the TTY belongs to a different prison. */ - if (dev->si_cred != NULL && - dev->si_cred->cr_prison != td->td_ucred->cr_prison && - priv_check(td, PRIV_TTY_PRISON)) { - return (EPERM); - } - tty_lock(tp); if (tty_gone(tp)) { /* Device is already gone. */ diff --git a/sys/sys/priv.h b/sys/sys/priv.h index d82341f..2af31eb 100644 --- a/sys/sys/priv.h +++ b/sys/sys/priv.h @@ -211,7 +211,6 @@ #define PRIV_TTY_DRAINWAIT 251 /* Set tty drain wait time. */ #define PRIV_TTY_DTRWAIT 252 /* Set DTR wait on tty. */ #define PRIV_TTY_EXCLUSIVE 253 /* Override tty exclusive flag. */ -#define PRIV_TTY_PRISON 254 /* Can open pts across jails. */ #define PRIV_TTY_STI 255 /* Simulate input on another tty. */ #define PRIV_TTY_SETA 256 /* Set tty termios structure. */ |