diff options
-rw-r--r-- | fs/devpts/inode.c | 45 |
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 | ||
35 | static struct vfsmount *devpts_mnt; | 35 | static struct vfsmount *devpts_mnt; |
36 | 36 | ||
37 | static struct { | 37 | struct 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 | ||
45 | enum { | 45 | enum { |
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 | ||
57 | struct pts_fs_info { | 57 | struct pts_fs_info { |
58 | struct ida allocated_ptys; | 58 | struct ida allocated_ptys; |
59 | struct pts_mount_opts mount_opts; | ||
59 | }; | 60 | }; |
60 | 61 | ||
61 | static inline struct pts_fs_info *DEVPTS_SB(struct super_block *sb) | 62 | static 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) | |||
74 | static int devpts_remount(struct super_block *sb, int *flags, char *data) | 75 | static 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 | ||
120 | static int devpts_show_options(struct seq_file *seq, struct vfsmount *vfs) | 123 | static 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 | ||