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

Reply via email to