Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> writes: > On Wed, Sep 16, 2020 at 12:59 PM Andrii Nakryiko > <andrii.nakryiko@xxxxxxxxx> wrote: >> >> On Tue, Sep 15, 2020 at 5:50 PM Toke Høiland-Jørgensen <toke@xxxxxxxxxx> wrote: >> > >> > From: Toke Høiland-Jørgensen <toke@xxxxxxxxxx> >> > >> > Eelco reported we can't properly access arguments if the tracing >> > program is attached to extension program. >> > >> > Having following program: >> > >> > SEC("classifier/test_pkt_md_access") >> > int test_pkt_md_access(struct __sk_buff *skb) >> > >> > with its extension: >> > >> > SEC("freplace/test_pkt_md_access") >> > int test_pkt_md_access_new(struct __sk_buff *skb) >> > >> > and tracing that extension with: >> > >> > SEC("fentry/test_pkt_md_access_new") >> > int BPF_PROG(fentry, struct sk_buff *skb) >> > >> > It's not possible to access skb argument in the fentry program, >> > with following error from verifier: >> > >> > ; int BPF_PROG(fentry, struct sk_buff *skb) >> > 0: (79) r1 = *(u64 *)(r1 +0) >> > invalid bpf_context access off=0 size=8 >> > >> > The problem is that btf_ctx_access gets the context type for the >> > traced program, which is in this case the extension. >> > >> > But when we trace extension program, we want to get the context >> > type of the program that the extension is attached to, so we can >> > access the argument properly in the trace program. >> > >> > This version of the patch is tweaked slightly from Jiri's original one, >> > since the refactoring in the previous patches means we have to get the >> > target prog type from the new variable in prog->aux instead of directly >> > from the target prog. >> > >> > Reported-by: Eelco Chaudron <echaudro@xxxxxxxxxx> >> > Suggested-by: Jiri Olsa <jolsa@xxxxxxxxxx> >> > Signed-off-by: Toke Høiland-Jørgensen <toke@xxxxxxxxxx> >> > --- >> > kernel/bpf/btf.c | 9 ++++++++- >> > 1 file changed, 8 insertions(+), 1 deletion(-) >> > >> > diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c >> > index 9228af9917a8..55f7b2ba1cbd 100644 >> > --- a/kernel/bpf/btf.c >> > +++ b/kernel/bpf/btf.c >> > @@ -3860,7 +3860,14 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type, >> > >> > info->reg_type = PTR_TO_BTF_ID; >> > if (tgt_prog) { >> > - ret = btf_translate_to_vmlinux(log, btf, t, tgt_prog->type, arg); >> > + enum bpf_prog_type tgt_type; >> > + >> > + if (tgt_prog->type == BPF_PROG_TYPE_EXT) >> > + tgt_type = tgt_prog->aux->tgt_prog_type; >> >> what if tgt_prog->aux->tgt_prog_type is also BPF_PROG_TYPE_EXT? Should >> this be a loop? > > ok, never mind this specifically. there is an explicit check > > if (tgt_prog->type == prog->type) { > verbose(env, "Cannot recursively attach\n"); > return -EINVAL; > } > > that will prevent this. > > But, I think we still will be able to construct a long chain of > fmod_ret -> freplace -> fmod_ret -> freplace -> and so on ad > infinitum. Can you please construct such a selftest? And then we > should probably fix those checks to also disallow FMOD_RET, in > addition to BPF_TRACE_FENTRY/FEXIT (and someone more familiar with LSM > prog type should check if that can cause any problems). Huh, I thought fmod_ret was supposed to be for kernel functions only? However, I can't really point to anywhere in the code that ensures this, other than check_attach_modify_return(), but I think that will allow a bpf function as long as its name starts with "security_" ? Is there actually any use case for modify_return being attached to a BPF function (you could just use freplace instead, couldn't you?). Or should we just disallow that entirely (if I'm not missing somewhere it's already blocked)? -Toke