On Sun, Nov 20, 2022 at 2:34 PM Alexei Starovoitov <alexei.starovoitov@xxxxxxxxx> wrote: > > On Mon, Nov 21, 2022 at 02:19:30AM +0530, Kumar Kartikeya Dwivedi wrote: > > On Mon, Nov 21, 2022 at 01:46:04AM IST, Alexei Starovoitov wrote: > > > On Sun, Nov 20, 2022 at 11:57 AM Yonghong Song <yhs@xxxxxx> wrote: > > > > > > > > @@ -8938,6 +8941,24 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, > > > > regs[BPF_REG_0].type = PTR_TO_BTF_ID | PTR_TRUSTED; > > > > regs[BPF_REG_0].btf = desc_btf; > > > > regs[BPF_REG_0].btf_id = meta.ret_btf_id; > > > > + } else if (meta.func_id == special_kfunc_list[KF_bpf_rdonly_cast]) { > > > > + if (!capable(CAP_PERFMON)) { > > > > + verbose(env, > > > > + "kfunc bpf_rdonly_cast requires CAP_PERFMON capability\n"); > > > > + return -EACCES; > > > > + } > > > > > > Just realized that bpf_cast_to_kern_ctx() has to be > > > gated by cap_perfmon as well. > > > > > > Also the direct capable(CAP_PERFMON) is not quite correct. > > > It should at least be perfmon_capable(). > > > But even better to use env->allow_ptr_leaks here. > > > > Based on this, I wonder if this needs to be done for bpf_obj_new as well? It > > doesn't zero initialize the memory it returns (except special fields, which is > > required for correctness), so technically it allows leaking kernel addresses > > with just CAP_BPF (apart from capabilities needed for the specific program types > > it is available to). > > > > Should that also have a env->allow_ptr_leaks check? > > Yeah. Good point. > My first reaction was to audit everything where the verifier produces > PTR_TO_BTF_ID and gate it with allow_ptr_leaks. > But then it looks simpler to gate it once in check_ptr_to_btf_access(). > Then bpf_rdonly_cast and everything wouldn't need those checks. Noticed that check_ptr_to_map_access is doing "Simulate access to a PTR_TO_BTF_ID" and has weird allow_ptr_to_map_access bool which is the same as allow_ptr_leaks. So I'm thinking we can remove allow_ptr_to_map_access and add allow_ptr_leaks check to btf_struct_access() which will cover all these cases. Also since bpf_cast_to_kern_ctx() is expected to be used out of networking progs and those progs are not always GPL we should add env->prog->gpl_compatible to btf_struct_access() too.