Re: [PATCH v4 sched_ext/for-7.3 08/40] sched_ext: Reject direct slice and dsq_vtime writes for cid-form schedulers

From: Andrea Righi

Date: Thu Jul 09 2026 - 16:57:10 EST


On Wed, Jul 08, 2026 at 11:23:57AM -1000, Tejun Heo wrote:
> Direct writes to p->scx.slice and p->scx.dsq_vtime bypass
> scx_bpf_task_set_slice/dsq_vtime() and the authority checks they carry.
> Those checks exist for sub-schedulers, which attach only through the
> cid-form struct_ops, so the direct writes only need to be closed there.
>
> Give sched_ext_ops_cid its own verifier ops that reject the two fields.
> cid-form is a new interface with no legacy users, so there is no
> compatibility to keep. The cpu-form keeps direct writes, and the deprecation
> warning they carried is dropped.
>
> Signed-off-by: Tejun Heo <tj@xxxxxxxxxx>

The thing reported by sashiko seems more like a BPF issue. From an scx
perspective this one looks good to me.

Reviewed-by: Andrea Righi <arighi@xxxxxxxxxx>

Thanks,
-Andrea

> ---
> kernel/sched/ext/ext.c | 44 ++++++++++++++++++++++++++++++------------
> 1 file changed, 32 insertions(+), 12 deletions(-)
>
> diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
> index be75bdc9ada2..bd3cb59b1dbf 100644
> --- a/kernel/sched/ext/ext.c
> +++ b/kernel/sched/ext/ext.c
> @@ -6995,6 +6995,21 @@ static bool bpf_scx_is_valid_access(int off, int size,
> return btf_ctx_access(off, size, type, prog, info);
> }
>
> +/* common to both forms: only scx.disallow is writable */
> +static int bpf_scx_btf_struct_access_common(const struct bpf_reg_state *reg,
> + int off, int size)
> +{
> + const struct btf_type *t;
> +
> + t = btf_type_by_id(reg->btf, reg->btf_id);
> + if (t == task_struct_type &&
> + off >= offsetof(struct task_struct, scx.disallow) &&
> + off + size <= offsetofend(struct task_struct, scx.disallow))
> + return SCALAR_VALUE;
> +
> + return -EACCES;
> +}
> +
> static int bpf_scx_btf_struct_access(struct bpf_verifier_log *log,
> const struct bpf_reg_state *reg, int off,
> int size)
> @@ -7003,23 +7018,22 @@ static int bpf_scx_btf_struct_access(struct bpf_verifier_log *log,
>
> t = btf_type_by_id(reg->btf, reg->btf_id);
> if (t == task_struct_type) {
> - /*
> - * COMPAT: Will be removed in v6.23.
> - */
> if ((off >= offsetof(struct task_struct, scx.slice) &&
> off + size <= offsetofend(struct task_struct, scx.slice)) ||
> (off >= offsetof(struct task_struct, scx.dsq_vtime) &&
> - off + size <= offsetofend(struct task_struct, scx.dsq_vtime))) {
> - pr_warn_ratelimited("sched_ext: Writing directly to p->scx.slice/dsq_vtime is deprecated, use scx_bpf_task_set_slice/dsq_vtime()\n");
> - return SCALAR_VALUE;
> - }
> -
> - if (off >= offsetof(struct task_struct, scx.disallow) &&
> - off + size <= offsetofend(struct task_struct, scx.disallow))
> + off + size <= offsetofend(struct task_struct, scx.dsq_vtime)))
> return SCALAR_VALUE;
> }
>
> - return -EACCES;
> + return bpf_scx_btf_struct_access_common(reg, off, size);
> +}
> +
> +/* cid-form rejects direct slice and dsq_vtime writes in favor of the kfuncs */
> +static int bpf_scx_cid_btf_struct_access(struct bpf_verifier_log *log,
> + const struct bpf_reg_state *reg, int off,
> + int size)
> +{
> + return bpf_scx_btf_struct_access_common(reg, off, size);
> }
>
> static const struct bpf_verifier_ops bpf_scx_verifier_ops = {
> @@ -7028,6 +7042,12 @@ static const struct bpf_verifier_ops bpf_scx_verifier_ops = {
> .btf_struct_access = bpf_scx_btf_struct_access,
> };
>
> +static const struct bpf_verifier_ops bpf_scx_cid_verifier_ops = {
> + .get_func_proto = bpf_base_func_proto,
> + .is_valid_access = bpf_scx_is_valid_access,
> + .btf_struct_access = bpf_scx_cid_btf_struct_access,
> +};
> +
> static int bpf_scx_init_member(const struct btf_type *t,
> const struct btf_member *member,
> void *kdata, const void *udata)
> @@ -7368,7 +7388,7 @@ static struct sched_ext_ops_cid __bpf_ops_sched_ext_ops_cid = {
> * verified to match by the BUILD_BUG_ON checks in scx_init().
> */
> static struct bpf_struct_ops bpf_sched_ext_ops_cid = {
> - .verifier_ops = &bpf_scx_verifier_ops,
> + .verifier_ops = &bpf_scx_cid_verifier_ops,
> .reg = bpf_scx_reg_cid,
> .unreg = bpf_scx_unreg,
> .check_member = bpf_scx_check_member,
> --
> 2.54.0
>