Skip to content

Commit 49b3378

Browse files
committed
sched_ext: Fix premature ops->priv publication in scx_alloc_and_add_sched()
scx_alloc_and_add_sched() publishes @sch through ops->priv before allocating the cgroup path. If that allocation fails, the unwind path clears ops->priv and frees @sch immediately. scx_prog_sched() callers can dereference ops->priv from RCU context the moment it is set, so freeing without a grace period can use-after-free a concurrent kfunc caller. Move the publication below the cgroup path allocation so that every failure path after publication frees @sch through kobject_put(), whose release path defers the freeing by a grace period. Fixes: 105dcd0 ("sched_ext: Introduce scx_prog_sched()") Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
1 parent db4e9de commit 49b3378

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

kernel/sched/ext/ext.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6878,11 +6878,6 @@ static struct scx_sched *scx_alloc_and_add_sched(struct scx_enable_cmd *cmd,
68786878
sch->ops = *cmd->ops;
68796879
}
68806880

6881-
rcu_assign_pointer(ops->priv, sch);
6882-
6883-
sch->kobj.kset = scx_kset;
6884-
INIT_LIST_HEAD(&sch->all);
6885-
68866881
#ifdef CONFIG_EXT_SUB_SCHED
68876882
char *buf = kzalloc(PATH_MAX, GFP_KERNEL);
68886883
if (!buf) {
@@ -6900,7 +6895,19 @@ static struct scx_sched *scx_alloc_and_add_sched(struct scx_enable_cmd *cmd,
69006895
sch->cgrp = cgrp;
69016896
INIT_LIST_HEAD(&sch->children);
69026897
INIT_LIST_HEAD(&sch->sibling);
6898+
#endif /* CONFIG_EXT_SUB_SCHED */
69036899

6900+
/*
6901+
* Publishing makes @sch visible to scx_prog_sched() readers. Failure
6902+
* paths after this point must free @sch through kobject_put() whose
6903+
* release path defers the actual freeing by an RCU grace period.
6904+
*/
6905+
rcu_assign_pointer(ops->priv, sch);
6906+
6907+
sch->kobj.kset = scx_kset;
6908+
INIT_LIST_HEAD(&sch->all);
6909+
6910+
#ifdef CONFIG_EXT_SUB_SCHED
69046911
if (parent) {
69056912
/*
69066913
* Pin @parent for @sch's lifetime. The kobject hierarchy pins
@@ -6955,7 +6962,6 @@ static struct scx_sched *scx_alloc_and_add_sched(struct scx_enable_cmd *cmd,
69556962

69566963
#ifdef CONFIG_EXT_SUB_SCHED
69576964
err_free_lb_resched:
6958-
RCU_INIT_POINTER(ops->priv, NULL);
69596965
free_cpumask_var(sch->bypass_lb_resched_cpumask);
69606966
#endif
69616967
err_free_lb_cpumask:

0 commit comments

Comments
 (0)