aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/devpts/inode.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 49d879d911b1..b793e6e3c21e 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -34,13 +34,13 @@ static DEFINE_MUTEX(allocated_ptys_lock);
34 34
35static struct vfsmount *devpts_mnt; 35static struct vfsmount *devpts_mnt;
36 36
37static struct { 37struct pts_mount_opts {
38 int setuid; 38 int setuid;
39 int setgid; 39 int setgid;
40 uid_t uid; 40 uid_t uid;
41 gid_t gid; 41 gid_t gid;
42 umode_t mode; 42 umode_t mode;
43} config = {.mode = DEVPTS_DEFAULT_MODE}; 43};
44 44
45enum { 45enum {
46 Opt_uid, Opt_gid, Opt_mode, 46 Opt_uid, Opt_gid, Opt_mode,
@@ -56,6 +56,7 @@ static const match_table_t tokens = {
56 56
57struct pts_fs_info { 57struct pts_fs_info {
58 struct ida allocated_ptys; 58 struct ida allocated_ptys;
59 struct pts_mount_opts mount_opts;
59}; 60};
60 61
61static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb) 62static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb)
@@ -74,12 +75,14 @@ static inline struct super_block *pts_sb_from_inode(struct inode *inode)
74static int devpts_remount(struct super_block *sb, int *flags, char *data) 75static int devpts_remount(struct super_block *sb, int *flags, char *data)
75{ 76{
76 char *p; 77 char *p;
78 struct pts_fs_info *fsi = DEVPTS_SB(sb);
79 struct pts_mount_opts *opts = &fsi->mount_opts;
77 80
78 config.setuid = 0; 81 opts->setuid = 0;
79 config.setgid = 0; 82 opts->setgid = 0;
80 config.uid = 0; 83 opts->uid = 0;
81 config.gid = 0; 84 opts->gid = 0;
82 config.mode = DEVPTS_DEFAULT_MODE; 85 opts->mode = DEVPTS_DEFAULT_MODE;
83 86
84 while ((p = strsep(&data, ",")) != NULL) { 87 while ((p = strsep(&data, ",")) != NULL) {
85 substring_t args[MAX_OPT_ARGS]; 88 substring_t args[MAX_OPT_ARGS];
@@ -94,19 +97,19 @@ static int devpts_remount(struct super_block *sb, int *flags, char *data)
94 case Opt_uid: 97 case Opt_uid:
95 if (match_int(&args[0], &option)) 98 if (match_int(&args[0], &option))
96 return -EINVAL; 99 return -EINVAL;
97 config.uid = option; 100 opts->uid = option;
98 config.setuid = 1; 101 opts->setuid = 1;
99 break; 102 break;
100 case Opt_gid: 103 case Opt_gid:
101 if (match_int(&args[0], &option)) 104 if (match_int(&args[0], &option))
102 return -EINVAL; 105 return -EINVAL;
103 config.gid = option; 106 opts->gid = option;
104 config.setgid = 1; 107 opts->setgid = 1;
105 break; 108 break;
106 case Opt_mode: 109 case Opt_mode:
107 if (match_octal(&args[0], &option)) 110 if (match_octal(&args[0], &option))
108 return -EINVAL; 111 return -EINVAL;
109 config.mode = option & S_IALLUGO; 112 opts->mode = option & S_IALLUGO;
110 break; 113 break;
111 default: 114 default:
112 printk(KERN_ERR "devpts: called with bogus options\n"); 115 printk(KERN_ERR "devpts: called with bogus options\n");
@@ -119,11 +122,14 @@ static int devpts_remount(struct super_block *sb, int *flags, char *data)
119 122
120static int devpts_show_options(struct seq_file *seq, struct vfsmount *vfs) 123static int devpts_show_options(struct seq_file *seq, struct vfsmount *vfs)
121{ 124{
122 if (config.setuid) 125 struct pts_fs_info *fsi = DEVPTS_SB(vfs->mnt_sb);
123 seq_printf(seq, ",uid=%u", config.uid); 126 struct pts_mount_opts *opts = &fsi->mount_opts;
124 if (config.setgid) 127
125 seq_printf(seq, ",gid=%u", config.gid); 128 if (opts->setuid)
126 seq_printf(seq, ",mode=%03o", config.mode); 129 seq_printf(seq, ",uid=%u", opts->uid);
130 if (opts->setgid)
131 seq_printf(seq, ",gid=%u", opts->gid);
132 seq_printf(seq, ",mode=%03o", opts->mode);
127 133
128 return 0; 134 return 0;
129} 135}
@@ -143,6 +149,7 @@ static void *new_pts_fs_info(void)
143 return NULL; 149 return NULL;
144 150
145 ida_init(&fsi->allocated_ptys); 151 ida_init(&fsi->allocated_ptys);
152 fsi->mount_opts.mode = DEVPTS_DEFAULT_MODE;
146 153
147 return fsi; 154 return fsi;
148} 155}
@@ -262,6 +269,8 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
262 struct super_block *sb = pts_sb_from_inode(ptmx_inode); 269 struct super_block *sb = pts_sb_from_inode(ptmx_inode);
263 struct inode *inode = new_inode(sb); 270 struct inode *inode = new_inode(sb);
264 struct dentry *root = sb->s_root; 271 struct dentry *root = sb->s_root;
272 struct pts_fs_info *fsi = DEVPTS_SB(sb);
273 struct pts_mount_opts *opts = &fsi->mount_opts;
265 char s[12]; 274 char s[12];
266 275
267 /* We're supposed to be given the slave end of a pty */ 276 /* We're supposed to be given the slave end of a pty */
@@ -275,7 +284,7 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
275 inode->i_uid = config.setuid ? config.uid : current_fsuid(); 284 inode->i_uid = config.setuid ? config.uid : current_fsuid();
276 inode->i_gid = config.setgid ? config.gid : current_fsgid(); 285 inode->i_gid = config.setgid ? config.gid : current_fsgid();
277 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 286 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
278 init_special_inode(inode, S_IFCHR|config.mode, device); 287 init_special_inode(inode, S_IFCHR|opts->mode, device);
279 inode->i_private = tty; 288 inode->i_private = tty;
280 tty->driver_data = inode; 289 tty->driver_data = inode;
281 290