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