aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/root.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/root.c')
-rw-r--r--fs/proc/root.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 03102d978180..6a8ac1d361a9 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -18,6 +18,7 @@
18#include <linux/bitops.h> 18#include <linux/bitops.h>
19#include <linux/mount.h> 19#include <linux/mount.h>
20#include <linux/pid_namespace.h> 20#include <linux/pid_namespace.h>
21#include <linux/parser.h>
21 22
22#include "internal.h" 23#include "internal.h"
23 24
@@ -36,6 +37,48 @@ static int proc_set_super(struct super_block *sb, void *data)
36 return err; 37 return err;
37} 38}
38 39
40enum {
41 Opt_err,
42};
43
44static const match_table_t tokens = {
45 {Opt_err, NULL},
46};
47
48static int proc_parse_options(char *options, struct pid_namespace *pid)
49{
50 char *p;
51 substring_t args[MAX_OPT_ARGS];
52
53 pr_debug("proc: options = %s\n", options);
54
55 if (!options)
56 return 1;
57
58 while ((p = strsep(&options, ",")) != NULL) {
59 int token;
60 if (!*p)
61 continue;
62
63 args[0].to = args[0].from = 0;
64 token = match_token(p, tokens, args);
65 switch (token) {
66 default:
67 pr_err("proc: unrecognized mount option \"%s\" "
68 "or missing value\n", p);
69 return 0;
70 }
71 }
72
73 return 1;
74}
75
76int proc_remount(struct super_block *sb, int *flags, char *data)
77{
78 struct pid_namespace *pid = sb->s_fs_info;
79 return !proc_parse_options(data, pid);
80}
81
39static struct dentry *proc_mount(struct file_system_type *fs_type, 82static struct dentry *proc_mount(struct file_system_type *fs_type,
40 int flags, const char *dev_name, void *data) 83 int flags, const char *dev_name, void *data)
41{ 84{
@@ -43,11 +86,15 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
43 struct super_block *sb; 86 struct super_block *sb;
44 struct pid_namespace *ns; 87 struct pid_namespace *ns;
45 struct proc_inode *ei; 88 struct proc_inode *ei;
89 char *options;
46 90
47 if (flags & MS_KERNMOUNT) 91 if (flags & MS_KERNMOUNT) {
48 ns = (struct pid_namespace *)data; 92 ns = (struct pid_namespace *)data;
49 else 93 options = NULL;
94 } else {
50 ns = current->nsproxy->pid_ns; 95 ns = current->nsproxy->pid_ns;
96 options = data;
97 }
51 98
52 sb = sget(fs_type, proc_test_super, proc_set_super, ns); 99 sb = sget(fs_type, proc_test_super, proc_set_super, ns);
53 if (IS_ERR(sb)) 100 if (IS_ERR(sb))
@@ -55,6 +102,10 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
55 102
56 if (!sb->s_root) { 103 if (!sb->s_root) {
57 sb->s_flags = flags; 104 sb->s_flags = flags;
105 if (!proc_parse_options(options, ns)) {
106 deactivate_locked_super(sb);
107 return ERR_PTR(-EINVAL);
108 }
58 err = proc_fill_super(sb); 109 err = proc_fill_super(sb);
59 if (err) { 110 if (err) {
60 deactivate_locked_super(sb); 111 deactivate_locked_super(sb);