summaryrefslogtreecommitdiffstats
path: root/sys/fs
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 /sys/fs
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)
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/devfs/devfs_vnops.c22
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
OpenPOWER on IntegriCloud