Commit 00b85860 authored by Kumar Kartikeya Dwivedi's avatar Kumar Kartikeya Dwivedi Committed by Alexei Starovoitov

bpf: Rewrite kfunc argument handling

As we continue to add more features, argument types, kfunc flags, and
different extensions to kfuncs, the code to verify the correctness of
the kfunc prototype wrt the passed in registers has become ad-hoc and
ugly to read. To make life easier, and make a very clear split between
different stages of argument processing, move all the code into
verifier.c and refactor into easier to read helpers and functions.

This also makes sharing code within the verifier easier with kfunc
argument processing. This will be more and more useful in later patches
as we are now moving to implement very core BPF helpers as kfuncs, to
keep them experimental before baking into UAPI.

Remove all kfunc related bits now from btf_check_func_arg_match, as
users have been converted away to refactored kfunc argument handling.
Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20221118015614.2013203-12-memxor@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent b7ff9792
...@@ -2109,22 +2109,11 @@ int btf_distill_func_proto(struct bpf_verifier_log *log, ...@@ -2109,22 +2109,11 @@ int btf_distill_func_proto(struct bpf_verifier_log *log,
const char *func_name, const char *func_name,
struct btf_func_model *m); struct btf_func_model *m);
struct bpf_kfunc_arg_meta {
u64 r0_size;
bool r0_rdonly;
int ref_obj_id;
u32 flags;
};
struct bpf_reg_state; struct bpf_reg_state;
int btf_check_subprog_arg_match(struct bpf_verifier_env *env, int subprog, int btf_check_subprog_arg_match(struct bpf_verifier_env *env, int subprog,
struct bpf_reg_state *regs); struct bpf_reg_state *regs);
int btf_check_subprog_call(struct bpf_verifier_env *env, int subprog, int btf_check_subprog_call(struct bpf_verifier_env *env, int subprog,
struct bpf_reg_state *regs); struct bpf_reg_state *regs);
int btf_check_kfunc_arg_match(struct bpf_verifier_env *env,
const struct btf *btf, u32 func_id,
struct bpf_reg_state *regs,
struct bpf_kfunc_arg_meta *meta);
int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog, int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog,
struct bpf_reg_state *reg); struct bpf_reg_state *reg);
int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog, int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog,
......
...@@ -603,8 +603,6 @@ int check_ptr_off_reg(struct bpf_verifier_env *env, ...@@ -603,8 +603,6 @@ int check_ptr_off_reg(struct bpf_verifier_env *env,
int check_func_arg_reg_off(struct bpf_verifier_env *env, int check_func_arg_reg_off(struct bpf_verifier_env *env,
const struct bpf_reg_state *reg, int regno, const struct bpf_reg_state *reg, int regno,
enum bpf_arg_type arg_type); enum bpf_arg_type arg_type);
int check_kfunc_mem_size_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
u32 regno);
int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg, int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
u32 regno, u32 mem_size); u32 regno, u32 mem_size);
bool is_dynptr_reg_valid_init(struct bpf_verifier_env *env, bool is_dynptr_reg_valid_init(struct bpf_verifier_env *env,
......
...@@ -338,6 +338,16 @@ static inline bool btf_type_is_struct(const struct btf_type *t) ...@@ -338,6 +338,16 @@ static inline bool btf_type_is_struct(const struct btf_type *t)
return kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION; return kind == BTF_KIND_STRUCT || kind == BTF_KIND_UNION;
} }
static inline bool __btf_type_is_struct(const struct btf_type *t)
{
return BTF_INFO_KIND(t->info) == BTF_KIND_STRUCT;
}
static inline bool btf_type_is_array(const struct btf_type *t)
{
return BTF_INFO_KIND(t->info) == BTF_KIND_ARRAY;
}
static inline u16 btf_type_vlen(const struct btf_type *t) static inline u16 btf_type_vlen(const struct btf_type *t)
{ {
return BTF_INFO_VLEN(t->info); return BTF_INFO_VLEN(t->info);
...@@ -439,9 +449,10 @@ static inline void *btf_id_set8_contains(const struct btf_id_set8 *set, u32 id) ...@@ -439,9 +449,10 @@ static inline void *btf_id_set8_contains(const struct btf_id_set8 *set, u32 id)
return bsearch(&id, set->pairs, set->cnt, sizeof(set->pairs[0]), btf_id_cmp_func); return bsearch(&id, set->pairs, set->cnt, sizeof(set->pairs[0]), btf_id_cmp_func);
} }
#ifdef CONFIG_BPF_SYSCALL
struct bpf_prog; struct bpf_prog;
struct bpf_verifier_log;
#ifdef CONFIG_BPF_SYSCALL
const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id); const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id);
const char *btf_name_by_offset(const struct btf *btf, u32 offset); const char *btf_name_by_offset(const struct btf *btf, u32 offset);
struct btf *btf_parse_vmlinux(void); struct btf *btf_parse_vmlinux(void);
...@@ -455,6 +466,12 @@ s32 btf_find_dtor_kfunc(struct btf *btf, u32 btf_id); ...@@ -455,6 +466,12 @@ s32 btf_find_dtor_kfunc(struct btf *btf, u32 btf_id);
int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_cnt, int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_cnt,
struct module *owner); struct module *owner);
struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf, u32 btf_id); struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf, u32 btf_id);
const struct btf_member *
btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf,
const struct btf_type *t, enum bpf_prog_type prog_type,
int arg);
bool btf_types_are_same(const struct btf *btf1, u32 id1,
const struct btf *btf2, u32 id2);
#else #else
static inline const struct btf_type *btf_type_by_id(const struct btf *btf, static inline const struct btf_type *btf_type_by_id(const struct btf *btf,
u32 type_id) u32 type_id)
...@@ -490,6 +507,18 @@ static inline struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf ...@@ -490,6 +507,18 @@ static inline struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf
{ {
return NULL; return NULL;
} }
static inline const struct btf_member *
btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf,
const struct btf_type *t, enum bpf_prog_type prog_type,
int arg)
{
return NULL;
}
static inline bool btf_types_are_same(const struct btf *btf1, u32 id1,
const struct btf *btf2, u32 id2)
{
return false;
}
#endif #endif
static inline bool btf_type_is_struct_ptr(struct btf *btf, const struct btf_type *t) static inline bool btf_type_is_struct_ptr(struct btf *btf, const struct btf_type *t)
......
This diff is collapsed.
This diff is collapsed.
...@@ -22,7 +22,7 @@ static struct { ...@@ -22,7 +22,7 @@ static struct {
"arg#0 pointer type STRUCT bpf_dynptr_kern points to unsupported dynamic pointer type", 0}, "arg#0 pointer type STRUCT bpf_dynptr_kern points to unsupported dynamic pointer type", 0},
{"not_valid_dynptr", {"not_valid_dynptr",
"arg#0 pointer type STRUCT bpf_dynptr_kern must be valid and initialized", 0}, "arg#0 pointer type STRUCT bpf_dynptr_kern must be valid and initialized", 0},
{"not_ptr_to_stack", "arg#0 pointer type STRUCT bpf_dynptr_kern not to stack", 0}, {"not_ptr_to_stack", "arg#0 expected pointer to stack", 0},
{"dynptr_data_null", NULL, -EBADMSG}, {"dynptr_data_null", NULL, -EBADMSG},
}; };
......
...@@ -109,7 +109,7 @@ ...@@ -109,7 +109,7 @@
}, },
.prog_type = BPF_PROG_TYPE_SCHED_CLS, .prog_type = BPF_PROG_TYPE_SCHED_CLS,
.result = REJECT, .result = REJECT,
.errstr = "arg#0 pointer type STRUCT prog_test_ref_kfunc must point", .errstr = "arg#0 expected pointer to btf or socket",
.fixup_kfunc_btf_id = { .fixup_kfunc_btf_id = {
{ "bpf_kfunc_call_test_acquire", 3 }, { "bpf_kfunc_call_test_acquire", 3 },
{ "bpf_kfunc_call_test_release", 5 }, { "bpf_kfunc_call_test_release", 5 },
......
...@@ -142,7 +142,7 @@ ...@@ -142,7 +142,7 @@
.kfunc = "bpf", .kfunc = "bpf",
.expected_attach_type = BPF_LSM_MAC, .expected_attach_type = BPF_LSM_MAC,
.flags = BPF_F_SLEEPABLE, .flags = BPF_F_SLEEPABLE,
.errstr = "arg#0 pointer type STRUCT bpf_key must point to scalar, or struct with scalar", .errstr = "arg#0 expected pointer to btf or socket",
.fixup_kfunc_btf_id = { .fixup_kfunc_btf_id = {
{ "bpf_lookup_user_key", 2 }, { "bpf_lookup_user_key", 2 },
{ "bpf_key_put", 4 }, { "bpf_key_put", 4 },
...@@ -163,7 +163,7 @@ ...@@ -163,7 +163,7 @@
.kfunc = "bpf", .kfunc = "bpf",
.expected_attach_type = BPF_LSM_MAC, .expected_attach_type = BPF_LSM_MAC,
.flags = BPF_F_SLEEPABLE, .flags = BPF_F_SLEEPABLE,
.errstr = "arg#0 pointer type STRUCT bpf_key must point to scalar, or struct with scalar", .errstr = "arg#0 expected pointer to btf or socket",
.fixup_kfunc_btf_id = { .fixup_kfunc_btf_id = {
{ "bpf_lookup_system_key", 1 }, { "bpf_lookup_system_key", 1 },
{ "bpf_key_put", 3 }, { "bpf_key_put", 3 },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment