Sun Mar 15 16:43:55 2009 UTC ()
Add a chroot flag, so that ptyfs can be mounted in a chrooted environment.
XXX: This is a hack, in reality we should allow multiple ptyfs mounts.


(christos)
diff -r1.7 -r1.8 src/sys/fs/ptyfs/ptyfs.h
diff -r1.38 -r1.39 src/sys/fs/ptyfs/ptyfs_vfsops.c

cvs diff -r1.7 -r1.8 src/sys/fs/ptyfs/ptyfs.h (expand / switch to unified diff)

--- src/sys/fs/ptyfs/ptyfs.h 2008/06/28 01:34:05 1.7
+++ src/sys/fs/ptyfs/ptyfs.h 2009/03/15 16:43:55 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ptyfs.h,v 1.7 2008/06/28 01:34:05 rumble Exp $ */ 1/* $NetBSD: ptyfs.h,v 1.8 2009/03/15 16:43:55 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1993 4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Jan-Simon Pendry. 8 * Jan-Simon Pendry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -98,39 +98,46 @@ struct ptyfsnode { @@ -98,39 +98,46 @@ struct ptyfsnode {
98#define PTYFS_MODIFY 2 98#define PTYFS_MODIFY 2
99#define PTYFS_CHANGE 4 99#define PTYFS_CHANGE 4
100 /* Attribute information */ 100 /* Attribute information */
101 uid_t ptyfs_uid; 101 uid_t ptyfs_uid;
102 gid_t ptyfs_gid; 102 gid_t ptyfs_gid;
103 mode_t ptyfs_mode; 103 mode_t ptyfs_mode;
104 int ptyfs_flags; 104 int ptyfs_flags;
105 struct timespec ptyfs_ctime, ptyfs_mtime, ptyfs_atime, ptyfs_birthtime; 105 struct timespec ptyfs_ctime, ptyfs_mtime, ptyfs_atime, ptyfs_birthtime;
106}; 106};
107 107
108struct ptyfsmount { 108struct ptyfsmount {
109 gid_t pmnt_gid; 109 gid_t pmnt_gid;
110 mode_t pmnt_mode; 110 mode_t pmnt_mode;
 111 int pmnt_flags;
111}; 112};
112 113
113#define VFSTOPTY(mp) ((struct ptyfsmount *)(mp)->mnt_data) 114#define VFSTOPTY(mp) ((struct ptyfsmount *)(mp)->mnt_data)
114 115
115#endif /* _KERNEL */ 116#endif /* _KERNEL */
116 117
117struct ptyfs_args { 118struct ptyfs_args {
118 int version; 119 int version;
119 gid_t gid; 120 gid_t gid;
120 mode_t mode; 121 mode_t mode;
 122 int flags;
121}; 123};
122 124
123#define PTYFS_ARGSVERSION 1 125#define PTYFS_ARGSVERSION 2
 126
 127#define PTYFSMNT_CHROOT 0x01
 128
 129#define PTYFSMNT_BITS "\177\20" \
 130 "b\00chroot\0"
124 131
125/* 132/*
126 * Kernel stuff follows 133 * Kernel stuff follows
127 */ 134 */
128#ifdef _KERNEL 135#ifdef _KERNEL
129 136
130#define UIO_MX 32 137#define UIO_MX 32
131 138
132#define PTYFS_FILENO(pty, type) \ 139#define PTYFS_FILENO(pty, type) \
133 ((type == PTYFSroot) ? 2 : \ 140 ((type == PTYFSroot) ? 2 : \
134 ((((pty) + 1) * 2 + (((type) == PTYFSpts) ? 1 : 2)))) 141 ((((pty) + 1) * 2 + (((type) == PTYFSpts) ? 1 : 2))))
135 142
136#define PTYFS_MAKEDEV(ptyfs) \ 143#define PTYFS_MAKEDEV(ptyfs) \

cvs diff -r1.38 -r1.39 src/sys/fs/ptyfs/ptyfs_vfsops.c (expand / switch to unified diff)

--- src/sys/fs/ptyfs/ptyfs_vfsops.c 2009/01/11 02:45:51 1.38
+++ src/sys/fs/ptyfs/ptyfs_vfsops.c 2009/03/15 16:43:55 1.39
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ptyfs_vfsops.c,v 1.38 2009/01/11 02:45:51 christos Exp $ */ 1/* $NetBSD: ptyfs_vfsops.c,v 1.39 2009/03/15 16:43:55 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1992, 1993, 1995 4 * Copyright (c) 1992, 1993, 1995
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software donated to Berkeley by 7 * This code is derived from software donated to Berkeley by
8 * Jan-Simon Pendry. 8 * Jan-Simon Pendry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 */ 34 */
35 35
36/* 36/*
37 * Pseudo-tty Filesystem 37 * Pseudo-tty Filesystem
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__KERNEL_RCSID(0, "$NetBSD: ptyfs_vfsops.c,v 1.38 2009/01/11 02:45:51 christos Exp $"); 41__KERNEL_RCSID(0, "$NetBSD: ptyfs_vfsops.c,v 1.39 2009/03/15 16:43:55 christos Exp $");
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/sysctl.h> 45#include <sys/sysctl.h>
46#include <sys/conf.h> 46#include <sys/conf.h>
47#include <sys/proc.h> 47#include <sys/proc.h>
48#include <sys/vnode.h> 48#include <sys/vnode.h>
49#include <sys/mount.h> 49#include <sys/mount.h>
50#include <sys/namei.h> 50#include <sys/namei.h>
51#include <sys/stat.h> 51#include <sys/stat.h>
52#include <sys/dirent.h> 52#include <sys/dirent.h>
53#include <sys/malloc.h> 53#include <sys/malloc.h>
54#include <sys/syslog.h> 54#include <sys/syslog.h>
@@ -81,41 +81,73 @@ static void ptyfs__getvattr(struct ptm_p @@ -81,41 +81,73 @@ static void ptyfs__getvattr(struct ptm_p
81/* 81/*
82 * ptm glue: When we mount, we make ptm point to us. 82 * ptm glue: When we mount, we make ptm point to us.
83 */ 83 */
84struct ptm_pty *ptyfs_save_ptm; 84struct ptm_pty *ptyfs_save_ptm;
85static int ptyfs_count; 85static int ptyfs_count;
86 86
87struct ptm_pty ptm_ptyfspty = { 87struct ptm_pty ptm_ptyfspty = {
88 ptyfs__allocvp, 88 ptyfs__allocvp,
89 ptyfs__makename, 89 ptyfs__makename,
90 ptyfs__getvattr, 90 ptyfs__getvattr,
91 NULL 91 NULL
92}; 92};
93 93
 94static const char *
 95ptyfs__getpath(struct lwp *l, const struct mount *mp)
 96{
 97#define MAXBUF (sizeof(mp->mnt_stat.f_mntonname) + 32)
 98 struct cwdinfo *cwdi = l->l_proc->p_cwdi;
 99 char *buf;
 100 const char *rv;
 101 size_t len;
 102 char *bp;
 103 int error;
 104 struct ptyfsmount *pmnt = mp->mnt_data;
 105
 106 rv = mp->mnt_stat.f_mntonname;
 107 if (cwdi->cwdi_rdir == NULL ||
 108 (pmnt->pmnt_flags & PTYFSMNT_CHROOT) == 0)
 109 return rv;
 110
 111 buf = malloc(MAXBUF, M_TEMP, M_WAITOK);
 112 bp = buf + MAXBUF;
 113 *--bp = '\0';
 114 error = getcwd_common(cwdi->cwdi_rdir, rootvnode, &bp,
 115 buf, MAXBUF / 2, 0, l);
 116 if (error) /* XXX */
 117 goto out;
 118
 119 len = strlen(bp);
 120 if (len < sizeof(mp->mnt_stat.f_mntonname)) /* XXX */
 121 rv += len;
 122out:
 123 free(buf, M_TEMP);
 124 return rv;
 125}
 126
94static int 127static int
95ptyfs__makename(struct ptm_pty *pt, struct lwp *l, char *tbuf, size_t bufsiz, 128ptyfs__makename(struct ptm_pty *pt, struct lwp *l, char *tbuf, size_t bufsiz,
96 dev_t dev, char ms) 129 dev_t dev, char ms)
97{ 130{
98 struct mount *mp = pt->arg; 131 struct mount *mp = pt->arg;
99 size_t len; 132 size_t len;
100 133
101 switch (ms) { 134 switch (ms) {
102 case 'p': 135 case 'p':
103 /* We don't provide access to the master, should we? */ 136 /* We don't provide access to the master, should we? */
104 len = snprintf(tbuf, bufsiz, "/dev/null"); 137 len = snprintf(tbuf, bufsiz, "/dev/null");
105 break; 138 break;
106 case 't': 139 case 't':
107 len = snprintf(tbuf, bufsiz, "%s/%llu", 140 len = snprintf(tbuf, bufsiz, "%s/%llu", ptyfs__getpath(l, mp),
108 mp->mnt_stat.f_mntonname, 
109 (unsigned long long)minor(dev)); 141 (unsigned long long)minor(dev));
110 break; 142 break;
111 default: 143 default:
112 return EINVAL; 144 return EINVAL;
113 } 145 }
114 146
115 return len >= bufsiz ? ENOSPC : 0; 147 return len >= bufsiz ? ENOSPC : 0;
116} 148}
117 149
118 150
119static int 151static int
120/*ARGSUSED*/ 152/*ARGSUSED*/
121ptyfs__allocvp(struct ptm_pty *pt, struct lwp *l, struct vnode **vpp, 153ptyfs__allocvp(struct ptm_pty *pt, struct lwp *l, struct vnode **vpp,
@@ -189,48 +221,57 @@ ptyfs_mount(struct mount *mp, const char @@ -189,48 +221,57 @@ ptyfs_mount(struct mount *mp, const char
189 221
190 if (*data_len < sizeof *args) 222 if (*data_len < sizeof *args)
191 return EINVAL; 223 return EINVAL;
192 224
193 if (UIO_MX & (UIO_MX - 1)) { 225 if (UIO_MX & (UIO_MX - 1)) {
194 log(LOG_ERR, "ptyfs: invalid directory entry size"); 226 log(LOG_ERR, "ptyfs: invalid directory entry size");
195 return EINVAL; 227 return EINVAL;
196 } 228 }
197 229
198 if (mp->mnt_flag & MNT_GETARGS) { 230 if (mp->mnt_flag & MNT_GETARGS) {
199 pmnt = VFSTOPTY(mp); 231 pmnt = VFSTOPTY(mp);
200 if (pmnt == NULL) 232 if (pmnt == NULL)
201 return EIO; 233 return EIO;
202 args->version = PTYFS_ARGSVERSION; 
203 args->mode = pmnt->pmnt_mode; 234 args->mode = pmnt->pmnt_mode;
204 args->gid = pmnt->pmnt_gid; 235 args->gid = pmnt->pmnt_gid;
205 *data_len = sizeof *args; 236 if (args->version >= PTYFS_ARGSVERSION) {
 237 args->flags = pmnt->pmnt_flags;
 238 *data_len = sizeof *args;
 239 } else {
 240 *data_len =
 241 sizeof(struct { int f; gid_t g; mode_t m; });
 242 }
206 return 0; 243 return 0;
207 } 244 }
208 245
209 /* Don't allow more than one mount */ 246 /* Don't allow more than one mount */
210 if (ptyfs_count) 247 if (ptyfs_count)
211 return EBUSY; 248 return EBUSY;
212 249
213 if (mp->mnt_flag & MNT_UPDATE) 250 if (mp->mnt_flag & MNT_UPDATE)
214 return EOPNOTSUPP; 251 return EOPNOTSUPP;
215 252
216 if (args->version != PTYFS_ARGSVERSION) 253 if (args->version != PTYFS_ARGSVERSION)
217 return EINVAL; 254 return EINVAL;
218 255
219 pmnt = malloc(sizeof(struct ptyfsmount), M_PTYFSMNT, M_WAITOK); 256 pmnt = malloc(sizeof(struct ptyfsmount), M_PTYFSMNT, M_WAITOK);
220 257
221 mp->mnt_data = pmnt; 258 mp->mnt_data = pmnt;
222 pmnt->pmnt_gid = args->gid; 259 pmnt->pmnt_gid = args->gid;
223 pmnt->pmnt_mode = args->mode; 260 pmnt->pmnt_mode = args->mode;
 261 if (args->version >= PTYFS_ARGSVERSION)
 262 pmnt->pmnt_flags = args->flags;
 263 else
 264 pmnt->pmnt_flags = 0;
224 mp->mnt_flag |= MNT_LOCAL; 265 mp->mnt_flag |= MNT_LOCAL;
225 vfs_getnewfsid(mp); 266 vfs_getnewfsid(mp);
226 267
227 if ((error = set_statvfs_info(path, UIO_USERSPACE, "ptyfs", 268 if ((error = set_statvfs_info(path, UIO_USERSPACE, "ptyfs",
228 UIO_SYSSPACE, mp->mnt_op->vfs_name, mp, l)) != 0) { 269 UIO_SYSSPACE, mp->mnt_op->vfs_name, mp, l)) != 0) {
229 free(pmnt, M_PTYFSMNT); 270 free(pmnt, M_PTYFSMNT);
230 return error; 271 return error;
231 } 272 }
232 273
233 /* Point pty access to us */ 274 /* Point pty access to us */
234 275
235 ptm_ptyfspty.arg = mp; 276 ptm_ptyfspty.arg = mp;
236 ptyfs_save_ptm = pty_sethandler(&ptm_ptyfspty); 277 ptyfs_save_ptm = pty_sethandler(&ptm_ptyfspty);