Register bpf_uring_buf_dynptr() and bpf_uring_buf_dynptr_rdwr() in the verifier's special_kfunc_list so they can produce LOCAL dynptrs. Without these entries, the verifier cannot determine the dynptr type for the __uninit output parameter. We cannot reuse the existing bpf_dynptr_from_mem() helper because kfunc PTR_TO_MEM returns are always marked MEM_RDONLY by the verifier (meta.r0_rdonly = true), but bpf_dynptr_from_mem() requires writable memory (ARG_PTR_TO_UNINIT_MEM). A dedicated kfunc with a special_kfunc_list entry is the only way to produce a dynptr from read-only kernel-provided memory. Signed-off-by: Ming Lei --- kernel/bpf/verifier.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 159b25f8269d..42d0672336e1 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -12531,6 +12531,8 @@ enum special_kfunc_type { KF_bpf_session_is_return, KF_bpf_stream_vprintk, KF_bpf_stream_print_stack, + KF_bpf_uring_buf_dynptr, + KF_bpf_uring_buf_dynptr_rdwr, }; BTF_ID_LIST(special_kfunc_list) @@ -12611,6 +12613,13 @@ BTF_ID(func, bpf_arena_reserve_pages) BTF_ID(func, bpf_session_is_return) BTF_ID(func, bpf_stream_vprintk) BTF_ID(func, bpf_stream_print_stack) +#ifdef CONFIG_IO_URING_BPF_EXT +BTF_ID(func, bpf_uring_buf_dynptr) +BTF_ID(func, bpf_uring_buf_dynptr_rdwr) +#else +BTF_ID_UNUSED +BTF_ID_UNUSED +#endif static bool is_task_work_add_kfunc(u32 func_id) { @@ -13590,6 +13599,9 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ dynptr_arg_type |= DYNPTR_TYPE_SKB_META; } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_file]) { dynptr_arg_type |= DYNPTR_TYPE_FILE; + } else if (meta->func_id == special_kfunc_list[KF_bpf_uring_buf_dynptr] || + meta->func_id == special_kfunc_list[KF_bpf_uring_buf_dynptr_rdwr]) { + dynptr_arg_type |= DYNPTR_TYPE_LOCAL; } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_file_discard]) { dynptr_arg_type |= DYNPTR_TYPE_FILE; meta->release_regno = regno; -- 2.53.0