summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-06-20 14:50:32 +0000
committered <ed@FreeBSD.org>2009-06-20 14:50:32 +0000
commit63a4c7f5226e69853f4c0d15a1c6d0e35ea5523e (patch)
treef0fd4ecb52c9718823a0b05d1efd9e87c9c6be2c
parent51b981d72bb852d8a1bf8627132b440a55357373 (diff)
downloadFreeBSD-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.c22
-rw-r--r--sys/kern/tty.c7
-rw-r--r--sys/sys/priv.h1
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. */
OpenPOWER on IntegriCloud