Module Name:    src
Committed By:   christos
Date:           Fri Apr  4 18:10:29 UTC 2014

Modified Files:
        src/sys/fs/ptyfs: ptyfs.h ptyfs_vfsops.c ptyfs_vnops.c

Log Message:
Handle multiple ptyfs mounts with different chroots. ptys opened in one
chroot are only visible in that chroot.


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/sys/fs/ptyfs/ptyfs.h
cvs rdiff -u -r1.48 -r1.49 src/sys/fs/ptyfs/ptyfs_vfsops.c
cvs rdiff -u -r1.45 -r1.46 src/sys/fs/ptyfs/ptyfs_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/ptyfs/ptyfs.h
diff -u src/sys/fs/ptyfs/ptyfs.h:1.11 src/sys/fs/ptyfs/ptyfs.h:1.12
--- src/sys/fs/ptyfs/ptyfs.h:1.11	Fri Mar 21 13:21:53 2014
+++ src/sys/fs/ptyfs/ptyfs.h	Fri Apr  4 14:10:29 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptyfs.h,v 1.11 2014/03/21 17:21:53 christos Exp $	*/
+/*	$NetBSD: ptyfs.h,v 1.12 2014/04/04 18:10:29 christos Exp $	*/
 
 /*
  * Copyright (c) 1993
@@ -106,6 +106,8 @@ struct ptyfsnode {
 };
 
 struct ptyfsmount {
+	TAILQ_ENTRY(ptyfsmount) pmnt_le;
+	struct mount *pmnt_mp;
 	gid_t pmnt_gid;
 	mode_t pmnt_mode;
 	int pmnt_flags;

Index: src/sys/fs/ptyfs/ptyfs_vfsops.c
diff -u src/sys/fs/ptyfs/ptyfs_vfsops.c:1.48 src/sys/fs/ptyfs/ptyfs_vfsops.c:1.49
--- src/sys/fs/ptyfs/ptyfs_vfsops.c:1.48	Thu Mar 27 13:31:56 2014
+++ src/sys/fs/ptyfs/ptyfs_vfsops.c	Fri Apr  4 14:10:29 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptyfs_vfsops.c,v 1.48 2014/03/27 17:31:56 christos Exp $	*/
+/*	$NetBSD: ptyfs_vfsops.c,v 1.49 2014/04/04 18:10:29 christos Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993, 1995
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ptyfs_vfsops.c,v 1.48 2014/03/27 17:31:56 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ptyfs_vfsops.c,v 1.49 2014/04/04 18:10:29 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -77,6 +77,7 @@ static int ptyfs__allocvp(struct mount *
 static int ptyfs__makename(struct mount *, struct lwp *, char *, size_t,
     dev_t, char);
 static void ptyfs__getvattr(struct mount *, struct lwp *, struct vattr *);
+static int ptyfs__getmp(struct lwp *, struct mount **);
 
 /*
  * ptm glue: When we mount, we make ptm point to us.
@@ -84,13 +85,37 @@ static void ptyfs__getvattr(struct mount
 struct ptm_pty *ptyfs_save_ptm;
 static int ptyfs_count;
 
+static TAILQ_HEAD(, ptyfsmount) ptyfs_head;
+
 struct ptm_pty ptm_ptyfspty = {
 	ptyfs__allocvp,
 	ptyfs__makename,
 	ptyfs__getvattr,
-	NULL
+	ptyfs__getmp,
 };
 
+static int
+ptyfs__getmp(struct lwp *l, struct mount **mpp)
+{
+ 	struct cwdinfo *cwdi = l->l_proc->p_cwdi;
+ 	struct mount *mp;
+	struct ptyfsmount *pmnt;
+ 
+	TAILQ_FOREACH(pmnt, &ptyfs_head, pmnt_le) {
+		mp = pmnt->pmnt_mp;
+		if (cwdi->cwdi_rdir == NULL)
+			goto ok;
+
+		if (vn_isunder(mp->mnt_vnodecovered, cwdi->cwdi_rdir, l))
+			goto ok;
+	}
+ 	*mpp = NULL;
+ 	return EOPNOTSUPP;
+ok:
+	*mpp = mp;
+	return 0;
+}
+
 static const char *
 ptyfs__getpath(struct lwp *l, const struct mount *mp)
 {
@@ -137,6 +162,18 @@ ptyfs__makename(struct mount *mp, struct
 		len = snprintf(tbuf, bufsiz, "/dev/null");
 		break;
 	case 't':
+		/*
+		 * We support traditional ptys, so we can get here,
+		 * if pty had been opened before PTYFS was mounted,
+		 * or was opened through /dev/ptyXX devices.
+		 * Return it only outside chroot for more security .
+		 */
+		if (l->l_proc->p_cwdi->cwdi_rdir == NULL
+		    && ptyfs_save_ptm != NULL 
+		    && ptyfs_used_get(PTYFSptc, minor(dev), mp, 0) == NULL)
+			return (*ptyfs_save_ptm->makename)(mp, l,
+			    tbuf, bufsiz, dev, ms);
+
 		np = ptyfs__getpath(l, mp);
 		if (np == NULL)
 			return EOPNOTSUPP;
@@ -189,6 +226,7 @@ void
 ptyfs_init(void)
 {
 
+	TAILQ_INIT(&ptyfs_head);
 	malloc_type_attach(M_PTYFSMNT);
 	malloc_type_attach(M_PTYFSTMP);
 	ptyfs_hashinit();
@@ -274,12 +312,12 @@ ptyfs_mount(struct mount *mp, const char
 		return error;
 	}
 
-	/* Point pty access to us */
-	if (ptyfs_count == 0) {
-		ptm_ptyfspty.arg = mp;
+	pmnt->pmnt_mp = mp;
+	TAILQ_INSERT_TAIL(&ptyfs_head, pmnt, pmnt_le);
+	if (ptyfs_count++ == 0) {
+		/* Point pty access to us */
 		ptyfs_save_ptm = pty_sethandler(&ptm_ptyfspty);
 	}
-	ptyfs_count++;
 	return 0;
 }
 
@@ -296,6 +334,7 @@ ptyfs_unmount(struct mount *mp, int mntf
 {
 	int error;
 	int flags = 0;
+	struct ptyfsmount *pmnt;
 
 	if (mntflags & MNT_FORCE)
 		flags |= FORCECLOSE;
@@ -308,8 +347,13 @@ ptyfs_unmount(struct mount *mp, int mntf
 		/* Restore where pty access was pointing */
 		(void)pty_sethandler(ptyfs_save_ptm);
 		ptyfs_save_ptm = NULL;
-		ptm_ptyfspty.arg = NULL;
 	}
+	TAILQ_FOREACH(pmnt, &ptyfs_head, pmnt_le) {
+		if (pmnt->pmnt_mp == mp) {
+			TAILQ_REMOVE(&ptyfs_head, pmnt, pmnt_le);
+			break;
+		}
+ 	}
 
 	/*
 	 * Finally, throw away the ptyfsmount structure

Index: src/sys/fs/ptyfs/ptyfs_vnops.c
diff -u src/sys/fs/ptyfs/ptyfs_vnops.c:1.45 src/sys/fs/ptyfs/ptyfs_vnops.c:1.46
--- src/sys/fs/ptyfs/ptyfs_vnops.c:1.45	Thu Mar 27 17:13:06 2014
+++ src/sys/fs/ptyfs/ptyfs_vnops.c	Fri Apr  4 14:10:29 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptyfs_vnops.c,v 1.45 2014/03/27 21:13:06 christos Exp $	*/
+/*	$NetBSD: ptyfs_vnops.c,v 1.46 2014/04/04 18:10:29 christos Exp $	*/
 
 /*
  * Copyright (c) 1993, 1995
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.45 2014/03/27 21:13:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.46 2014/04/04 18:10:29 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -141,6 +141,7 @@ int	ptyfs_readdir	(void *);
 #define	ptyfs_readlink	genfs_eopnotsupp
 #define	ptyfs_abortop	genfs_abortop
 int	ptyfs_reclaim	(void *);
+int	ptyfs_inactive	(void *);
 #define	ptyfs_lock	genfs_lock
 #define	ptyfs_unlock	genfs_unlock
 #define	ptyfs_bmap	genfs_badop
@@ -192,7 +193,7 @@ const struct vnodeopv_entry_desc ptyfs_v
 	{ &vop_readdir_desc, ptyfs_readdir },		/* readdir */
 	{ &vop_readlink_desc, ptyfs_readlink },		/* readlink */
 	{ &vop_abortop_desc, ptyfs_abortop },		/* abortop */
-	{ &vop_inactive_desc, spec_inactive },		/* inactive */
+	{ &vop_inactive_desc, ptyfs_inactive },		/* inactive */
 	{ &vop_reclaim_desc, ptyfs_reclaim },		/* reclaim */
 	{ &vop_lock_desc, ptyfs_lock },			/* lock */
 	{ &vop_unlock_desc, ptyfs_unlock },		/* unlock */
@@ -225,6 +226,28 @@ ptyfs_reclaim(void *v)
 	return ptyfs_freevp(ap->a_vp);
 }
 
+int
+ptyfs_inactive(void *v)
+{
+	struct vop_inactive_args /* {
+		struct vnode *a_vp;
+		bool *a_recycle;
+	} */ *ap = v;
+	struct vnode *vp = ap->a_vp;
+	struct ptyfsnode *ptyfs = VTOPTYFS(vp);
+
+	switch (ptyfs->ptyfs_type) {
+	case PTYFSpts:
+	case PTYFSptc:
+		/* Emulate file deletion for call reclaim(). */
+		*ap->a_recycle = true;
+		break;
+	default:
+		break;
+	}
+	return spec_inactive(v);
+}
+
 /*
  * Return POSIX pathconf information applicable to special devices.
  */

Reply via email to