summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2026-04-24 14:31:36 -1000
committerTejun Heo <tj@kernel.org>2026-04-24 14:31:36 -1000
commit05b4a9a9bc37f1fa289a8f07b4fbfc3ae681b650 (patch)
tree102d45a21e497d38a3d30e362c7bffe77449ca27 /kernel
parentea7c716a24aebe887e0990649ab697bd698cc325 (diff)
downloadlinux-next-05b4a9a9bc37f1fa289a8f07b4fbfc3ae681b650.tar.gz
linux-next-05b4a9a9bc37f1fa289a8f07b4fbfc3ae681b650.zip
sched_ext: Reject NULL-sch callers in scx_bpf_task_set_slice/dsq_vtime
scx_prog_sched(aux) returns NULL for TRACING / SYSCALL BPF progs that have no struct_ops association when the root scheduler has sub_attach set. scx_bpf_task_set_slice() and scx_bpf_task_set_dsq_vtime() pass that NULL into scx_task_on_sched(sch, p), which under CONFIG_EXT_SUB_SCHED is rcu_access_pointer(p->scx.sched) == sch. For any non-scx task p->scx.sched is NULL, so NULL == NULL returns true and the authority gate is bypassed - a privileged but non-struct_ops-associated prog can poke p->scx.slice / p->scx.dsq_vtime on arbitrary tasks. Reject !sch up front so the gate only admits callers with a resolved scheduler. Fixes: 245d09c594ea ("sched_ext: Enforce scheduler ownership when updating slice and dsq_vtime") Reported-by: Chris Mason <clm@meta.com> Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/ext.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index e2898d60315b..f333fd0cb83f 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -8640,7 +8640,7 @@ __bpf_kfunc bool scx_bpf_task_set_slice(struct task_struct *p, u64 slice,
guard(rcu)();
sch = scx_prog_sched(aux);
- if (unlikely(!scx_task_on_sched(sch, p)))
+ if (unlikely(!sch || !scx_task_on_sched(sch, p)))
return false;
p->scx.slice = slice;
@@ -8663,7 +8663,7 @@ __bpf_kfunc bool scx_bpf_task_set_dsq_vtime(struct task_struct *p, u64 vtime,
guard(rcu)();
sch = scx_prog_sched(aux);
- if (unlikely(!scx_task_on_sched(sch, p)))
+ if (unlikely(!sch || !scx_task_on_sched(sch, p)))
return false;
p->scx.dsq_vtime = vtime;