On Wed, Dec 1, 2021 at 2:21 PM Hao Luo <haoluo@xxxxxxxxxx> wrote: > > On Wed, Dec 1, 2021 at 12:34 PM Alexei Starovoitov > <alexei.starovoitov@xxxxxxxxx> wrote: > > > > On Mon, Nov 29, 2021 at 05:29:47PM -0800, Hao Luo wrote: > > > > > > + > > > struct bpf_reg_types { > > > const enum bpf_reg_type types[10]; > > > u32 *btf_id; > > > + > > > + /* Certain types require customized type matching function. */ > > > + bool (*type_match_fn)(enum bpf_arg_type arg_type, > > > + enum bpf_reg_type type, > > > + enum bpf_reg_type expected); > > > }; > > > > > > static const struct bpf_reg_types map_key_value_types = { > > > @@ -5013,6 +5019,19 @@ static const struct bpf_reg_types btf_id_sock_common_types = { > > > }; > > > #endif > > > > > > +static bool mem_type_match(enum bpf_arg_type arg_type, > > > + enum bpf_reg_type type, enum bpf_reg_type expected) > > > +{ > > > + /* If arg_type is tagged with MEM_RDONLY, type is compatible with both > > > + * RDONLY and RDWR mem, fold the MEM_RDONLY flag in 'type' before > > > + * comparison. > > > + */ > > > + if ((arg_type & MEM_RDONLY) != 0) > > > + type &= ~MEM_RDONLY; > > > + > > > + return type == expected; > > > +} > > > + > > > static const struct bpf_reg_types mem_types = { > > > .types = { > > > PTR_TO_STACK, > > > @@ -5022,8 +5041,8 @@ static const struct bpf_reg_types mem_types = { > > > PTR_TO_MAP_VALUE, > > > PTR_TO_MEM, > > > PTR_TO_BUF, > > > - PTR_TO_BUF | MEM_RDONLY, > > > }, > > > + .type_match_fn = mem_type_match, > > > > why add a callback for this logic? > > Isn't it a universal rule for MEM_RDONLY? > > Ah, good point, I didn't realize that. Maybe, not only MEM_RDONLY, but > all flags can be checked in the same way? Like the following > > static const struct bpf_reg_types int_ptr_types = { > @@ -5097,6 +5116,13 @@ static int check_reg_type(struct > bpf_verifier_env *env, u32 regno, > if (expected == NOT_INIT) > break; > > + flag = bpf_type_flag(arg_type); > > - if (type == expected) > + if ((type & ~flag) == expected) > goto found; > } I think for MAYBE_NULL and MEM_RDONLY that would be correct, but not necessarily apply to future flags. I would open code it for these specific flags. Also what do you think about dropping bpf_ prefix from type_flag()? It won't conflict with anything and less verbose.