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
548
549
550
551
552
553
554
555
556
557struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
558 void *priv)
559{
560 struct dentry *dentry;
561 struct super_block *sb = pts_sb_from_inode(ptmx_inode);
562 struct inode *inode;
563 struct dentry *root = sb->s_root;
564 struct pts_fs_info *fsi = DEVPTS_SB(sb);
565 struct pts_mount_opts *opts = &fsi->mount_opts;
566 char s[12];
567
568 inode = new_inode(sb);
569 if (!inode)
570 return ERR_PTR(-ENOMEM);
571
572 inode->i_ino = index + 3;
573 inode->i_uid = opts->setuid ? opts->uid : current_fsuid();
574 inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
575 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
576 init_special_inode(inode, S_IFCHR|opts->mode, device);
577 inode->i_private = priv;
578
579 sprintf(s, "%d", index);
580
581 mutex_lock(&root->d_inode->i_mutex);
582
583 dentry = d_alloc_name(root, s);
584 if (dentry) {
585 d_add(dentry, inode);
586 fsnotify_create(root->d_inode, dentry);
587 } else {
588 iput(inode);
589 inode = ERR_PTR(-ENOMEM);
590 }
591
592 mutex_unlock(&root->d_inode->i_mutex);
593
594 return inode;
595}
596
597
598
599
600
601
602
603void *devpts_get_priv(struct inode *pts_inode)
604{
605 struct dentry *dentry;
606 void *priv = NULL;
607
608 BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
609
610
611 dentry = d_find_alias(pts_inode);
612 if (!dentry)
613 return NULL;
614
615 if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
616 priv = pts_inode->i_private;
617
618 dput(dentry);
619
620 return priv;
621}
622
623
624
625
626
627
628
629void devpts_pty_kill(struct inode *inode)
630{
631 struct super_block *sb = pts_sb_from_inode(inode);
632 struct dentry *root = sb->s_root;
633 struct dentry *dentry;
634
635 BUG_ON(inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
636
637 mutex_lock(&root->d_inode->i_mutex);
638
639 dentry = d_find_alias(inode);
640
641 drop_nlink(inode);
642 d_delete(dentry);
643 dput(dentry);
644 dput(dentry);
645
646 mutex_unlock(&root->d_inode->i_mutex);
647}
648
649static int __init init_devpts_fs(void)
650{
651 int err = register_filesystem(&devpts_fs_type);
652 struct ctl_table_header *table;
653
654 if (!err) {
655 table = register_sysctl_table(pty_root_table);
656 devpts_mnt = kern_mount(&devpts_fs_type);
657 if (IS_ERR(devpts_mnt)) {
658 err = PTR_ERR(devpts_mnt);
659 unregister_filesystem(&devpts_fs_type);
660 unregister_sysctl_table(table);
661 }
662 }
663 return err;
664}
665module_init(init_devpts_fs)
666