tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Enhance ptyfs to handle multiple instances.
Some misspelling corrections.
fs/ptyfs/ptyfs.h | 2 +
fs/ptyfs/ptyfs_vfsops.c | 63 ++++++++++++++++++++++++++++++++++++++++++------
fs/ptyfs/ptyfs_vnops.c | 25 ++++++++++++++++++-
kern/tty_bsdpty.c | 11 +++++++-
kern/tty_ptm.c | 45 ++++++++++++++++------------------
kern/tty_pty.c | 4 +--
sys/pty.h | 4 +--
7 files changed, 117 insertions(+), 37 deletions(-)
Ilya.
Index: fs/ptyfs/ptyfs.h
===================================================================
RCS file: /cvsil/nbcur/src/sys/fs/ptyfs/ptyfs.h,v
retrieving revision 1.6
diff -u -p -r1.6 ptyfs.h
--- fs/ptyfs/ptyfs.h 24 Mar 2014 20:48:08 -0000 1.6
+++ fs/ptyfs/ptyfs.h 4 Apr 2014 10:37:57 -0000
@@ -106,6 +106,8 @@ struct ptyfsnode {
};
struct ptyfsmount {
+ LIST_ENTRY(ptyfsmount) pmnt_le;
+ struct mount *pmnt_mp;
gid_t pmnt_gid;
mode_t pmnt_mode;
int pmnt_flags;
Index: fs/ptyfs/ptyfs_vfsops.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/fs/ptyfs/ptyfs_vfsops.c,v
retrieving revision 1.13
diff -u -p -r1.13 ptyfs_vfsops.c
--- fs/ptyfs/ptyfs_vfsops.c 28 Mar 2014 10:53:57 -0000 1.13
+++ fs/ptyfs/ptyfs_vfsops.c 4 Apr 2014 10:37:57 -0000
@@ -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 LIST_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;
+
+ LIST_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)
{
+ LIST_INIT(&ptyfs_head);
malloc_type_attach(M_PTYFSMNT);
malloc_type_attach(M_PTYFSTMP);
ptyfs_hashinit();
@@ -218,7 +256,7 @@ ptyfs_mount(struct mount *mp, const char
{
struct lwp *l = curlwp;
int error = 0;
- struct ptyfsmount *pmnt;
+ struct ptyfsmount *pmnt, *pmnt_next;
struct ptyfs_args *args = data;
if (*data_len != sizeof *args && *data_len != OSIZE)
@@ -274,12 +312,17 @@ 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;
+ if (ptyfs_count++ == 0) {
+ LIST_INSERT_HEAD(&ptyfs_head, pmnt, pmnt_le);
+ /* Point pty access to us */
ptyfs_save_ptm = pty_sethandler(&ptm_ptyfspty);
+ } else {
+ pmnt_next = LIST_FIRST(&ptyfs_head);
+ while(LIST_NEXT(pmnt_next, pmnt_le) != NULL)
+ pmnt_next = LIST_NEXT(pmnt_next, pmnt_le);
+ LIST_INSERT_AFTER(pmnt_next, pmnt, pmnt_le);
}
- ptyfs_count++;
return 0;
}
@@ -296,6 +339,7 @@ ptyfs_unmount(struct mount *mp, int mntf
{
int error;
int flags = 0;
+ struct ptyfsmount *pmnt;
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
@@ -308,8 +352,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;
}
+ LIST_FOREACH(pmnt, &ptyfs_head, pmnt_le) {
+ if (pmnt->pmnt_mp == mp) {
+ LIST_REMOVE(pmnt, pmnt_le);
+ break;
+ }
+ }
/*
* Finally, throw away the ptyfsmount structure
Index: fs/ptyfs/ptyfs_vnops.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/fs/ptyfs/ptyfs_vnops.c,v
retrieving revision 1.5
diff -u -p -r1.5 ptyfs_vnops.c
--- fs/ptyfs/ptyfs_vnops.c 28 Mar 2014 10:53:58 -0000 1.5
+++ fs/ptyfs/ptyfs_vnops.c 4 Apr 2014 10:37:57 -0000
@@ -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.
*/
Index: kern/tty_bsdpty.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/kern/tty_bsdpty.c,v
retrieving revision 1.5
diff -u -p -r1.5 tty_bsdpty.c
--- kern/tty_bsdpty.c 28 Mar 2014 10:53:58 -0000 1.5
+++ kern/tty_bsdpty.c 4 Apr 2014 10:37:58 -0000
@@ -74,12 +74,13 @@ static int pty_makename(struct mount *,
static int pty_allocvp(struct mount *, struct lwp *, struct vnode **,
dev_t, char);
static void pty_getvattr(struct mount *, struct lwp *, struct vattr *);
+static int pty__getmp(struct lwp *, struct mount **);
struct ptm_pty ptm_bsdpty = {
pty_allocvp,
pty_makename,
pty_getvattr,
- NULL
+ pty__getmp,
};
static int
@@ -152,5 +153,13 @@ pty_getvattr(struct mount *mp, struct lw
vattr->va_gid = TTY_GID;
vattr->va_mode = TTY_PERM;
}
+
+static int
+pty__getmp(struct lwp *l __unused, struct mount **mpp)
+{
+ *mpp = 0;
+ return 0;
+}
+
#endif /* COMPAT_BSDPTY */
#endif /* NO_DEV_PTM */
Index: kern/tty_ptm.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/kern/tty_ptm.c,v
retrieving revision 1.7
diff -u -p -r1.7 tty_ptm.c
--- kern/tty_ptm.c 28 Mar 2014 10:53:58 -0000 1.7
+++ kern/tty_ptm.c 4 Apr 2014 10:37:58 -0000
@@ -91,31 +91,12 @@ static int pty_alloc_slave(struct lwp *,
void ptmattach(int);
int
-ptyfs_getmp(struct lwp *l, struct mount **mpp) {
- struct cwdinfo *cwdi = l->l_proc->p_cwdi;
- struct mount *mp;
-
+pty_getmp(struct lwp *l, struct mount **mpp)
+{
if (ptm == NULL)
return EOPNOTSUPP;
- if (ptm->arg == NULL) { /* BSDPTY */
- *mpp = NULL;
- return 0;
- }
-
- mp = ptm->arg; /* PTYFS */
-
- 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;
+ return (*ptm->getmp)(l, mpp);
}
dev_t
@@ -193,6 +174,22 @@ retry:
error = EOPNOTSUPP;
goto bad;
}
+ /*
+ * XXX Since PTYFS has now multiple instance support, if we mounted
+ * more than one PTYFS we must check here the ptyfs_used_tbl, to find
+ * out if the ptyfsnode is under the appropriate mount and skip the
+ * node if not, because the pty could has been released, but
+ * ptyfs_reclaim didn't get a chance to release the corresponding
+ * node other mount point yet.
+ *
+ * It's important to have only one mount point's ptyfsnode for each
+ * appropriate device in ptyfs_used_tbl, else we will have a security
+ * problem, because every entry will have access to this device.
+ *
+ * Also we will not have not efficient vnode and memory usage.
+ * You can test this by changing a_recycle from true to false
+ * in ptyfs_inactive.
+ */
if ((error = (*ptm->allocvp)(mp, l, &vp, *dev, 'p')) != 0) {
DPRINTF(("pty_allocvp %d\n", error));
goto bad;
@@ -356,7 +353,7 @@ ptmopen(dev_t dev, int flag, int mode, s
switch(minor(dev)) {
case 0: /* /dev/ptmx */
case 2: /* /emul/linux/dev/ptmx */
- if ((error = ptyfs_getmp(l, &mp)) != 0)
+ if ((error = pty_getmp(l, &mp)) != 0)
return error;
if ((error = pty_alloc_master(l, &fd, &ttydev, mp)) != 0)
return error;
@@ -404,7 +401,7 @@ ptmioctl(dev_t dev, u_long cmd, void *da
error = 0;
switch (cmd) {
case TIOCPTMGET:
- if ((error = ptyfs_getmp(l, &mp)) != 0)
+ if ((error = pty_getmp(l, &mp)) != 0)
return error;
if ((error = pty_alloc_master(l, &cfd, &newdev, mp)) != 0)
Index: kern/tty_pty.c
===================================================================
RCS file: /cvsil/nbcur/src/sys/kern/tty_pty.c,v
retrieving revision 1.4
diff -u -p -r1.4 tty_pty.c
--- kern/tty_pty.c 31 Mar 2014 06:54:23 -0000 1.4
+++ kern/tty_pty.c 4 Apr 2014 10:37:58 -0000
@@ -1075,7 +1075,7 @@ ptyioctl(dev_t dev, u_long cmd, void *da
#ifndef NO_DEV_PTM
/* Allow getting the name from either the master or the slave */
if (cmd == TIOCPTSNAME) {
- if ((error = ptyfs_getmp(l, &mp)) != 0)
+ if ((error = pty_getmp(l, &mp)) != 0)
return error;
return pty_fill_ptmget(l, dev, -1, -1, data, mp);
}
@@ -1086,7 +1086,7 @@ ptyioctl(dev_t dev, u_long cmd, void *da
switch (cmd) {
#ifndef NO_DEV_PTM
case TIOCGRANTPT:
- if ((error = ptyfs_getmp(l, &mp)) != 0)
+ if ((error = pty_getmp(l, &mp)) != 0)
return error;
return pty_grant_slave(l, dev, mp);
#endif
Index: sys/pty.h
===================================================================
RCS file: /cvsil/nbcur/src/sys/sys/pty.h,v
retrieving revision 1.4
diff -u -p -r1.4 pty.h
--- sys/pty.h 28 Mar 2014 10:53:58 -0000 1.4
+++ sys/pty.h 4 Apr 2014 10:37:59 -0000
@@ -41,7 +41,7 @@ int pty_grant_slave(struct lwp *, dev_t,
dev_t pty_makedev(char, int);
int pty_vn_open(struct vnode *, struct lwp *);
struct ptm_pty *pty_sethandler(struct ptm_pty *);
-int ptyfs_getmp(struct lwp *, struct mount **);
+int pty_getmp(struct lwp *, struct mount **);
/*
* Ptm_pty is used for switch ptm{x} driver between BSDPTY, PTYFS.
@@ -53,7 +53,7 @@ struct ptm_pty {
char);
int (*makename)(struct mount *, struct lwp *, char *, size_t, dev_t,
char);
void (*getvattr)(struct mount *, struct lwp *, struct vattr *);
- void *arg;
+ int (*getmp)(struct lwp *, struct mount **);
};
#ifdef COMPAT_BSDPTY
Home |
Main Index |
Thread Index |
Old Index