[Devel] [PATCH RHEL10 COMMIT] ve_namespace: Don't allow to share thread group across VE boundaries

Konstantin Khorenko khorenko at virtuozzo.com
Sat Dec 13 23:30:21 MSK 2025


The commit is pushed to "branch-rh10-6.12.0-55.13.1.3.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh10-6.12.0-55.13.1.2.24.vz10
------>
commit 1d667f1232fa4344f031cb2e0a2455d81897411c
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date:   Wed Dec 10 18:34:25 2025 +0800

    ve_namespace: Don't allow to share thread group across VE boundaries
    
    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 cfafff15bb856..5ce4c2ac91c1c 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 e76a41a0fbca0..9df82c95f3d59 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;


More information about the Devel mailing list