Skip to content

Commit e26080d

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
bpf: prepare btf_prepare_func_args() for handling static subprogs
Generalize btf_prepare_func_args() to support both global and static subprogs. We are going to utilize this property in the next patch, reusing btf_prepare_func_args() for subprog call logic instead of reparsing BTF information in a completely separate implementation. btf_prepare_func_args() now detects whether subprog is global or static makes slight logic adjustments for static func cases, like not failing fatally (-EFAULT) for conditions that are allowable for static subprogs. Somewhat subtle (but major!) difference is the handling of pointer arguments. Both global and static functions need to handle special context arguments (which are pointers to predefined type names), but static subprogs give up on any other pointers, falling back to marking subprog as "unreliable", disabling the use of BTF type information altogether. For global functions, though, we are assuming that such pointers to unrecognized types are just pointers to fixed-sized memory region (or error out if size cannot be established, like for `void *` pointers). This patch accommodates these small differences and sets up a stage for refactoring in the next patch, eliminating a separate BTF-based parsing logic in btf_check_func_arg_match(). Acked-by: Eduard Zingerman <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 5eccd2d commit e26080d

File tree

3 files changed

+14
-14
lines changed

3 files changed

+14
-14
lines changed

include/linux/bpf_verifier.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,11 @@ struct bpf_verifier_env {
738738
char tmp_str_buf[TMP_STR_BUF_LEN];
739739
};
740740

741+
static inline struct bpf_func_info_aux *subprog_aux(struct bpf_verifier_env *env, int subprog)
742+
{
743+
return &env->prog->aux->func_info_aux[subprog];
744+
}
745+
741746
static inline struct bpf_subprog_info *subprog_info(struct bpf_verifier_env *env, int subprog)
742747
{
743748
return &env->subprog_info[subprog];

kernel/bpf/btf.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6914,6 +6914,7 @@ int btf_check_subprog_call(struct bpf_verifier_env *env, int subprog,
69146914
*/
69156915
int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
69166916
{
6917+
bool is_global = subprog_aux(env, subprog)->linkage == BTF_FUNC_GLOBAL;
69176918
struct bpf_subprog_info *sub = subprog_info(env, subprog);
69186919
struct bpf_verifier_log *log = &env->log;
69196920
struct bpf_prog *prog = env->prog;
@@ -6927,14 +6928,15 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
69276928
if (sub->args_cached)
69286929
return 0;
69296930

6930-
if (!prog->aux->func_info ||
6931-
prog->aux->func_info_aux[subprog].linkage != BTF_FUNC_GLOBAL) {
6931+
if (!prog->aux->func_info) {
69326932
bpf_log(log, "Verifier bug\n");
69336933
return -EFAULT;
69346934
}
69356935

69366936
btf_id = prog->aux->func_info[subprog].type_id;
69376937
if (!btf_id) {
6938+
if (!is_global) /* not fatal for static funcs */
6939+
return -EINVAL;
69386940
bpf_log(log, "Global functions need valid BTF\n");
69396941
return -EFAULT;
69406942
}
@@ -6990,16 +6992,14 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog)
69906992
sub->args[i].arg_type = ARG_ANYTHING;
69916993
continue;
69926994
}
6993-
if (btf_type_is_ptr(t)) {
6995+
if (btf_type_is_ptr(t) && btf_get_prog_ctx_type(log, btf, t, prog_type, i)) {
6996+
sub->args[i].arg_type = ARG_PTR_TO_CTX;
6997+
continue;
6998+
}
6999+
if (is_global && btf_type_is_ptr(t)) {
69947000
u32 mem_size;
69957001

6996-
if (btf_get_prog_ctx_type(log, btf, t, prog_type, i)) {
6997-
sub->args[i].arg_type = ARG_PTR_TO_CTX;
6998-
continue;
6999-
}
7000-
70017002
t = btf_type_skip_modifiers(btf, t->type, NULL);
7002-
70037003
ref_t = btf_resolve_size(btf, t, &mem_size);
70047004
if (IS_ERR(ref_t)) {
70057005
bpf_log(log,

kernel/bpf/verifier.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -437,11 +437,6 @@ static const char *subprog_name(const struct bpf_verifier_env *env, int subprog)
437437
return btf_type_name(env->prog->aux->btf, info->type_id);
438438
}
439439

440-
static struct bpf_func_info_aux *subprog_aux(const struct bpf_verifier_env *env, int subprog)
441-
{
442-
return &env->prog->aux->func_info_aux[subprog];
443-
}
444-
445440
static void mark_subprog_exc_cb(struct bpf_verifier_env *env, int subprog)
446441
{
447442
struct bpf_subprog_info *info = subprog_info(env, subprog);

0 commit comments

Comments
 (0)