On Mon, Dec 6, 2021 at 9:51 PM Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> wrote: > > On Mon, Dec 6, 2021 at 3:22 PM Hao Luo <haoluo@xxxxxxxxxx> wrote: > > > > We have introduced a new type to make bpf_ret composable, by > > reserving high bits to represent flags. > > > > One of the flag is PTR_MAYBE_NULL, which indicates a pointer > > may be NULL. When applying this flag to ret_types, it means > > the returned value could be a NULL pointer. This patch > > switches the qualified arg_types to use this flag. > > The ret_types changed in this patch include: > > > > 1. RET_PTR_TO_MAP_VALUE_OR_NULL > > 2. RET_PTR_TO_SOCKET_OR_NULL > > 3. RET_PTR_TO_TCP_SOCK_OR_NULL > > 4. RET_PTR_TO_SOCK_COMMON_OR_NULL > > 5. RET_PTR_TO_ALLOC_MEM_OR_NULL > > 6. RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL > > 7. RET_PTR_TO_BTF_ID_OR_NULL > > > > This patch doesn't eliminate the use of these names, instead > > it makes them aliases to 'RET_PTR_TO_XXX | PTR_MAYBE_NULL'. > > > > Signed-off-by: Hao Luo <haoluo@xxxxxxxxxx> > > --- > > include/linux/bpf.h | 19 ++++++++++------ > > kernel/bpf/helpers.c | 2 +- > > kernel/bpf/verifier.c | 52 +++++++++++++++++++++---------------------- > > 3 files changed, 39 insertions(+), 34 deletions(-) > > > > [...] > > > @@ -6570,28 +6570,28 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn > > return -EINVAL; > > } > > regs[BPF_REG_0].type = > > - fn->ret_type == RET_PTR_TO_MEM_OR_BTF_ID ? > > - PTR_TO_MEM : PTR_TO_MEM_OR_NULL; > > + (ret_type & PTR_MAYBE_NULL) ? > > + PTR_TO_MEM_OR_NULL : PTR_TO_MEM; > > nit: I expected something like (let's use the fact that those flags > are the same across different enums): > > regs[BPF_REG_0].type = PTR_TO_MEM | (ret_type & PTR_MAYBE_NULL); > We haven't taught reg_type to recognize PTR_MAYBE_NULL until the next patch. Patch 4/9 does have the suggested conversion: regs[BPF_REG_0].type = PTR_TO_MEM | ret_flag; > > > regs[BPF_REG_0].mem_size = tsize; > > } else { > > regs[BPF_REG_0].type = > > - fn->ret_type == RET_PTR_TO_MEM_OR_BTF_ID ? > > - PTR_TO_BTF_ID : PTR_TO_BTF_ID_OR_NULL; > > + (ret_type & PTR_MAYBE_NULL) ? > > + PTR_TO_BTF_ID_OR_NULL : PTR_TO_BTF_ID; > > same as above > > > regs[BPF_REG_0].btf = meta.ret_btf; > > regs[BPF_REG_0].btf_id = meta.ret_btf_id; > > } > > - } else if (fn->ret_type == RET_PTR_TO_BTF_ID_OR_NULL || > > - fn->ret_type == RET_PTR_TO_BTF_ID) { > > + } else if (base_type(ret_type) == RET_PTR_TO_BTF_ID) { > > int ret_btf_id; > > > > mark_reg_known_zero(env, regs, BPF_REG_0); > > - regs[BPF_REG_0].type = fn->ret_type == RET_PTR_TO_BTF_ID ? > > - PTR_TO_BTF_ID : > > - PTR_TO_BTF_ID_OR_NULL; > > + regs[BPF_REG_0].type = (ret_type & PTR_MAYBE_NULL) ? > > + PTR_TO_BTF_ID_OR_NULL : > > + PTR_TO_BTF_ID; > > and here > > > > ret_btf_id = *fn->ret_btf_id; > > if (ret_btf_id == 0) { > > - verbose(env, "invalid return type %d of func %s#%d\n", > > - fn->ret_type, func_id_name(func_id), func_id); > > + verbose(env, "invalid return type %lu of func %s#%d\n", > > + base_type(ret_type), func_id_name(func_id), > > base type returns u32, shouldn't it be %u then? > Ack, you are right. When writing this, I know '%lu' will work but didn't give it much thought. Will use '%u' in v2. > > + func_id); > > return -EINVAL; > > } > > /* current BPF helper definitions are only coming from > > @@ -6600,8 +6600,8 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn > > regs[BPF_REG_0].btf = btf_vmlinux; > > regs[BPF_REG_0].btf_id = ret_btf_id; > > } else { > > - verbose(env, "unknown return type %d of func %s#%d\n", > > - fn->ret_type, func_id_name(func_id), func_id); > > + verbose(env, "unknown return type %lu of func %s#%d\n", > > + base_type(ret_type), func_id_name(func_id), func_id); > > same %u > > > return -EINVAL; > > } > > > > -- > > 2.34.1.400.ga245620fadb-goog > >