public inbox for linux-doc@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cgroup/cpuset: Creating or adding CPUs to partition not allowed without privilege
@ 2026-04-28  3:34 Waiman Long
  2026-04-28  7:58 ` Michal Koutný
  0 siblings, 1 reply; 6+ messages in thread
From: Waiman Long @ 2026-04-28  3:34 UTC (permalink / raw)
  To: Chen Ridong, Tejun Heo, Johannes Weiner, Michal Koutný,
	Jonathan Corbet, Shuah Khan
  Cc: cgroups, linux-doc, linux-kernel, stable, Xie Maoyi, Waiman Long

Creation of a cpuset partition or adding more CPUs to an existing
partition will take CPUs away from other cpusets outside of the
partition leaving less CPUs for the others. So it is a privileged
operation that non-privileged users shouldn't be allowed to do.

Currently, remote partition code has check for CAP_SYS_ADMIN capability
before allowing such operations, but not for local partition. This leaves
a security hole in case cpuset.cpus.partition of a cpuset is chown'ed
to a non-root user and its parent cpuset happens to be a partition root.

Add such privilege check for local partition too to close such a hole.
Also update Documentation/admin-guide/cgroup-v2.rst to clarify the
intention.

With this patch applied, any attempt to enable partition or add CPUs
to an existing local or remote partition by an unprivileged user will
invalidate the partition even if writing to cpuset control files are
allowed.

Fixes: ee8dde0cd2ce ("cpuset: Add new v2 cpuset.sched.partition flag")
Reported-by: Xie Maoyi <maoyi.xie@ntu.edu.sg>
Signed-off-by: Waiman Long <longman@redhat.com>
---
 Documentation/admin-guide/cgroup-v2.rst |  6 ++++--
 kernel/cgroup/cpuset.c                  | 16 +++++++++++++---
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst
index 6efd0095ed99..df58557902db 100644
--- a/Documentation/admin-guide/cgroup-v2.rst
+++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -2599,8 +2599,10 @@ Cpuset Interface Files
 
   cpuset.cpus.partition
 	A read-write single value file which exists on non-root
-	cpuset-enabled cgroups.  This flag is owned by the parent cgroup
-	and is not delegatable.
+	cpuset-enabled cgroups. This file is owned by the parent cgroup
+	and is not delegatable. Any partition operations that take CPUs
+	away from other cpusets outside of a partition is not allowed
+	without privilege.
 
 	It accepts only the following input values when written to.
 
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index e3a081a07c6d..5fc8555f2046 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -57,7 +57,7 @@ static const char * const perr_strings[] = {
 	[PERR_HOTPLUG]   = "No cpu available due to hotplug",
 	[PERR_CPUSEMPTY] = "cpuset.cpus and cpuset.cpus.exclusive are empty",
 	[PERR_HKEEPING]  = "partition config conflicts with housekeeping setup",
-	[PERR_ACCESS]    = "Enable partition not permitted",
+	[PERR_ACCESS]    = "Partition operation not permitted",
 	[PERR_REMOTE]    = "Have remote partition underneath",
 };
 
@@ -1740,6 +1740,8 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
 	nocpu = tasks_nocpu_error(parent, cs, xcpus);
 
 	if ((cmd == partcmd_enable) || (cmd == partcmd_enablei)) {
+		if (!capable(CAP_SYS_ADMIN))
+			return PERR_ACCESS;
 		/*
 		 * Need to call compute_excpus() in case
 		 * exclusive_cpus not set. Sibling conflict should only happen
@@ -1833,12 +1835,18 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
 					       parent->effective_xcpus);
 		}
 
+		/*
+		 * Taking CPUs away from parent is not allowed without privilege
+		 */
+		if (deleting && !capable(CAP_SYS_ADMIN))
+			part_error = PERR_ACCESS;
+
 		/*
 		 * TBD: Invalidate a currently valid child root partition may
 		 * still break isolated_cpus_can_update() rule if parent is an
 		 * isolated partition.
 		 */
-		if (is_partition_valid(cs) && (old_prs != parent_prs)) {
+		else if (is_partition_valid(cs) && (old_prs != parent_prs)) {
 			if ((parent_prs == PRS_ROOT) &&
 			    /* Adding to parent means removing isolated CPUs */
 			    !isolated_cpus_can_update(tmp->delmask, tmp->addmask))
@@ -1919,8 +1927,10 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
 	}
 
 write_error:
-	if (part_error)
+	if (part_error) {
 		WRITE_ONCE(cs->prs_err, part_error);
+		adding = deleting = false;
+	}
 
 	if (cmd == partcmd_update) {
 		/*
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-04-28 18:02 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-28  3:34 [PATCH] cgroup/cpuset: Creating or adding CPUs to partition not allowed without privilege Waiman Long
2026-04-28  7:58 ` Michal Koutný
2026-04-28 15:19   ` Waiman Long
2026-04-28 15:44     ` Tejun Heo
2026-04-28 18:02       ` Waiman Long
2026-04-28 15:49     ` Waiman Long

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox