On 11/8/19 10:49 AM, Song Liu wrote: > > >> On Nov 7, 2019, at 10:40 PM, Alexei Starovoitov <ast@xxxxxxxxxx> wrote: >> >> Allow FENTRY/FEXIT BPF programs to attach to other BPF programs of any type >> including their subprograms. This feature allows snooping on input and output >> packets in XDP, TC programs including their return values. In order to do that >> the verifier needs to track types not only of vmlinux, but types of other BPF >> programs as well. The verifier also needs to translate uapi/linux/bpf.h types >> used by networking programs into kernel internal BTF types used by FENTRY/FEXIT >> BPF programs. In some cases LLVM optimizations can remove arguments from BPF >> subprograms without adjusting BTF info that LLVM backend knows. When BTF info >> disagrees with actual types that the verifiers sees the BPF trampoline has to >> fallback to conservative and treat all arguments as u64. The FENTRY/FEXIT >> program can still attach to such subprograms, but won't be able to recognize >> pointer types like 'struct sk_buff *' into won't be able to pass them to > ^^^^^ these few words are confusing yep. will fix. >> bpf_skb_output() for dumping to user space. >> >> The BPF_PROG_LOAD command is extended with attach_prog_fd field. When it's set >> to zero the attach_btf_id is one vmlinux BTF type ids. When attach_prog_fd >> points to previously loaded BPF program the attach_btf_id is BTF type id of >> main function or one of its subprograms. >> >> Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx> >> > > [...] > >> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c >> index cd9a9395c4b5..f385c4043594 100644 >> --- a/kernel/bpf/verifier.c >> +++ b/kernel/bpf/verifier.c >> @@ -9390,13 +9390,17 @@ static void print_verification_stats(struct bpf_verifier_env *env) >> static int check_attach_btf_id(struct bpf_verifier_env *env) >> { >> struct bpf_prog *prog = env->prog; >> + struct bpf_prog *tgt_prog = prog->aux->linked_prog; >> u32 btf_id = prog->aux->attach_btf_id; >> const char prefix[] = "btf_trace_"; >> struct bpf_trampoline *tr; >> const struct btf_type *t; >> + int ret, subprog = -1, i; >> + bool conservative = true; >> const char *tname; >> + struct btf *btf; >> long addr; >> - int ret; >> + u64 key; >> >> if (prog->type != BPF_PROG_TYPE_TRACING) >> return 0; >> @@ -9405,19 +9409,42 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) >> verbose(env, "Tracing programs must provide btf_id\n"); >> return -EINVAL; >> } >> - t = btf_type_by_id(btf_vmlinux, btf_id); >> + btf = bpf_prog_get_target_btf(prog); > > btf could be NULL here, so we need to check it? yep. will fix.