[RFC 1/2] cgroup, kthread: do not allow moving kthreads out of the root cgroup

From: Roman Gushchin
Date: Thu Oct 12 2017 - 13:38:55 EST


Attaching kernel threads to a non-root cgroup is generally a bad
idea. Kernel threads are generally performing the work required
to keep the system working and healthy, and applying various
resource limits may affect system stability and performance.

Some examples of dangerous behavior are limiting CPU time available
to rcu stuff, memory limits applied to almost all kthreads, etc.

To prevent this dangerous behavior, let's deny all kthread
movements between cgroups. Right now only kthreads bounded
to CPUs are not allowed to move, which is not sufficient.

If there are examples of kthreads which can be limited,
and it's guaranteed to be safe, we can allow explicit
exceptions further.

Signed-off-by: Roman Gushchin <guro@xxxxxx>
Cc: Tejun Heo <tj@xxxxxxxxxx>
Cc: Oleg Nesterov <oleg@xxxxxxxxxx>
Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
Cc: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Chris Mason <clm@xxxxxx>
Cc: kernel-team@xxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx
---
kernel/cgroup/cgroup.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index c7086c8835da..a3d7a1b5720d 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -2629,12 +2629,12 @@ struct task_struct *cgroup_procs_write_start(char *buf, bool threadgroup)
tsk = tsk->group_leader;

/*
- * kthreads may acquire PF_NO_SETAFFINITY during initialization.
- * If userland migrates such a kthread to a non-root cgroup, it can
+ * If userland migrates a kthread to a non-root cgroup, it can
* become trapped in a cpuset, or RT kthread may be born in a
- * cgroup with no rt_runtime allocated. Just say no.
+ * cgroup with no rt_runtime allocated, or it can suffer from
+ * memory shortage, etc. Just say no.
*/
- if (tsk->no_cgroup_migration || (tsk->flags & PF_NO_SETAFFINITY)) {
+ if (tsk->flags & (PF_KTHREAD | PF_NO_SETAFFINITY)) {
tsk = ERR_PTR(-EINVAL);
goto out_unlock_threadgroup;
}
--
2.13.6