From: Konstantin Khlebnikov <khlebni...@openvz.org> hidepidns=1 makes all tasks from nested pid-namespaces invisible. They are still accessible via /proc/<pid>/, but readdir will not show them.
Signed-off-by: Konstantin Khlebnikov <khlebni...@openvz.org> === VZ 8 rebase part https://jira.sw.ru/browse/PSBM-127782 vz7 commit: a98711f ("pidns: add proc mount option 'hidepidns=0|1'") Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalit...@virtuozzo.com> Rebased to vz9: - hide_pid is moved from struct pid_namespace to new struct proc_fs_info, so move hide_pidns accordingly - add new fs_info argument to is_visible() since has_pid_permissions() now uses fs_context argument (cherry picked from vz8 commit e227ad685ab89e1ef76bfe7c6de84900d4590a73) Signed-off-by: Andrey Zhadchenko <andrey.zhadche...@virtuozzo.com> --- Documentation/filesystems/proc.rst | 4 ++++ fs/proc/base.c | 11 ++++++++++- fs/proc/inode.c | 2 ++ fs/proc/root.c | 12 ++++++++++++ include/linux/proc_fs.h | 1 + 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst index 042c418..49e3fa4 100644 --- a/Documentation/filesystems/proc.rst +++ b/Documentation/filesystems/proc.rst @@ -2184,6 +2184,7 @@ Chapter 4: Configuring procfs ========= ======================================================== hidepid= Set /proc/<pid>/ access mode. + hidepidns= Hide tasks from nested pid-namespaces. gid= Set the group authorized to learn processes information. subset= Show only the specified subset of procfs. ========= ======================================================== @@ -2211,6 +2212,9 @@ other users run any program at all, etc. hidepid=ptraceable or hidepid=4 means that procfs should only contain /proc/<pid>/ directories that the caller can ptrace. +hidepidns=1 makes all tasks from nested pid-namespaces invisible. They are still +accessible via /proc/<pid>/, but readdir will not show them. + gid= defines a group authorized to learn processes information otherwise prohibited by hidepid=. If you use some daemon like identd which needs to learn information about processes information, just add identd to this group. diff --git a/fs/proc/base.c b/fs/proc/base.c index 6fb9575..550866d 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -730,6 +730,15 @@ static bool has_pid_permissions(struct proc_fs_info *fs_info, return ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS); } +static bool is_visible_task(struct pid_namespace *ns, + struct proc_fs_info *fs_info, struct task_struct *tsk) +{ + if (fs_info->hide_pidns == 1 && task_active_pid_ns(tsk) != ns) + return false; + if (!has_pid_permissions(fs_info, tsk, HIDEPID_INVISIBLE)) + return false; + return true; +} static int proc_pid_permission(struct user_namespace *mnt_userns, struct inode *inode, int mask) @@ -3491,7 +3500,7 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx) unsigned int len; cond_resched(); - if (!has_pid_permissions(fs_info, iter.task, HIDEPID_INVISIBLE)) + if (!is_visible_task(ns, fs_info, iter.task)) continue; len = snprintf(name, sizeof(name), "%u", iter.tgid); diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 35699dc..270fb81 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -186,6 +186,8 @@ static int proc_show_options(struct seq_file *seq, struct dentry *root) 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=%s", hidepid2str(fs_info->hide_pid)); + if (fs_info->hide_pidns) + seq_printf(seq, ",hidepidns=%u", fs_info->hide_pidns); 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 5e5944a..3e9de20 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -33,6 +33,7 @@ struct proc_fs_context { struct pid_namespace *pid_ns; unsigned int mask; enum proc_hidepid hidepid; + int hidepidns; int gid; enum proc_pidonly pidonly; }; @@ -40,12 +41,14 @@ struct proc_fs_context { enum proc_param { Opt_gid, Opt_hidepid, + Opt_hidepidns, Opt_subset, }; static const struct fs_parameter_spec proc_fs_parameters[] = { fsparam_u32("gid", Opt_gid), fsparam_string("hidepid", Opt_hidepid), + fsparam_u32("hidepidns",Opt_hidepidns), fsparam_string("subset", Opt_subset), {} }; @@ -137,6 +140,13 @@ static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param) return -EINVAL; break; + case Opt_hidepidns: + ctx->hidepidns = result.uint_32; + if (ctx->hidepidns < 0 || ctx->hidepidns > 1) { + return invalfc(fc, "proc: hidepidns value must be between 0 and 1.\n"); + } + break; + default: return -EINVAL; } @@ -155,6 +165,8 @@ static void proc_apply_options(struct proc_fs_info *fs_info, fs_info->pid_gid = make_kgid(user_ns, ctx->gid); if (ctx->mask & (1 << Opt_hidepid)) fs_info->hide_pid = ctx->hidepid; + if (ctx->mask & (1 << Opt_hidepidns)) + fs_info->hide_pidns = ctx->hidepidns; if (ctx->mask & (1 << Opt_subset)) fs_info->pidonly = ctx->pidonly; } diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index aa59b35..9c6f204 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -65,6 +65,7 @@ struct proc_fs_info { kgid_t pid_gid; enum proc_hidepid hide_pid; enum proc_pidonly pidonly; + int hide_pidns; }; static inline struct proc_fs_info *proc_sb_info(struct super_block *sb) -- 1.8.3.1 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel