proc: use human-readable values for hidepid
The hidepid parameter values are becoming more and more and it becomes difficult to remember what each new magic number means. Backward compatibility is preserved since it is possible to specify numerical value for the hidepid parameter. This does not break the fsconfig since it is not possible to specify a numerical value through it. All numeric values are converted to a string. The type FSCONFIG_SET_BINARY cannot be used to indicate a numerical value. Selftest has been added to verify this behavior. Suggested-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com> Reviewed-by: Alexey Dobriyan <adobriyan@gmail.com> Reviewed-by: Kees Cook <keescook@chromium.org> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Tento commit je obsažen v:

odevzdal
Eric W. Biederman

rodič
37e7647a72
revize
1c6c4d112e
@@ -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");
|
||||
|
||||
|
@@ -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:
|
||||
|
Odkázat v novém úkolu
Zablokovat Uživatele