From: Waiman Long <longman@redhat.com>
To: "Chen Ridong" <chenridong@huawei.com>,
"Tejun Heo" <tj@kernel.org>,
"Johannes Weiner" <hannes@cmpxchg.org>,
"Michal Koutný" <mkoutny@suse.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"Shuah Khan" <skhan@linuxfoundation.org>
Cc: cgroups@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Xie Maoyi <maoyi.xie@ntu.edu.sg>,
Waiman Long <longman@redhat.com>
Subject: [PATCH] cgroup/cpuset: Creating or adding CPUs to partition not allowed without privilege
Date: Mon, 27 Apr 2026 23:34:39 -0400 [thread overview]
Message-ID: <20260428033439.783246-1-longman@redhat.com> (raw)
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
next reply other threads:[~2026-04-28 3:35 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-28 3:34 Waiman Long [this message]
2026-04-28 7:58 ` [PATCH] cgroup/cpuset: Creating or adding CPUs to partition not allowed without privilege 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260428033439.783246-1-longman@redhat.com \
--to=longman@redhat.com \
--cc=cgroups@vger.kernel.org \
--cc=chenridong@huawei.com \
--cc=corbet@lwn.net \
--cc=hannes@cmpxchg.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maoyi.xie@ntu.edu.sg \
--cc=mkoutny@suse.com \
--cc=skhan@linuxfoundation.org \
--cc=stable@vger.kernel.org \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox