summaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2016-06-09 16:32:10 -0400
committerEric W. Biederman <ebiederm@xmission.com>2016-06-23 16:41:54 -0400
commite94591d0d90c13166cb6eb54ce5f96ed13d81b55 (patch)
treea52df89fe96d5ed24657c3fed1552ffc1d474b3a /fs/proc
parentd91ee87d8d85a0808c01787e8b4a6b48f2ba487b (diff)
proc: Convert proc_mount to use mount_ns.
Move the call of get_pid_ns, the call of proc_parse_options, and the setting of s_iflags into proc_fill_super so that mount_ns can be used. Convert proc_mount to call mount_ns and remove the now unnecessary code. Acked-by: Seth Forshee <seth.forshee@canonical.com> Reviewed-by: Djalal Harouni <tixxdz@gmail.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/inode.c9
-rw-r--r--fs/proc/internal.h3
-rw-r--r--fs/proc/root.c52
3 files changed, 13 insertions, 51 deletions
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 78fa452d65ed..f4817efb25a6 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -457,12 +457,17 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
457 return inode; 457 return inode;
458} 458}
459 459
460int proc_fill_super(struct super_block *s) 460int proc_fill_super(struct super_block *s, void *data, int silent)
461{ 461{
462 struct pid_namespace *ns = get_pid_ns(s->s_fs_info);
462 struct inode *root_inode; 463 struct inode *root_inode;
463 int ret; 464 int ret;
464 465
465 s->s_iflags |= SB_I_USERNS_VISIBLE; 466 if (!proc_parse_options(data, ns))
467 return -EINVAL;
468
469 /* User space would break if executables appear on proc */
470 s->s_iflags |= SB_I_USERNS_VISIBLE | SB_I_NOEXEC;
466 s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC; 471 s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC;
467 s->s_blocksize = 1024; 472 s->s_blocksize = 1024;
468 s->s_blocksize_bits = 10; 473 s->s_blocksize_bits = 10;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index aa2781095bd1..7931c558c192 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -212,7 +212,7 @@ extern const struct inode_operations proc_pid_link_inode_operations;
212 212
213extern void proc_init_inodecache(void); 213extern void proc_init_inodecache(void);
214extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); 214extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *);
215extern int proc_fill_super(struct super_block *); 215extern int proc_fill_super(struct super_block *, void *data, int flags);
216extern void proc_entry_rundown(struct proc_dir_entry *); 216extern void proc_entry_rundown(struct proc_dir_entry *);
217 217
218/* 218/*
@@ -268,6 +268,7 @@ static inline void proc_tty_init(void) {}
268 * root.c 268 * root.c
269 */ 269 */
270extern struct proc_dir_entry proc_root; 270extern struct proc_dir_entry proc_root;
271extern int proc_parse_options(char *options, struct pid_namespace *pid);
271 272
272extern void proc_self_init(void); 273extern void proc_self_init(void);
273extern int proc_remount(struct super_block *, int *, char *); 274extern int proc_remount(struct super_block *, int *, char *);
diff --git a/fs/proc/root.c b/fs/proc/root.c
index a1b2860fec62..8d3e484055a6 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -23,21 +23,6 @@
23 23
24#include "internal.h" 24#include "internal.h"
25 25
26static int proc_test_super(struct super_block *sb, void *data)
27{
28 return sb->s_fs_info == data;
29}
30
31static int proc_set_super(struct super_block *sb, void *data)
32{
33 int err = set_anon_super(sb, NULL);
34 if (!err) {
35 struct pid_namespace *ns = (struct pid_namespace *)data;
36 sb->s_fs_info = get_pid_ns(ns);
37 }
38 return err;
39}
40
41enum { 26enum {
42 Opt_gid, Opt_hidepid, Opt_err, 27 Opt_gid, Opt_hidepid, Opt_err,
43}; 28};
@@ -48,7 +33,7 @@ static const match_table_t tokens = {
48 {Opt_err, NULL}, 33 {Opt_err, NULL},
49}; 34};
50 35
51static int proc_parse_options(char *options, struct pid_namespace *pid) 36int proc_parse_options(char *options, struct pid_namespace *pid)
52{ 37{
53 char *p; 38 char *p;
54 substring_t args[MAX_OPT_ARGS]; 39 substring_t args[MAX_OPT_ARGS];
@@ -100,45 +85,16 @@ int proc_remount(struct super_block *sb, int *flags, char *data)
100static struct dentry *proc_mount(struct file_system_type *fs_type, 85static struct dentry *proc_mount(struct file_system_type *fs_type,
101 int flags, const char *dev_name, void *data) 86 int flags, const char *dev_name, void *data)
102{ 87{
103 int err;
104 struct super_block *sb;
105 struct pid_namespace *ns; 88 struct pid_namespace *ns;
106 char *options;
107 89
108 if (flags & MS_KERNMOUNT) { 90 if (flags & MS_KERNMOUNT) {
109 ns = (struct pid_namespace *)data; 91 ns = data;
110 options = NULL; 92 data = NULL;
111 } else { 93 } else {
112 ns = task_active_pid_ns(current); 94 ns = task_active_pid_ns(current);
113 options = data;
114
115 /* Does the mounter have privilege over the pid namespace? */
116 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
117 return ERR_PTR(-EPERM);
118 }
119
120 sb = sget(fs_type, proc_test_super, proc_set_super, flags, ns);
121 if (IS_ERR(sb))
122 return ERR_CAST(sb);
123
124 if (!proc_parse_options(options, ns)) {
125 deactivate_locked_super(sb);
126 return ERR_PTR(-EINVAL);
127 }
128
129 if (!sb->s_root) {
130 err = proc_fill_super(sb);
131 if (err) {
132 deactivate_locked_super(sb);
133 return ERR_PTR(err);
134 }
135
136 sb->s_flags |= MS_ACTIVE;
137 /* User space would break if executables appear on proc */
138 sb->s_iflags |= SB_I_NOEXEC;
139 } 95 }
140 96
141 return dget(sb->s_root); 97 return mount_ns(fs_type, flags, data, ns, ns->user_ns, proc_fill_super);
142} 98}
143 99
144static void proc_kill_sb(struct super_block *sb) 100static void proc_kill_sb(struct super_block *sb)