Skip to content

Commit 1d7e48a

Browse files
committed
Merge: CVE-2025-21771: sched_ext: Fix incorrect autogroup migration detection
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/470 JIRA: https://issues.redhat.com/browse/RHEL-81482 CVE: CVE-2025-21771 ``` commit d6f3e7d Author: Tejun Heo <tj@kernel.org> Date: Fri Jan 24 12:22:12 2025 -1000 sched_ext: Fix incorrect autogroup migration detection scx_move_task() is called from sched_move_task() and tells the BPF scheduler that cgroup migration is being committed. sched_move_task() is used by both cgroup and autogroup migrations and scx_move_task() tried to filter out autogroup migrations by testing the destination cgroup and PF_EXITING but this is not enough. In fact, without explicitly tagging the thread which is doing the cgroup migration, there is no good way to tell apart scx_move_task() invocations for racing migration to the root cgroup and an autogroup migration. This led to scx_move_task() incorrectly ignoring a migration from non-root cgroup to an autogroup of the root cgroup triggering the following warning: WARNING: CPU: 7 PID: 1 at kernel/sched/ext.c:3725 scx_cgroup_can_attach+0x196/0x340 ... Call Trace: <TASK> cgroup_migrate_execute+0x5b1/0x700 cgroup_attach_task+0x296/0x400 __cgroup_procs_write+0x128/0x140 cgroup_procs_write+0x17/0x30 kernfs_fop_write_iter+0x141/0x1f0 vfs_write+0x31d/0x4a0 __x64_sys_write+0x72/0xf0 do_syscall_64+0x82/0x160 entry_SYSCALL_64_after_hwframe+0x76/0x7e Fix it by adding an argument to sched_move_task() that indicates whether the moving is for a cgroup or autogroup migration. After the change, scx_move_task() is called only for cgroup migrations and renamed to scx_cgroup_move_task(). Link: sched-ext/scx#370 Fixes: 8195136 ("sched_ext: Add cgroup support") Cc: stable@vger.kernel.org # v6.12+ Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Tejun Heo <tj@kernel.org>``` Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com> --- <small>Created 2025-02-27 22:41 UTC by backporter - [KWF FAQ](https://red.ht/kernel_workflow_doc) - [Slack #team-kernel-workflow](https://redhat-internal.slack.com/archives/C04LRUPMJQ5) - [Source](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/webhook/utils/backporter.py) - [Documentation](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/docs/README.backporter.md) - [Report an issue](https://gitlab.com/cki-project/kernel-workflow/-/issues/new?issue%5Btitle%5D=backporter%20webhook%20issue)</small> Approved-by: Phil Auld <pauld@redhat.com> Merged-by: Julio Faracco <jfaracco@redhat.com>
2 parents 0d72831 + 69120bc commit 1d7e48a

File tree

5 files changed

+10
-22
lines changed

5 files changed

+10
-22
lines changed

kernel/sched/autogroup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ void sched_autogroup_exit_task(struct task_struct *p)
150150
* see this thread after that: we can no longer use signal->autogroup.
151151
* See the PF_EXITING check in task_wants_autogroup().
152152
*/
153-
sched_move_task(p);
153+
sched_move_task(p, true);
154154
}
155155

156156
static void
@@ -182,7 +182,7 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag)
182182
* sched_autogroup_exit_task().
183183
*/
184184
for_each_thread(p, t)
185-
sched_move_task(t);
185+
sched_move_task(t, true);
186186

187187
unlock_task_sighand(p, &flags);
188188
autogroup_kref_put(prev);

kernel/sched/core.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9077,7 +9077,7 @@ static void sched_change_group(struct task_struct *tsk, struct task_group *group
90779077
* now. This function just updates tsk->se.cfs_rq and tsk->se.parent to reflect
90789078
* its new group.
90799079
*/
9080-
void sched_move_task(struct task_struct *tsk)
9080+
void sched_move_task(struct task_struct *tsk, bool for_autogroup)
90819081
{
90829082
int queued, running, queue_flags =
90839083
DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK;
@@ -9106,7 +9106,8 @@ void sched_move_task(struct task_struct *tsk)
91069106
put_prev_task(rq, tsk);
91079107

91089108
sched_change_group(tsk, group);
9109-
scx_move_task(tsk);
9109+
if (!for_autogroup)
9110+
scx_cgroup_move_task(tsk);
91109111

91119112
if (queued)
91129113
enqueue_task(rq, tsk, queue_flags);
@@ -9207,7 +9208,7 @@ static void cpu_cgroup_attach(struct cgroup_taskset *tset)
92079208
struct cgroup_subsys_state *css;
92089209

92099210
cgroup_taskset_for_each(task, css, tset)
9210-
sched_move_task(task);
9211+
sched_move_task(task, false);
92119212

92129213
scx_cgroup_finish_attach();
92139214
}

kernel/sched/ext.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3862,24 +3862,11 @@ int scx_cgroup_can_attach(struct cgroup_taskset *tset)
38623862
return ops_sanitize_err("cgroup_prep_move", ret);
38633863
}
38643864

3865-
void scx_move_task(struct task_struct *p)
3865+
void scx_cgroup_move_task(struct task_struct *p)
38663866
{
38673867
if (!scx_cgroup_enabled)
38683868
return;
38693869

3870-
/*
3871-
* We're called from sched_move_task() which handles both cgroup and
3872-
* autogroup moves. Ignore the latter.
3873-
*
3874-
* Also ignore exiting tasks, because in the exit path tasks transition
3875-
* from the autogroup to the root group, so task_group_is_autogroup()
3876-
* alone isn't able to catch exiting autogroup tasks. This is safe for
3877-
* cgroup_move(), because cgroup migrations never happen for PF_EXITING
3878-
* tasks.
3879-
*/
3880-
if (task_group_is_autogroup(task_group(p)) || (p->flags & PF_EXITING))
3881-
return;
3882-
38833870
/*
38843871
* @p must have ops.cgroup_prep_move() called on it and thus
38853872
* cgrp_moving_from set.

kernel/sched/ext.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static inline void scx_update_idle(struct rq *rq, bool idle) {}
7373
int scx_tg_online(struct task_group *tg);
7474
void scx_tg_offline(struct task_group *tg);
7575
int scx_cgroup_can_attach(struct cgroup_taskset *tset);
76-
void scx_move_task(struct task_struct *p);
76+
void scx_cgroup_move_task(struct task_struct *p);
7777
void scx_cgroup_finish_attach(void);
7878
void scx_cgroup_cancel_attach(struct cgroup_taskset *tset);
7979
void scx_group_set_weight(struct task_group *tg, unsigned long cgrp_weight);
@@ -82,7 +82,7 @@ void scx_group_set_idle(struct task_group *tg, bool idle);
8282
static inline int scx_tg_online(struct task_group *tg) { return 0; }
8383
static inline void scx_tg_offline(struct task_group *tg) {}
8484
static inline int scx_cgroup_can_attach(struct cgroup_taskset *tset) { return 0; }
85-
static inline void scx_move_task(struct task_struct *p) {}
85+
static inline void scx_cgroup_move_task(struct task_struct *p) {}
8686
static inline void scx_cgroup_finish_attach(void) {}
8787
static inline void scx_cgroup_cancel_attach(struct cgroup_taskset *tset) {}
8888
static inline void scx_group_set_weight(struct task_group *tg, unsigned long cgrp_weight) {}

kernel/sched/sched.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ extern void sched_online_group(struct task_group *tg,
572572
extern void sched_destroy_group(struct task_group *tg);
573573
extern void sched_release_group(struct task_group *tg);
574574

575-
extern void sched_move_task(struct task_struct *tsk);
575+
extern void sched_move_task(struct task_struct *tsk, bool for_autogroup);
576576

577577
#ifdef CONFIG_FAIR_GROUP_SCHED
578578
extern int sched_group_set_shares(struct task_group *tg, unsigned long shares);

0 commit comments

Comments
 (0)