mirror of
https://github.com/torvalds/linux.git
synced 2026-05-13 00:28:54 +02:00
scx_kfunc_context_filter() currently allows non-SCX struct_ops programs
(e.g. tcp_congestion_ops) to call SCX unlocked kfuncs. This is wrong
for two reasons:
- It is semantically incorrect: a TCP congestion control program has no
business calling SCX kfuncs such as scx_bpf_kick_cpu().
- With CONFIG_EXT_SUB_SCHED=y, kfuncs like scx_bpf_kick_cpu() call
scx_prog_sched(aux), which invokes bpf_prog_get_assoc_struct_ops(aux)
and casts the result to struct sched_ext_ops * before reading ops->priv.
For a non-SCX struct_ops program the returned pointer is the kdata of
that struct_ops type, which is far smaller than sched_ext_ops, making
the read an out-of-bounds access (confirmed with KASAN).
Extend the filter to cover scx_kfunc_set_any and scx_kfunc_set_idle as
well, and deny all SCX kfuncs for any struct_ops program that is not the
SCX struct_ops. This addresses both issues: the semantic contract is
enforced at the verifier level, and the runtime out-of-bounds access
becomes unreachable.
Fixes: d1d3c1c6ae ("sched_ext: Add verifier-time kfunc context filter")
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Cheng-Yang Chou <yphbchou0911@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
28 lines
900 B
C
28 lines
900 B
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* BPF extensible scheduler class: Documentation/scheduler/sched-ext.rst
|
|
*
|
|
* Copyright (c) 2022 Meta Platforms, Inc. and affiliates.
|
|
* Copyright (c) 2022 Tejun Heo <tj@kernel.org>
|
|
* Copyright (c) 2022 David Vernet <dvernet@meta.com>
|
|
* Copyright (c) 2024 Andrea Righi <arighi@nvidia.com>
|
|
*/
|
|
#ifndef _KERNEL_SCHED_EXT_IDLE_H
|
|
#define _KERNEL_SCHED_EXT_IDLE_H
|
|
|
|
struct sched_ext_ops;
|
|
|
|
extern struct btf_id_set8 scx_kfunc_ids_idle;
|
|
extern struct btf_id_set8 scx_kfunc_ids_select_cpu;
|
|
|
|
void scx_idle_update_selcpu_topology(struct sched_ext_ops *ops);
|
|
void scx_idle_init_masks(void);
|
|
|
|
s32 scx_select_cpu_dfl(struct task_struct *p, s32 prev_cpu, u64 wake_flags,
|
|
const struct cpumask *cpus_allowed, u64 flags);
|
|
void scx_idle_enable(struct sched_ext_ops *ops);
|
|
void scx_idle_disable(void);
|
|
int scx_idle_init(void);
|
|
|
|
#endif /* _KERNEL_SCHED_EXT_IDLE_H */
|