[Devel] [PATCH VZ10 v2 04/12] ve_namespace: Don't allow to share thread group across VE boundaries
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Wed Dec 10 13:34:25 MSK 2025
We had the same thing for ve cgroup before, so let's also enforce it for
ve namespace. It's much easier when process (thread group) belongs to
one VE exclusively.
Let's do the same to what CLONE_NEWUSER does:
- On clone, fail if CLONE_THREAD is in flags (on new thread creation);
- On unshare, force CLONE_THREAD to flags, which leads to
check_unshare_flags verifying that the process is single threaded;
- On setns, fail if the process is not single threaded.
Note: This does effectively the same thing that ve_task_can_attach() did
for ve cgroup.
https://virtuozzo.atlassian.net/browse/VSTOR-119941
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Feature: ve: ve generic structures
---
kernel/fork.c | 8 ++++++++
kernel/ve/ve_namespace.c | 4 ++++
2 files changed, 12 insertions(+)
diff --git a/kernel/fork.c b/kernel/fork.c
index cfafff15bb85..5ce4c2ac91c1 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2182,6 +2182,10 @@ __latent_entropy struct task_struct *copy_process(
if ((clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) ||
(task_active_pid_ns(current) != nsp->pid_ns_for_children))
return ERR_PTR(-EINVAL);
+
+ /* Do not allow sharing a thread group across VE boundaries. */
+ if (clone_flags & CLONE_NEWVE)
+ return ERR_PTR(-EINVAL);
}
if (clone_flags & CLONE_PIDFD) {
@@ -3315,6 +3319,10 @@ int ksys_unshare(unsigned long unshare_flags)
if (unshare_flags & CLONE_NEWNS)
unshare_flags |= CLONE_FS;
+ /* If unsharing a ve namespace must also unshare the thread group. */
+ if (unshare_flags & CLONE_NEWVE)
+ unshare_flags |= CLONE_THREAD;
+
err = check_unshare_flags(unshare_flags);
if (err)
goto bad_unshare_out;
diff --git a/kernel/ve/ve_namespace.c b/kernel/ve/ve_namespace.c
index e76a41a0fbca..9df82c95f3d5 100644
--- a/kernel/ve/ve_namespace.c
+++ b/kernel/ve/ve_namespace.c
@@ -183,6 +183,10 @@ static int ve_ns_install(struct nsset *nsset, struct ns_common *new)
{
struct ve_namespace *ve_ns = to_ve_ns(new);
+ /* Tasks that share a thread group must share a VE namespace. */
+ if (!thread_group_empty(current))
+ return -EINVAL;
+
if (!ns_capable(ve_ns->user_ns, CAP_SYS_ADMIN) ||
!ns_capable(nsset->cred->user_ns, CAP_SYS_ADMIN))
return -EPERM;
--
2.52.0
More information about the Devel
mailing list