Add BTF_KFUNC_TYPE_DESTRUCTIVE and a new destructive_set in struct btf_kfunc_id_set. Functions in this set will require CAP_SYS_BOOT capabilities and BPF_F_DESTRUCTIVE flag. Signed-off-by: Artem Savkov <asavkov@xxxxxxxxxx> --- include/linux/btf.h | 2 ++ kernel/bpf/verifier.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/linux/btf.h b/include/linux/btf.h index 1bfed7fa04287..6c58aa70e8125 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -18,6 +18,7 @@ enum btf_kfunc_type { BTF_KFUNC_TYPE_RELEASE, BTF_KFUNC_TYPE_RET_NULL, BTF_KFUNC_TYPE_KPTR_ACQUIRE, + BTF_KFUNC_TYPE_DESTRUCTIVE, BTF_KFUNC_TYPE_MAX, }; @@ -37,6 +38,7 @@ struct btf_kfunc_id_set { struct btf_id_set *release_set; struct btf_id_set *ret_null_set; struct btf_id_set *kptr_acquire_set; + struct btf_id_set *destructive_set; }; struct btf_id_set *sets[BTF_KFUNC_TYPE_MAX]; }; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c59c3df0fea61..064035e70deac 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -7582,6 +7582,18 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, return -EACCES; } + if (btf_kfunc_id_set_contains(desc_btf, resolve_prog_type(env->prog), + BTF_KFUNC_TYPE_DESTRUCTIVE, func_id)) { + if (!env->prog->aux->destructive) { + verbose(env, "destructive kfunc calls require BPF_F_DESTRUCTIVE flag\n"); + return -EACCES; + } + if (!capable(CAP_SYS_BOOT)) { + verbose(env, "destructive kfunc calls require CAP_SYS_BOOT capabilities\n"); + return -EACCES; + } + } + acq = btf_kfunc_id_set_contains(desc_btf, resolve_prog_type(env->prog), BTF_KFUNC_TYPE_ACQUIRE, func_id); -- 2.35.3