Re: [PATCH v4 sched_ext/for-7.3 02/40] sched_ext: Fix premature ops->priv publication in scx_alloc_and_add_sched()

Andrea Righi <[email protected]>
Newsgroups dev.linux.lists.sched-ext,org.kernel.vger.linux-kernel
Message-ID <alAGuFvcUsrekmy4@gpd4>
On Wed, Jul 08, 2026 at 11:23:51AM -1000, Tejun Heo wrote:
> 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: 105dcd005be2 ("sched_ext: Introduce scx_prog_sched()")
> Signed-off-by: Tejun Heo <[email protected]>

Reviewed-by: Andrea Righi <[email protected]>

Thanks,
-Andrea

> ---
>  kernel/sched/ext/ext.c | 18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
> index 1a0ec985da77..f4725698f5ef 100644
> --- a/kernel/sched/ext/ext.c
> +++ b/kernel/sched/ext/ext.c
> @@ -6363,11 +6363,6 @@ struct scx_sched *scx_alloc_and_add_sched(struct scx_enable_cmd *cmd,
>  		sch->ops = *cmd->ops;
>  	}
>  
> -	rcu_assign_pointer(ops->priv, sch);
> -
> -	sch->kobj.kset = scx_kset;
> -	INIT_LIST_HEAD(&sch->all);
> -
>  #ifdef CONFIG_EXT_SUB_SCHED
>  	char *buf = kzalloc(PATH_MAX, GFP_KERNEL);
>  	if (!buf) {
> @@ -6385,7 +6380,19 @@ struct scx_sched *scx_alloc_and_add_sched(struct scx_enable_cmd *cmd,
>  	sch->cgrp = cgrp;
>  	INIT_LIST_HEAD(&sch->children);
>  	INIT_LIST_HEAD(&sch->sibling);
> +#endif	/* CONFIG_EXT_SUB_SCHED */
>  
> +	/*
> +	 * Publishing makes @sch visible to scx_prog_sched() readers. Failure
> +	 * paths after this point must free @sch through kobject_put() whose
> +	 * release path defers the actual freeing by an RCU grace period.
> +	 */
> +	rcu_assign_pointer(ops->priv, sch);
> +
> +	sch->kobj.kset = scx_kset;
> +	INIT_LIST_HEAD(&sch->all);
> +
> +#ifdef CONFIG_EXT_SUB_SCHED
>  	if (parent) {
>  		/*
>  		 * Pin @parent for @sch's lifetime. The kobject hierarchy pins
> @@ -6440,7 +6447,6 @@ struct scx_sched *scx_alloc_and_add_sched(struct scx_enable_cmd *cmd,
>  
>  #ifdef CONFIG_EXT_SUB_SCHED
>  err_free_lb_resched:
> -	RCU_INIT_POINTER(ops->priv, NULL);
>  	free_cpumask_var(sch->stall_cpus);
>  #endif
>  err_free_lb_resched_cpumask:
> -- 
> 2.54.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.