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. */