[Devel] [PATCH RH9 16/22] pidns: add proc mount option 'hidepidns=0|1'
Andrey Zhadchenko
andrey.zhadchenko at virtuozzo.com
Thu Oct 7 13:57:40 MSK 2021
From: Konstantin Khlebnikov <khlebnikov at 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 <khlebnikov at 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.mikhalitsyn at 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.zhadchenko at 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
More information about the Devel
mailing list