From: Nicholas Dudar check_ptr_to_btf_access() lets program-type btf_struct_access callbacks validate writes before the default BTF access path rejects non-read accesses. That bypasses the read-only policy for untrusted BTF pointers created by helpers such as bpf_rdonly_cast(). Reject non-read accesses through PTR_UNTRUSTED BTF pointers at the common entry point, before the callback branch to handle all cases. Fixes: 282de143ead9 ("bpf: Introduce allocated objects support") Reviewed-by: Amery Hung Signed-off-by: Nicholas Dudar Signed-off-by: Kumar Kartikeya Dwivedi --- kernel/bpf/verifier.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 51f7965d42e3..4f42b4e929ad 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -5790,6 +5790,11 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env, return -EACCES; } + if (atype != BPF_READ && (type_flag(reg->type) & PTR_UNTRUSTED)) { + verbose(env, "only read is supported\n"); + return -EACCES; + } + if (env->ops->btf_struct_access && !type_is_alloc(reg->type) && atype == BPF_WRITE) { if (!btf_is_kernel(reg->btf)) { verifier_bug(env, "reg->btf must be kernel btf"); @@ -5802,8 +5807,7 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env, reg_arg_name(env, argno), tname, off, size); } else { /* Writes are permitted with default btf_struct_access for - * program allocated objects (which always have id > 0), - * but not for untrusted PTR_TO_BTF_ID | MEM_ALLOC. + * program allocated objects (which always have id > 0). */ if (atype != BPF_READ && !type_is_ptr_alloc_obj(reg->type)) { verbose(env, "only read is supported\n"); -- 2.53.0