kernel/sched/ext/sub.c | 4 ++++ 1 file changed, 4 insertions(+)
find_parent_sched() dereferences cgrp->scx_sched without checking
for NULL. cgroup_get_from_id() can return cgroups from any
hierarchy, including cgroup v1 where scx_sched is never set.
A BPF program that passes a v1 cgroup ID as sub_cgroup_id would
hit parent->cgrp on a NULL pointer and crash the kernel.
Add a NULL check and return -ENODEV.
Signed-off-by: Cui Jian <cjian720@163.com>
---
kernel/sched/ext/sub.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel/sched/ext/sub.c b/kernel/sched/ext/sub.c
index d7842a609d96..6395281bae71 100644
--- a/kernel/sched/ext/sub.c
+++ b/kernel/sched/ext/sub.c
@@ -1209,6 +1209,10 @@ static struct scx_sched *find_parent_sched(struct cgroup *cgrp)
lockdep_assert_held(&scx_sched_lock);
+ /* no SCX sched */
+ if (!parent)
+ return ERR_PTR(-ENODEV);
+
/* can't attach twice to the same cgroup */
if (parent->cgrp == cgrp)
return ERR_PTR(-EBUSY);
--
2.34.1
On Fri, 7 Aug 2026 17:38:37 +0800, Cui Jian wrote: > cgroup_get_from_id() can return cgroups from any hierarchy, including > cgroup v1 where scx_sched is never set. It can't. The id is looked up in the v2 kernfs root only: kn = kernfs_find_and_get_node_by_id(cgrp_dfl_root.kf_root, id); so a v1 id gets -ENOENT there, and even if it were found, cgroup_get_from_id() rejects it through cgroup_is_descendant(), which starts with cgrp->root != ancestor->root. A v1 cgroup never reaches find_parent_sched(). That also fits ->scx_sched being v2-only anyway: scx_cgroup_lifetime_notify() bails out on !cgroup_on_dfl(cgrp). Is there another window? I could not find one in ext.c: sub-enable checks scx_enabled() under scx_enable_mutex, root enable sets ->scx_sched on every live v2 descendant, cgroups created later inherit it in the ONLINE notifier, and the sweep and the notifier both run under cgroup_mutex. I am reading ext.c since sub.c is not upstream yet, so the split may have introduced something I cannot see. The cgroup_get_from_id() part is independent of that. As hardening the check is harmless, but the changelog reads as a reachable crash, and that wording travels into backport and CVE decisions. Thanks, Zhan Xusheng
find_parent_sched() dereferences cgrp->scx_sched without checking
for NULL. This is safe in practice because scx_sched is always
set for cgroups that can reach this function, but add a defensive
check for robustness.
Signed-off-by: Cui Jian <cjian720@163.com>
---
kernel/sched/ext/sub.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel/sched/ext/sub.c b/kernel/sched/ext/sub.c
index d7842a609d96..6395281bae71 100644
--- a/kernel/sched/ext/sub.c
+++ b/kernel/sched/ext/sub.c
@@ -1209,6 +1209,10 @@ static struct scx_sched *find_parent_sched(struct cgroup *cgrp)
lockdep_assert_held(&scx_sched_lock);
+ /* no SCX sched */
+ if (!parent)
+ return ERR_PTR(-ENODEV);
+
/* can't attach twice to the same cgroup */
if (parent->cgrp == cgrp)
return ERR_PTR(-EBUSY);
--
2.34.1
© 2016 - 2026 Red Hat, Inc.