git: 24a8ea4df342 - stable/12 - MFC kern: cpuset: allow jails to modify child jails' roots
Kyle Evans
kevans at FreeBSD.org
Sun Dec 27 20:54:25 UTC 2020
The branch stable/12 has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=24a8ea4df3426dfce2896e265eb3e0206aa33a21
commit 24a8ea4df3426dfce2896e265eb3e0206aa33a21
Author: Kyle Evans <kevans at FreeBSD.org>
AuthorDate: 2020-12-19 03:30:06 +0000
Commit: Kyle Evans <kevans at FreeBSD.org>
CommitDate: 2020-12-27 20:53:46 +0000
MFC kern: cpuset: allow jails to modify child jails' roots
This partially lifts a restriction imposed by r191639 ("Prevent a superuser
inside a jail from modifying the dedicated root cpuset of that jail") that's
perhaps beneficial after r192895 ("Add hierarchical jails."). Jails still
cannot modify their own cpuset, but they can modify child jails' roots to
further restrict them or widen them back to the modifying jails' own mask.
As a side effect of this, the system root may once again widen the mask of
jails as long as they're still using a subset of the parent jails' mask.
This was previously prevented by the fact that cpuset_getroot of a root set
will return that root, rather than the root's parent -- cpuset_modify uses
cpuset_getroot since it was introduced in r327895, previously it was just
validating against set->cs_parent which allowed the system root to widen
jail masks.
PR: 240687
(cherry picked from commit 54a837c8cca109ad0d7ecb4b93379086f6f49275)
---
sys/kern/kern_cpuset.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/sys/kern/kern_cpuset.c b/sys/kern/kern_cpuset.c
index 27440aea5cc5..7695f07983ac 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -688,19 +688,34 @@ cpuset_modify(struct cpuset *set, cpuset_t *mask)
if (error)
return (error);
/*
- * In case we are called from within the jail
+ * In case we are called from within the jail,
* we do not allow modifying the dedicated root
* cpuset of the jail but may still allow to
- * change child sets.
+ * change child sets, including subordinate jails'
+ * roots.
*/
- if (jailed(curthread->td_ucred) &&
- set->cs_flags & CPU_SET_ROOT)
+ if ((set->cs_flags & CPU_SET_ROOT) != 0 &&
+ jailed(curthread->td_ucred) &&
+ set == curthread->td_ucred->cr_prison->pr_cpuset)
return (EPERM);
/*
* Verify that we have access to this set of
* cpus.
*/
- root = cpuset_getroot(set);
+ if ((set->cs_flags & (CPU_SET_ROOT | CPU_SET_RDONLY)) == CPU_SET_ROOT) {
+ KASSERT(set->cs_parent != NULL,
+ ("jail.cpuset=%d is not a proper child of parent jail's root.",
+ set->cs_id));
+
+ /*
+ * cpuset_getroot() cannot work here due to how top-level jail
+ * roots are constructed. Top-level jails are parented to
+ * thread0's cpuset (i.e. cpuset 1) rather than the system root.
+ */
+ root = set->cs_parent;
+ } else {
+ root = cpuset_getroot(set);
+ }
mtx_lock_spin(&cpuset_lock);
if (root && !CPU_SUBSET(&root->cs_mask, mask)) {
error = EINVAL;
More information about the dev-commits-src-all
mailing list