Hey folks, we've gotten an issue with how libvirt is currently detecting the 
cgroup2 mounts. Basically we expose cgroup2 mounts in a container from the 
host-level and libvirt was selecting that instead of the container-level mount, 
which uses the canonical path.

The current logic basically iterate on the mounts until it finds a cgroup2 
mount and uses that. If there's multiple, it will override until the last one 
is read, which is not very safe.

I've cut a quick patch that should:
1. Validate that the mount is actually an existing directory in the context
2. Prefer the canonical mount (/sys/fs/cgroup) if it's available
3. only override it once, so it will not go through lists of mounts overriding 
up to the end

I'm happy to get some feedback here especially on step 3 as I'm not very sure 
how we should proceed on non-canonical situations or if we should at all. Maybe 
the best solution is to just use the canonical path?

>From 4a0bf5c5b1e1cd4e0393981a25e1407d29beb43e Mon Sep 17 00:00:00 2001
From: Rogerio Vinhal Nunes <[email protected]>
Date: Mon, 2 Feb 2026 19:24:52 +0000
Subject: [PATCH] Preferred /sys/fs/cgroup as a canonical mount but also
 verifies if the mount is an existing directory in the namespace. The reason
 for this is preventing that mounts that are not visible in the container
 namespace or additional cgroupv2 mounts to share host context might be
 incorrectly taken as targets here.

---
 src/util/vircgroupv2.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
index eaf5ae98f6..aa8c950691 100644
--- a/src/util/vircgroupv2.c
+++ b/src/util/vircgroupv2.c
@@ -23,6 +23,7 @@
 #ifdef __linux__
 # include <mntent.h>
 # include <sys/mount.h>
+# include <sys/stat.h>
 #endif /* __linux__ */

 #include "internal.h"
@@ -46,6 +47,8 @@ VIR_LOG_INIT("util.cgroup");

 #define VIR_FROM_THIS VIR_FROM_CGROUP

+#define VIR_CGROUP_SYSFS_MOUNT "/sys/fs/cgroup"
+
 VIR_ENUM_DECL(virCgroupV2Controller);
 VIR_ENUM_IMPL(virCgroupV2Controller,
               VIR_CGROUP_CONTROLLER_LAST,
@@ -173,12 +176,26 @@ virCgroupV2DetectMounts(virCgroup *group,
                         const char *mntOpts G_GNUC_UNUSED,
                         const char *mntDir)
 {
+    struct stat sb;
+
     if (STRNEQ(mntType, "cgroup2"))
         return 0;

-    VIR_FREE(group->unified.mountPoint);
+    if (stat(mntDir, &sb) < 0 || !S_ISDIR(sb.st_mode)) {
+        VIR_DEBUG("Skipping non-directory cgroup2 mount: %s", mntDir);
+        return 0;
+    }
+
+    /* Always prefer /sys/fs/cgroup as the canonical mount point.
+     * If we already have /sys/fs/cgroup, don't override it.
+     * Otherwise, use the first valid directory we find as fallback. */
+    if (STREQ(mntDir, VIR_CGROUP_SYSFS_MOUNT)) {
+        VIR_FREE(group->unified.mountPoint);
+        group->unified.mountPoint = g_strdup(mntDir);
+    } else if (!group->unified.mountPoint) {
+        group->unified.mountPoint = g_strdup(mntDir);
+    }

-    group->unified.mountPoint = g_strdup(mntDir);
     return 0;
 }

--
2.52.0

Reply via email to