Re: [PATCH v3 bpf-next 15/18] bpf: Support attaching tracing BPF program to other BPF programs
From: Alexei Starovoitov <hidden>
Date: 2019-11-08 18:59:28
Also in:
bpf
On 11/8/19 10:49 AM, Song Liu wrote:
quoted
On Nov 7, 2019, at 10:40 PM, Alexei Starovoitov [off-list ref] 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.
quoted
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@kernel.org>[...]quoted
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.