[Devel] [PATCH RHEL7 COMMIT] proc/pid: Don't show kernel threads inside Containers

Konstantin Khorenko khorenko at virtuozzo.com
Fri Feb 28 13:05:31 MSK 2020


The commit is pushed to "branch-rh7-3.10.0-1062.12.1.vz7.131.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1062.12.1.vz7.131.5
------>
commit c5f333bd7614b4e127ce3d59732249b7f8cc1c86
Author: Konstantin Khorenko <khorenko at virtuozzo.com>
Date:   Fri Feb 28 13:05:31 2020 +0300

    proc/pid: Don't show kernel threads inside Containers
    
    We have our home-brew security defence feature from ptrace-ing
    processes entered a Container outside.
    It's based on "vps_dumpable" field of task->mm and is checked in
    __ptrace_may_access() in particular.
    Same function __ptrace_may_access() is used when someone tries to
    readlink /proc/$PID/ns/$SOMENS and gets -EPERM for kthreads because they
    lack task->mm and thus "vps_dumpable" field and we really would like
    people not to ptrace kernel threads from inside a Container.
    
    We might enhance the security check, but decided just to make Container
    kernel threads invisible (from inside a Container only of course).
    
    https://jira.sw.ru/browse/PSBM-92107
    
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
    Reviewed-by: Kirill Tkhai <ktkhai at virtuozzo.com>
    
    v2: * check PF_KTHREAD task flag for kthread detection as not all
          kthreads lack ->mm.
        * Hide kthreads from direct checking (via, say, /proc/$PID) access
          as well.
        * proc entries for kthreads are hidden in procfs mounted in non-init
          pidns despite the namespace of current process (i.e. if you enter
          CT's mount ns only, you still won't be able to check entries of
          CT's kthreads. Check host's procfs for that.)
        * introduce helper
---
 fs/proc/base.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index dbf5a84b604f3..965a7467c2b4d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -3300,6 +3300,15 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
 	return error;
 }
 
+static bool is_visible_task_ve(struct pid_namespace *ns, struct task_struct *task)
+{
+	/* Don't show kthreads inside Containers. */
+	if ((task->flags & PF_KTHREAD) && (ns != &init_pid_ns))
+		return false;
+
+	return true;
+}
+
 struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
 {
 	struct dentry *result = NULL;
@@ -3314,6 +3323,8 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsign
 	ns = dentry->d_sb->s_fs_info;
 	rcu_read_lock();
 	task = find_task_by_pid_ns(tgid, ns);
+	if (task && !is_visible_task_ve(ns, task))
+		task = NULL;
 	if (task)
 		get_task_struct(task);
 	rcu_read_unlock();
@@ -3410,6 +3421,9 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
 	for (iter = next_tgid(ns, iter);
 	     iter.task;
 	     iter.tgid += 1, iter = next_tgid(ns, iter)) {
+		if (!is_visible_task_ve(ns, iter.task))
+			continue;
+
 		if (is_visible_task(ns, iter.task))
 			__filldir = filldir;
 		else


More information about the Devel mailing list