1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/fs.h>
16#include <linux/sched.h>
17#include <linux/namei.h>
18#include <linux/slab.h>
19#include <linux/mount.h>
20#include <linux/tty.h>
21#include <linux/mutex.h>
22#include <linux/magic.h>
23#include <linux/idr.h>
24#include <linux/devpts_fs.h>
25#include <linux/parser.h>
26#include <linux/fsnotify.h>
27#include <linux/seq_file.h>
28
29#define DEVPTS_DEFAULT_MODE 0600
30
31
32
33
34
35
36#define DEVPTS_DEFAULT_PTMX_MODE 0000
37#define PTMX_MINOR 2
38
39
40
41
42
43static int pty_limit = NR_UNIX98_PTY_DEFAULT;
44static int pty_reserve = NR_UNIX98_PTY_RESERVE;
45static int pty_limit_min;
46static int pty_limit_max = INT_MAX;
47static int pty_count;
48
49static struct ctl_table pty_table[] = {
50 {
51 .procname = "max",
52 .maxlen = sizeof(int),
53 .mode = 0644,
54 .data = &pty_limit,
55 .proc_handler = proc_dointvec_minmax,
56 .extra1 = &pty_limit_min,
57 .extra2 = &pty_limit_max,
58 }, {
59 .procname = "reserve",
60 .maxlen = sizeof(int),
61 .mode = 0644,
62 .data = &pty_reserve,
63 .proc_handler = proc_dointvec_minmax,
64 .extra1 = &pty_limit_min,
65 .extra2 = &pty_limit_max,
66 }, {
67 .procname = "nr",
68 .maxlen = sizeof(int),
69 .mode = 0444,
70 .data = &pty_count,
71 .proc_handler = proc_dointvec,
72 },
73 {}
74};
75
76static struct ctl_table pty_kern_table[] = {
77 {
78 .procname = "pty",
79 .mode = 0555,
80 .child = pty_table,
81 },
82 {}
83};
84
85static struct ctl_table pty_root_table[] = {
86 {
87 .procname = "kernel",
88 .mode = 0555,
89 .child = pty_kern_table,
90 },
91 {}
92};
93
94static DEFINE_MUTEX(allocated_ptys_lock);
95
96static struct vfsmount *devpts_mnt;
97
98struct pts_mount_opts {
99 int setuid;
100 int setgid;
101 kuid_t uid;
102 kgid_t gid;
103 umode_t mode;
104 umode_t ptmxmode;
105 int newinstance;
106 int max;
107};
108
109enum {
110 Opt_uid, Opt_gid, Opt_mode, Opt_ptmxmode, Opt_newinstance, Opt_max,
111 Opt_err
112};
113
114static const match_table_t tokens = {
115 {Opt_uid, "uid=%u"},
116 {Opt_gid, "gid=%u"},
117 {Opt_mode, "mode=%o"},
118#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
119 {Opt_ptmxmode, "ptmxmode=%o"},
120 {Opt_newinstance, "newinstance"},
121 {Opt_max, "max=%d"},
122#endif
123 {Opt_err, NULL}
124};
125
126struct pts_fs_info {
127 struct ida allocated_ptys;
128 struct pts_mount_opts mount_opts;
129 struct dentry *ptmx_dentry;
130};
131
132static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb)
133{
134 return sb->s_fs_info;
135}
136
137static inline struct super_block *pts_sb_from_inode(struct inode *inode)
138{
139#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
140 if (inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
141 return inode->i_sb;
142#endif
143 return devpts_mnt->mnt_sb;
144}
145
146#define PARSE_MOUNT 0
147#define PARSE_REMOUNT 1
148
149
150
151
152
153
154
155
156
157
158static int parse_mount_options(char *data, int op, struct pts_mount_opts *opts)
159{
160 char *p;
161 kuid_t uid;
162 kgid_t gid;
163
164 opts->setuid = 0;
165 opts->setgid = 0;
166 opts->uid = GLOBAL_ROOT_UID;
167 opts->gid = GLOBAL_ROOT_GID;
168 opts->mode = DEVPTS_DEFAULT_MODE;
169 opts->ptmxmode = DEVPTS_DEFAULT_PTMX_MODE;
170 opts->max = NR_UNIX98_PTY_MAX;
171
172
173 if (op == PARSE_MOUNT)
174 opts->newinstance = 0;
175
176 while ((p = strsep(&data, ",")) != NULL) {
177 substring_t args[MAX_OPT_ARGS];
178 int token;
179 int option;
180
181 if (!*p)
182 continue;
183
184 token = match_token(p, tokens, args);
185 switch (token) {
186 case Opt_uid:
187 if (match_int(&args[0], &option))
188 return -EINVAL;
189 uid = make_kuid(current_user_ns(), option);
190 if (!uid_valid(uid))
191 return -EINVAL;
192 opts->uid = uid;
193 opts->setuid = 1;
194 break;
195 case Opt_gid:
196 if (match_int(&args[0], &option))
197 return -EINVAL;
198 gid = make_kgid(current_user_ns(), option);
199 if (!gid_valid(gid))
200 return -EINVAL;
201 opts->gid = gid;
202 opts->setgid = 1;
203 break;
204 case Opt_mode:
205 if (match_octal(&args[0], &option))
206 return -EINVAL;
207 opts->mode = option & S_IALLUGO;
208 break;
209#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
210 case Opt_ptmxmode:
211 if (match_octal(&args[0], &option))
212 return -EINVAL;
213 opts->ptmxmode = option & S_IALLUGO;
214 break;
215 case Opt_newinstance:
216
217 if (op == PARSE_MOUNT)
218 opts->newinstance = 1;
219 break;
220 case Opt_max:
221 if (match_int(&args[0], &option) ||
222 option < 0 || option > NR_UNIX98_PTY_MAX)
223 return -EINVAL;
224 opts->max = option;
225 break;
226#endif
227 default:
228 printk(KERN_ERR "devpts: called with bogus options\n");
229 return -EINVAL;
230 }
231 }
232
233 return 0;
234}
235
236#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
237static int mknod_ptmx(struct super_block *sb)
238{
239 int mode;
240 int rc = -ENOMEM;
241 struct dentry *dentry;
242 struct inode *inode;
243 struct dentry *root = sb->s_root;
244 struct pts_fs_info *fsi = DEVPTS_SB(sb);
245 struct pts_mount_opts *opts = &fsi->mount_opts;
246
247 mutex_lock(&root->d_inode->i_mutex);
248
249
250 if (fsi->ptmx_dentry) {
251 rc = 0;
252 goto out;
253 }
254
255 dentry = d_alloc_name(root, "ptmx");
256 if (!dentry) {
257 printk(KERN_NOTICE "Unable to alloc dentry for ptmx node\n");
258 goto out;
259 }
260
261
262
263
264 inode = new_inode(sb);
265 if (!inode) {
266 printk(KERN_ERR "Unable to alloc inode for ptmx node\n");
267 dput(dentry);
268 goto out;
269 }
270
271 inode->i_ino = 2;
272 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
273
274 mode = S_IFCHR|opts->ptmxmode;
275 init_special_inode(inode, mode, MKDEV(TTYAUX_MAJOR, 2));
276
277 d_add(dentry, inode);
278
279 fsi->ptmx_dentry = dentry;
280 rc = 0;
281out:
282 mutex_unlock(&root->d_inode->i_mutex);
283 return rc;
284}
285
286static void update_ptmx_mode(struct pts_fs_info *fsi)
287{
288 struct inode *inode;
289 if (fsi->ptmx_dentry) {
290 inode = fsi->ptmx_dentry->d_inode;
291 inode->i_mode = S_IFCHR|fsi->mount_opts.ptmxmode;
292 }
293}
294#else
295static inline void update_ptmx_mode(struct pts_fs_info *fsi)
296{
297 return;
298}
299#endif
300
301static int devpts_remount(struct super_block *sb, int *flags, char *data)
302{
303 int err;
304 struct pts_fs_info *fsi = DEVPTS_SB(sb);
305 struct pts_mount_opts *opts = &fsi->mount_opts;
306
307 err = parse_mount_options(data, PARSE_REMOUNT, opts);
308
309
310
311
312
313
314
315 update_ptmx_mode(fsi);
316
317 return err;
318}
319
320static int devpts_show_options(struct seq_file *seq, struct dentry *root)
321{
322 struct pts_fs_info *fsi = DEVPTS_SB(root->d_sb);
323 struct pts_mount_opts *opts = &fsi->mount_opts;
324
325 if (opts->setuid)
326 seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, opts->uid));
327 if (opts->setgid)
328 seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, opts->gid));
329 seq_printf(seq, ",mode=%03o", opts->mode);
330#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
331 seq_printf(seq, ",ptmxmode=%03o", opts->ptmxmode);
332 if (opts->max < NR_UNIX98_PTY_MAX)
333 seq_printf(seq, ",max=%d", opts->max);
334#endif
335
336 return 0;
337}
338
339static const struct super_operations devpts_sops = {
340 .statfs = simple_statfs,
341 .remount_fs = devpts_remount,
342 .show_options = devpts_show_options,
343};
344
345static void *new_pts_fs_info(void)
346{
347 struct pts_fs_info *fsi;
348
349 fsi = kzalloc(sizeof(struct pts_fs_info), GFP_KERNEL);
350 if (!fsi)
351 return NULL;
352
353 ida_init(&fsi->allocated_ptys);
354 fsi->mount_opts.mode = DEVPTS_DEFAULT_MODE;
355 fsi->mount_opts.ptmxmode = DEVPTS_DEFAULT_PTMX_MODE;
356
357 return fsi;
358}
359
360static int
361devpts_fill_super(struct super_block *s, void *data, int silent)
362{
363 struct inode *inode;
364
365 s->s_blocksize = 1024;
366 s->s_blocksize_bits = 10;
367 s->s_magic = DEVPTS_SUPER_MAGIC;
368 s->s_op = &devpts_sops;
369 s->s_time_gran = 1;
370
371 s->s_fs_info = new_pts_fs_info();
372 if (!s->s_fs_info)
373 goto fail;
374
375 inode = new_inode(s);
376 if (!inode)
377 goto fail;
378 inode->i_ino = 1;
379 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
380 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
381 inode->i_op = &simple_dir_inode_operations;
382 inode->i_fop = &simple_dir_operations;
383 set_nlink(inode, 2);
384
385 s->s_root = d_make_root(inode);
386 if (s->s_root)
387 return 0;
388
389 printk(KERN_ERR "devpts: get root dentry failed\n");
390
391fail:
392 return -ENOMEM;
393}
394
395#ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
396static int compare_init_pts_sb(struct super_block *s, void *p)
397{
398 if (devpts_mnt)
399 return devpts_mnt->mnt_sb == s;
400 return 0;
401}
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430static struct dentry *devpts_mount(struct file_system_type *fs_type,
431 int flags, const char *dev_name, void *data)
432{
433 int error;
434 struct pts_mount_opts opts;
435 struct super_block *s;
436
437 error = parse_mount_options(data, PARSE_MOUNT, &opts);
438 if (error)
439 return ERR_PTR(error);
440
441 if (opts.newinstance)
442 s = sget(fs_type, NULL, set_anon_super, flags, NULL);
443 else
444 s = sget(fs_type, compare_init_pts_sb, set_anon_super, flags,
445 NULL);
446
447 if (IS_ERR(s))
448 return ERR_CAST(s);
449
450 if (!s->s_root) {
451 error = devpts_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
452 if (error)
453 goto out_undo_sget;
454 s->s_flags |= MS_ACTIVE;
455 }
456
457 memcpy(&(DEVPTS_SB(s))->mount_opts, &opts, sizeof(opts));
458
459 error = mknod_ptmx(s);
460 if (error)
461 goto out_undo_sget;
462
463 return dget(s->s_root);
464
465out_undo_sget:
466 deactivate_locked_super(s);
467 return ERR_PTR(error);
468}
469
470#else
471
472
473
474
475static struct dentry *devpts_mount(struct file_system_type *fs_type, int flags,
476 const char *dev_name, void *data)
477{
478 return mount_single(fs_type, flags, data, devpts_fill_super);
479}
480#endif
481
482static void devpts_kill_sb(struct super_block *sb)
483{
484 struct pts_fs_info *fsi = DEVPTS_SB(sb);
485
486 kfree(fsi);
487 kill_litter_super(sb);
488}
489
490static struct file_system_type devpts_fs_type = {
491 .name = "devpts",
492 .mount = devpts_mount,
493 .kill_sb = devpts_kill_sb,
494};
495
496
497
498
499
500
501int devpts_new_index(struct inode *ptmx_inode)
502{
503 struct super_block *sb = pts_sb_from_inode(ptmx_inode);
504 struct pts_fs_info *fsi = DEVPTS_SB(sb);
505 int index;
506 int ida_ret;
507
508retry:
509 if (!ida_pre_get(&fsi->allocated_ptys, GFP_KERNEL))
510 return -ENOMEM;
511
512 mutex_lock(&allocated_ptys_lock);
513 if (pty_count >= pty_limit -
514 (fsi->mount_opts.newinstance ? pty_reserve : 0)) {
515 mutex_unlock(&allocated_ptys_lock);
516 return -ENOSPC;
517 }
518
519 ida_ret = ida_get_new(&fsi->allocated_ptys, &index);
520 if (ida_ret < 0) {
521 mutex_unlock(&allocated_ptys_lock);
522 if (ida_ret == -EAGAIN)
523 goto retry;
524 return -EIO;
525 }
526
527 if (index >= fsi->mount_opts.max) {
528 ida_remove(&fsi->allocated_ptys, index);
529 mutex_unlock(&allocated_ptys_lock);
530 return -ENOSPC;
531 }
532 pty_count++;
533 mutex_unlock(&allocated_ptys_lock);
534 return index;
535}
536
537void devpts_kill_index(struct inode *ptmx_inode, int idx)
538{
539 struct super_block *sb = pts_sb_from_inode(ptmx_inode);
540 struct pts_fs_info *fsi = DEVPTS_SB(sb);
541
542 mutex_lock(&allocated_ptys_lock);
543 ida_remove(&fsi->allocated_ptys, idx);
544 pty_count--;
545 mutex_unlock(&allocated_ptys_lock);
546}
547
548int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
549{
550
551 int number = tty->index;
552 struct tty_driver *driver = tty->driver;
553 dev_t device = MKDEV(driver->major, driver->minor_start+number);
554 struct dentry *dentry;
555 struct super_block *sb = pts_sb_from_inode(ptmx_inode);
556 struct inode *inode = new_inode(sb);
557 struct dentry *root = sb->s_root;
558 struct pts_fs_info *fsi = DEVPTS_SB(sb);
559 struct pts_mount_opts *opts = &fsi->mount_opts;
560 int ret = 0;
561 char s[12];
562
563
564 BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY);
565 BUG_ON(driver->subtype != PTY_TYPE_SLAVE);
566
567 if (!inode)
568 return -ENOMEM;
569
570 inode->i_ino = number + 3;
571 inode->i_uid = opts->setuid ? opts->uid : current_fsuid();
572 inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
573 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
574 init_special_inode(inode, S_IFCHR|opts->mode, device);
575 inode->i_private = tty;
576 tty->driver_data = inode;
577
578 sprintf(s, "%d", number);
579
580 mutex_lock(&root->d_inode->i_mutex);
581
582 dentry = d_alloc_name(root, s);
583 if (dentry) {
584 d_add(dentry, inode);
585 fsnotify_create(root->d_inode, dentry);
586 } else {
587 iput(inode);
588 ret = -ENOMEM;
589 }
590
591 mutex_unlock(&root->d_inode->i_mutex);
592
593 return ret;
594}
595
596struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
597{
598 struct dentry *dentry;
599 struct tty_struct *tty;
600
601 BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
602
603
604 dentry = d_find_alias(pts_inode);
605 if (!dentry)
606 return NULL;
607
608 tty = NULL;
609 if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
610 tty = (struct tty_struct *)pts_inode->i_private;
611
612 dput(dentry);
613
614 return tty;
615}
616
617void devpts_pty_kill(struct tty_struct *tty)
618{
619 struct inode *inode = tty->driver_data;
620 struct super_block *sb = pts_sb_from_inode(inode);
621 struct dentry *root = sb->s_root;
622 struct dentry *dentry;
623
624 BUG_ON(inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
625
626 mutex_lock(&root->d_inode->i_mutex);
627
628 dentry = d_find_alias(inode);
629
630 drop_nlink(inode);
631 d_delete(dentry);
632 dput(dentry);
633 dput(dentry);
634
635 mutex_unlock(&root->d_inode->i_mutex);
636}
637
638static int __init init_devpts_fs(void)
639{
640 int err = register_filesystem(&devpts_fs_type);
641 struct ctl_table_header *table;
642
643 if (!err) {
644 table = register_sysctl_table(pty_root_table);
645 devpts_mnt = kern_mount(&devpts_fs_type);
646 if (IS_ERR(devpts_mnt)) {
647 err = PTR_ERR(devpts_mnt);
648 unregister_filesystem(&devpts_fs_type);
649 unregister_sysctl_table(table);
650 }
651 }
652 return err;
653}
654module_init(init_devpts_fs)
655