diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/proc/inode.c | 15 | ||||
-rw-r--r-- | fs/proc/root.c | 38 |
2 files changed, 48 insertions, 5 deletions
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 0d5e68fa842f..cbacac2e892b 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -24,6 +24,7 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/mount.h> +#include <linux/bug.h> #include <linux/uaccess.h> @@ -165,6 +166,18 @@ void proc_invalidate_siblings_dcache(struct hlist_head *inodes, spinlock_t *lock deactivate_super(old_sb); } +static inline const char *hidepid2str(int v) +{ + switch (v) { + case HIDEPID_OFF: return "off"; + case HIDEPID_NO_ACCESS: return "noaccess"; + case HIDEPID_INVISIBLE: return "invisible"; + case HIDEPID_NOT_PTRACEABLE: return "ptraceable"; + } + WARN_ONCE(1, "bad hide_pid value: %d\n", v); + return "unknown"; +} + static int proc_show_options(struct seq_file *seq, struct dentry *root) { struct proc_fs_info *fs_info = proc_sb_info(root->d_sb); @@ -172,7 +185,7 @@ static int proc_show_options(struct seq_file *seq, struct dentry *root) if (!gid_eq(fs_info->pid_gid, GLOBAL_ROOT_GID)) seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, fs_info->pid_gid)); if (fs_info->hide_pid != HIDEPID_OFF) - seq_printf(seq, ",hidepid=%u", fs_info->hide_pid); + seq_printf(seq, ",hidepid=%s", hidepid2str(fs_info->hide_pid)); if (fs_info->pidonly != PROC_PIDONLY_OFF) seq_printf(seq, ",subset=pid"); diff --git a/fs/proc/root.c b/fs/proc/root.c index baff006a918f..288093261b7f 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -45,7 +45,7 @@ enum proc_param { static const struct fs_parameter_spec proc_fs_parameters[] = { fsparam_u32("gid", Opt_gid), - fsparam_u32("hidepid", Opt_hidepid), + fsparam_string("hidepid", Opt_hidepid), fsparam_string("subset", Opt_subset), {} }; @@ -58,6 +58,37 @@ static inline int valid_hidepid(unsigned int value) value == HIDEPID_NOT_PTRACEABLE); } +static int proc_parse_hidepid_param(struct fs_context *fc, struct fs_parameter *param) +{ + struct proc_fs_context *ctx = fc->fs_private; + struct fs_parameter_spec hidepid_u32_spec = fsparam_u32("hidepid", Opt_hidepid); + struct fs_parse_result result; + int base = (unsigned long)hidepid_u32_spec.data; + + if (param->type != fs_value_is_string) + return invalf(fc, "proc: unexpected type of hidepid value\n"); + + if (!kstrtouint(param->string, base, &result.uint_32)) { + if (!valid_hidepid(result.uint_32)) + return invalf(fc, "proc: unknown value of hidepid - %s\n", param->string); + ctx->hidepid = result.uint_32; + return 0; + } + + if (!strcmp(param->string, "off")) + ctx->hidepid = HIDEPID_OFF; + else if (!strcmp(param->string, "noaccess")) + ctx->hidepid = HIDEPID_NO_ACCESS; + else if (!strcmp(param->string, "invisible")) + ctx->hidepid = HIDEPID_INVISIBLE; + else if (!strcmp(param->string, "ptraceable")) + ctx->hidepid = HIDEPID_NOT_PTRACEABLE; + else + return invalf(fc, "proc: unknown value of hidepid - %s\n", param->string); + + return 0; +} + static int proc_parse_subset_param(struct fs_context *fc, char *value) { struct proc_fs_context *ctx = fc->fs_private; @@ -97,9 +128,8 @@ static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param) break; case Opt_hidepid: - if (!valid_hidepid(result.uint_32)) - return invalf(fc, "proc: unknown value of hidepid.\n"); - ctx->hidepid = result.uint_32; + if (proc_parse_hidepid_param(fc, param)) + return -EINVAL; break; case Opt_subset: |