[PATCH bpf-next] bpf: sched_ext: Mark ops argument container pointer fields as trusted
Tejun Heo <[email protected]>
| Newsgroups | dev.linux.lists.sched-ext,org.kernel.vger.bpf,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Walking an unannotated pointer field of a trusted struct yields a bare PTR_TO_BTF_ID in non-sleepable programs, which kfuncs and helpers accept, but PTR_UNTRUSTED in sleepable programs, which they reject. This gets in the way of making ops.init_task() sleepable, which schedulers want for allocations. For example, passing args->cgroup into bpf_cgrp_storage_get() then fails verification and the only recourse is round-tripping through the cgroup ID with bpf_cgroup_from_id(). The pointer fields in the sched_ext ops argument containers are all pinned by the callers for the duration of the ops calls and are never NULL. Add them to the verifier's trusted-fields whitelist so that they are PTR_TRUSTED in both sleepable and non-sleepable programs. Signed-off-by: Tejun Heo <[email protected]> --- kernel/bpf/verifier.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5661,6 +5661,28 @@ BTF_TYPE_SAFE_TRUSTED(struct file) { struct inode *f_inode; }; +/* + * The pointer fields in the sched_ext ops argument containers are pinned by the + * callers for the duration of the ops calls and are never NULL. + */ +BTF_TYPE_SAFE_TRUSTED(struct scx_init_task_args) { +#ifdef CONFIG_EXT_GROUP_SCHED + struct cgroup *cgroup; +#endif +}; + +BTF_TYPE_SAFE_TRUSTED(struct scx_cpu_release_args) { + struct task_struct *task; +}; + +BTF_TYPE_SAFE_TRUSTED(struct scx_sub_attach_args) { + struct sched_ext_ops *ops; +}; + +BTF_TYPE_SAFE_TRUSTED(struct scx_sub_detach_args) { + struct sched_ext_ops *ops; +}; + BTF_TYPE_SAFE_TRUSTED_OR_NULL(struct dentry) { struct inode *d_inode; }; @@ -5705,6 +5727,10 @@ static bool type_is_trusted(struct bpf_v BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct bpf_iter__task)); BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct linux_binprm)); BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct file)); + BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct scx_init_task_args)); + BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct scx_cpu_release_args)); + BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct scx_sub_attach_args)); + BTF_TYPE_EMIT(BTF_TYPE_SAFE_TRUSTED(struct scx_sub_detach_args)); return btf_nested_type_is_trusted(&env->log, reg, field_name, btf_id, "__safe_trusted"); }